JavaFX如何从子登记窗口刷新主窗口的TableView数据
问题解决步骤
现有代码的核心问题
- 你在
saveData方法中直接给静态变量FxmlMainController.DATA_LIST重新赋值了新的ObservableList对象,但主窗口TableView绑定的是初始化时的旧列表引用,替换引用不会触发TableView刷新,还会覆盖原有列表的历史数据 - 主窗口初始化时使用
dataTable.getItems().addAll(DATA_LIST)只是把列表内容一次性复制到TableView的items中,后续原列表变动不会同步到TableView
修改代码即可实现需求
第一步:修改主窗口控制器初始化逻辑
找到initialize方法,把dataTable.getItems().addAll(DATA_LIST)替换为dataTable.setItems(DATA_LIST),直接让TableView的数据源绑定到DATA_LIST,后续列表增删会自动触发TableView刷新:
@Override public void initialize(URL url, ResourceBundle rb) { DATA_LIST = FXCollections.observableArrayList(new DataArray("Michael", "Jackson")); firstNameCol.setCellValueFactory(new PropertyValueFactory<DataArray, String>("firstName")); lastNameCol.setCellValueFactory(new PropertyValueFactory<DataArray, String>("lastName")); // 替换原addAll代码,直接绑定数据源 dataTable.setItems(DATA_LIST); }
第二步:修改登记窗口控制器的saveData方法
不要重新赋值DATA_LIST,改为往原有列表中新增数据,新增后可主动关闭登记窗口:
@FXML private void saveData(MouseEvent event) throws IOException { // 新增数据到已有的ObservableList,不要重新赋值 FxmlMainController.DATA_LIST.add(new DataArray(firsNametInput.getText(), lastNameInput.getText())); // 可选:保存完成后关闭登记窗口 ((Stage) firsNametInput.getScene().getWindow()).close(); }
可选优化(降低耦合)
不建议用静态变量共享数据,更好的做法是打开登记窗口时拿到控制器实例,把主窗口的列表传递过去:
// 主窗口openInscriptionWindow方法修改 @FXML private void openInscriptionWindow(ActionEvent event) throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("/inscriptionui/FxmlInscription.fxml")); Parent root = loader.load(); // 拿到登记窗口控制器 FxmlInscriptionController inscriptionController = loader.getController(); // 把主窗口的列表传给登记窗口控制器(需要先在FxmlInscriptionController里加个ObservableList<DataArray>类型的成员变量接收) inscriptionController.setDataList(DATA_LIST); Scene scene = new Scene(root); Stage stage = new Stage(); stage.setScene(scene); stage.show(); }
这样就不用依赖静态变量,代码耦合度更低,更易维护。
内容的提问来源于stack exchange,提问作者Majid
相关产品推荐
相关产品推荐

