当我在 JavaFx 中的场景 2 视图中时,如何更新场景 1 数据视图?

How to update Scene 1 data view when I am in scene 2 view in JavaFx?

提问人:AdnanArch 提问时间:9/30/2023 更新时间:10/19/2023 访问量:33

问:

我面临的问题是我正在尝试通过 excel 文件获取数据并将其插入到我的数据库中,之后表上的数据应该更新,但它没有发生。

这是我的主类,它导致打开一个新框架,我可以通过该框架上传 excel 数据并将其插入到我的数据库中。

AddNewAccountHolderController.java文件。

@FXML
void onImport() {
    ImportAccountHoldersData accountHolder = new ImportAccountHoldersData();
    Stage stage = new Stage();
    try {
        accountHolder.start(stage);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

}

此函数打开一个新视图,其控制器为 。现在在这个控制器中,我有一个插入函数,用于将数据插入数据库。ImportAccountHoldersDataController.java

功能如下:

@FXML
void onInsert() {
    try {
        // Check if the table is not empty
        if (accountHoldersTableView.getItems().isEmpty()) {
            MessageDialogs.showErrorMessage("No account holders to insert.");
            return; // Exit the method since there's nothing to insert
        }

        DatabaseConnection db = new DatabaseConnection();
        CallableStatement statement = db.connection.prepareCall("{CALL sp_create_account_holder(?, ?, ?, ?, ?, ?)}");

        boolean allRecordsInserted = true;

        for (AccountHolder accountHolder : accountHoldersTableView.getItems()) {
            // Set the input parameters for the stored procedure
            statement.setString(1, accountHolder.getName());
            String cnicNo = accountHolder.getCnicNo().replaceAll("-", "");
            statement.setBigDecimal(2, BigDecimal.valueOf(Long.parseLong(cnicNo)));
            statement.setString(3, accountHolder.getAddress());
            statement.setString(4, accountHolder.getPhone());
            statement.setBoolean(5, accountHolder.isisRetailer());

            statement.registerOutParameter(6, Types.VARCHAR);

            // Execute the stored procedure
            statement.execute();

            // Retrieve the result message
            String resultMessage = statement.getString(6);

            if (!resultMessage.equals("Account holder added successfully.")) {
                allRecordsInserted = false;
            }
        }

        // Close the database connection and statement
        db.connection.close();
        statement.close();

        if (allRecordsInserted) {
            MessageDialogs.showMessageDialog("All account holders created successfully.");

                AddNewAccountHolderController controller = new AddNewAccountHolderController();
controller.populateAccountHoldersTable();


        } else {
            MessageDialogs.showErrorMessage("Error inserting account holder(s).");
        }
    } catch (Exception e) {
        // Log the exception for debugging purposes
        log.error("Error inserting account holders(s): " + e.getMessage(), e);

        // Show a user-friendly error message
        MessageDialogs.showErrorMessage("An error occurred while inserting account holder(s).");
    }
}

现在,正如您在成功插入所有记录后所看到的那样。我想更新上一个视图的表视图,称为文件视图。但这给了我一个空指针异常。AddNewAccountHolderController.java

ERROR com.al_makkah_traders_app.controller.ImportAccountHoldersDataController - Error inserting account holders(s): Cannot invoke "com.al_makkah_traders_app.controller.AddNewAccountHolderController.populateAccountHoldersTable()" because "this.addNewAccountHolderController" is null
java.lang.NullPointerException: Cannot invoke "com.al_makkah_traders_app.controller.AddNewAccountHolderController.populateAccountHoldersTable()" because "this.addNewAccountHolderController" is null

我不知道如何防止它并更新表视图。

Java 异常 JavaFX NullPointerException

评论

4赞 jewelsea 9/30/2023
这完全是错误的方法。一个控制器不应调用另一个控制器(尤其是您自己创建的实例,而不是来自 FXML 的实例)。请改用 MVC 方法。将数据放在支持模型中表的可观察对象列表中,并更新该列表。

答:

0赞 David Weber 10/19/2023 #1

在新 Stage 的控制器中:

添加一个名为“callbackOnClose”的类 Runnable 的属性。 为此属性创建一个 setter。 在“onInsert”的末尾,执行“callbackOnClose.run()”。

在父阶段:

在加载新的 Stage/Scene 之前,请获取它的控制器,并使用您创建的 setter 方法设置回调。 您可以创建一个 Runnable 并将其作为参数传递,或者使用 Lambda 来执行。 由于您位于父视图控制器中,因此可以访问其属性。

注意:

这是我在所有项目中的做法,每次都像魅力一样工作。

注2:

您可以使用任何类型的接口而不是 Runnable。如果需要,您可以创建自己的界面。