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
相关产品推荐
相关产品推荐

