You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX+Spring桌面应用:纯代码视图如何拆分MVC视图与控制器?

嘿,我完全懂你现在的纠结——用纯代码手写JavaFX界面的时候,想拆分MVC确实不像FXML那样有@FXML注解现成可用,但核心思路其实是一致的:把UI组件的创建/布局和业务逻辑、事件处理彻底分开就行。我给你用代码示例一步步拆解,保证你看完就能上手。

1. 先拆出视图(View)类

视图类的职责只有一个:创建并布局所有UI元素,绝对不写任何业务逻辑。同时,要给需要被控制器操作的组件(比如TableView、Save按钮)提供getter方法,让控制器能安全访问它们。

比如我们写一个DataView类,专门负责搭建表格和按钮:

import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;

public class DataView extends VBox {
    private final TableView<YourDataModel> dataTable;
    private final Button saveButton;
    private final Button addButton;

    public DataView() {
        // 初始化表格和列
        dataTable = new TableView<>();
        TableColumn<YourDataModel, String> nameCol = new TableColumn<>("姓名");
        nameCol.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
        // 其他列...

        dataTable.getColumns().addAll(nameCol);

        // 初始化按钮
        saveButton = new Button("保存");
        addButton = new Button("新增");

        // 布局组件
        this.setSpacing(10);
        this.getChildren().addAll(dataTable, addButton, saveButton);
    }

    // 给控制器提供访问组件的入口
    public TableView<YourDataModel> getDataTable() {
        return dataTable;
    }

    public Button getSaveButton() {
        return saveButton;
    }

    public Button getAddButton() {
        return addButton;
    }
}
2. 再写控制器(Controller)类

控制器类负责所有逻辑处理:加载数据库数据、处理按钮点击事件、表格的增删改操作。它会持有视图的引用,通过视图提供的getter来操作UI组件。

如果用Spring的话,你可以把控制器声明为Bean,方便后续注入服务(比如数据库操作的Service)。这里我们先写基础版本:

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

public class DataController {
    private final DataView view;
    private final YourDatabaseService dbService; // 假设这是你的Spring数据库服务
    private ObservableList<YourDataModel> dataList;

    // 构造注入视图和服务(Spring可以用@Autowired自动注入)
    public DataController(DataView view, YourDatabaseService dbService) {
        this.view = view;
        this.dbService = dbService;
        initEvents();
        loadDataFromDb();
    }

    // 绑定所有按钮事件
    private void initEvents() {
        view.getSaveButton().setOnAction(e -> saveData());
        view.getAddButton().setOnAction(e -> addNewRow());
    }

    // 从数据库加载数据到表格
    private void loadDataFromDb() {
        dataList = FXCollections.observableArrayList(dbService.getAllData());
        view.getDataTable().setItems(dataList);
    }

    // 保存数据的逻辑
    private void saveData() {
        YourDataModel selectedData = view.getDataTable().getSelectionModel().getSelectedItem();
        if (selectedData != null) {
            dbService.saveData(selectedData);
            // 可以加个提示或者刷新表格
        }
    }

    // 新增行的逻辑
    private void addNewRow() {
        YourDataModel newData = new YourDataModel();
        dataList.add(newData);
        view.getDataTable().getSelectionModel().select(newData);
    }
}
3. 主类整合View和Controller

最后在主应用类里把视图和控制器关联起来,启动JavaFX应用。如果用Spring,你可以用ApplicationContext来获取Bean,这样更符合Spring的依赖注入逻辑:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainApp extends Application {
    @Override
    public void start(Stage primaryStage) {
        // 初始化Spring容器(如果用Spring的话)
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        
        // 获取视图和控制器Bean
        DataView view = context.getBean(DataView.class);
        DataController controller = context.getBean(DataController.class);

        // 搭建场景并显示
        Scene scene = new Scene(view, 800, 600);
        primaryStage.setTitle("数据管理");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
几个关键要点提醒
  • 不要让控制器直接修改视图内部:只能通过视图提供的getter访问组件,这样视图的内部布局变化时,控制器不需要修改,降低耦合。
  • 事件绑定放在控制器:所有按钮、表格的事件处理逻辑都要放在控制器里,视图只负责展示UI。
  • Spring整合小技巧:把DataView和DataController都声明为Spring的@Component,然后在控制器里用@Autowired注入视图和数据库服务,这样不用手动new实例,更符合Spring的依赖注入思想。

内容的提问来源于stack exchange,提问作者Waqar Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:15:20