【问题标题】:How to refresh a TableView in window A from a Window B in javaFX? (Edit)java - 如何从javaFX中的窗口B刷新窗口A中的TableView? (编辑)
【发布时间】:2023-04-06 08:43:01
【问题描述】:

我有一个窗口 A(主窗口),它包含一个 TableView 和一个按钮,当单击该按钮时,它会打开一个新窗口(题字窗口),其中包含两个文本字段(为了设置名字和姓氏)和一个“保存”按钮。我想要发生的是,当我单击 inscription 窗口 中的“保存”按钮时,主窗口 中的 TableView 会刷新并显示名字和姓氏新行。

这是我的主窗口控制器:

public class FxmlMainController implements Initializable {

    @FXML
    private TableView<DataArray> dataTable;
    
    @FXML
    private TableColumn<DataArray, String> firstNameCol;
    @FXML
    private TableColumn<DataArray, String> lastNameCol;
    
    public static ObservableList<DataArray> DATA_LIST;

    @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"));
       dataTable.getItems().addAll(DATA_LIST);
    }    

    //Open the inscription window
    @FXML
    private void openInscriptionWindow(ActionEvent event) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("/inscriptionui/FxmlInscription.fxml"));
        Scene scene = new Scene(root);
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.show();
    }
    
}

这是我的题字窗口:

public class FxmlInscriptionController implements Initializable {

    @FXML
    private TextField firsNametInput;   //first name TextField

    @FXML
    private TextField lastNameInput;   //last name TextField

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }

    //Show the inserted first name and last name in my TableView in the main window
    @FXML
    private void saveData(MouseEvent event) throws IOException {
   
    FxmlMainController.DATA_LIST = FXCollections.observableArrayList(new DataArray(firsNametInput.getText(), lastNameInput.getText()));

        /*
        what should I write more here to make my TableView
        get refreshed automatically and show the new inserted values?
         */
    }

}

这是我的 DataArray 类:

public class DataArray {

    private String firstName;
    private String lastName;

    public DataArray(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}

感谢您的帮助 谢谢

【问题讨论】:

  • 这里的结构/策略对我来说似乎是错误的。您应该将项目列表从表传递到第二个控制器。然后在第二个控制器中:1. 从 UI 获取数据,2. 执行数据库插入,3. 将新项目添加到列表中。然后表格会自动更新。无需从数据库中拉回整个列表。
  • 无论如何,它无法正常工作的原因是您第二次加载mainUI.fxml。这将创建一个新表,您获得的控制器是包含该新表的 UI 的控制器。那永远不会显示,所以你永远看不到它的变化。您想更新现有表,而不是创建新表。
  • minimal reproducible example 请(注意 M!)并遵守 java 命名约定
  • @James_D 谢谢,我理解逻辑,我试过了,但表格没有自动刷新,我在我的 mainUI 中尝试了一个按钮,它在单击时调用我的 TableView 实例上的刷新方法(右在我做了你的逻辑之后)并且它运行良好,但不幸的是从第二个 UI 中的按钮刷新它不起作用。
  • 这仍然不是最小的(仅仅删除导入是不行的 - 请阅读参考的帮助页面以了解如何将代码集中在 one 问题上)也不是遵循命名约定..

标签: java javafx tableview


【解决方案1】:

将表格的项目列表传递给第二个控制器:

@FXML
private void openInscriptionWindow(ActionEvent event) throws IOException {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/inscriptionui/FxmlInscription.fxml"));
    Parent root = loader.load();

    FxmlInscriptionController controller = loader.getController();
    controller.setTableItems(dataTable.getItems());

    Scene scene = new Scene(root);
    Stage stage = new Stage();
    stage.setScene(scene);
    stage.show();
}

然后简单地将新项目添加到列表中:

public class FxmlInscriptionController implements Initializable {

    @FXML
    private TextField firsNametInput;   //first name TextField

    @FXML
    private TextField lastNameInput;   //last name TextField

    private ObservableList<DataArray> tableItems ;

    public void setTableItems(ObservableList<DataArray> tableItems) {
        this.tableItems = tableItems ;
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }

    //Show the inserted first name and last name in my TableView in the main window
    @FXML
    private void saveData(MouseEvent event) throws IOException {
   
        tableItems.add(new DataArray(firsNametInput.getText(), lastNameInput.getText()));

    }

}

【讨论】:

  • 非常感谢您的回答!我很抱歉我迟到的回复。顺便说一句,我还必须传递我的 tableview 的引用才能从另一个场景中刷新它。只有一个问题:当您以这种方式加载 fxml 文件时,它可以工作:FXMLLoader loader = new FXMLLoader(getClass().getResource("/inscriptionui/FxmlInscription.fxml")); Parent root = loader.load(); FxmlInscriptionController controller = loader.getController(); 但是,如果您以这种方式将 fxml 文件 URL 作为输入流传递:Parent root = loader.load("/inscriptionui/FxmlInscription.fxml"); 它不起作用,为什么?
  • @Madjid 您不必将TableView 本身传递给控制器​​;如果您需要做的事情会破坏表格视图与其项目列表之间的连接(例如,在传递列表后调用setItems(...))。
  • @Madjid FXMLLoader.load(URL) 方法是一个静态方法(请阅读文档;如果您从引用中调用此方法,您的 IDE 肯定会给您一个警告)。因此,使用该方法无法更改FXMLLoader 实例loader 的状态,尤其是其控制器保持为空。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多