java 如何在没有eventHandler的情况下使用getUserData()

velaa5lx  于 2023-03-28  发布在  Java
关注(0)|答案(1)|浏览(129)

我创建了一个登录系统,它连接到一个SQLite数据库。用户输入正确的帐户信息后, Jmeter 板应该加载他的姓名和余额,这也应该从数据库中检索。我从传递到登录表单的信息创建了一个Account-Objekt,并使用“stage.setUserData()”方法保存它们,以便在Dashboard-Controller类中使用它们。

@FXML
    void loginButtonClicked(ActionEvent event) {
        String user = usernameTextField.getText();
        String pw = passwordTextField.getText();
        database.openConnection();
        try {

            if(loginModel.isLogin(database.getConnection(), user, pw)) {
                TabPane root = FXMLLoader.load(getClass().getClassLoader().getResource("de/hannes/account/AccountGUI.fxml"));
                final Node source = (Node) event.getSource();
                Account account = accModel.getAccount(database.getConnection(), database.getStatement(), user);
                stage = (Stage) source.getScene().getWindow();
                stage.setUserData(account);
                Scene scene = new Scene(root);
                stage.setResizable(false);
                stage.setTitle("Dashboard");
                stage.setScene(scene);
                stage.show();
                
            }
            
            else {
                usernameTextField.clear();
                passwordTextField.clear();
                loginButton.setDisable(true);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        
    }

好吧,到目前为止,它工作,但只有当用户点击一个按钮,在 Jmeter 板,然后使用stage.getUserData()”-方法。

@FXML
    void test(ActionEvent event) {
        Node node = (Node) event.getSource();
        Stage stage = (Stage) node.getScene().getWindow();
        Account account = (Account) stage.getUserData();
        balanceLabel.setText(account.getGuthabenAsString());
    }

但是这种解决方案非常麻烦,而且对用户一点也不友好。我想显示用户的帐户详细信息,而不需要之前在Button上调用EventHandler。我考虑过使用initialize-Method,但我不确定如何在没有eventHandler的情况下访问userData。

ozxc1zmp

ozxc1zmp1#

虽然可以使用StageuserData属性,但我推荐一种不同的方法。在FXML的控制器类中创建一个可以调用的方法。该方法将负责执行控制器所需的任何额外初始化,只有当它可以访问Account时才能完成。

// create an FXMLLoader *instance*
FXMLLoader loader = new FXMLLoader(getClass().getResource("/de/hannes/account/AccountGUI.fxml"));

TabPane root = loader.load(); // uses the INSTANCE 'load()' method
YourControllerClass controller = loader.getController(); // called AFTER 'load()'

Account account = accModel.getAccount(database.getConnection(), database.getStatement(), user);
controller.initAccount(account); // call the method you added to the controller

final Node source = (Node) event.getSource();

stage = (Stage) source.getScene().getWindow();

Scene scene = new Scene(root);
stage.setResizable(false);
stage.setTitle("Dashboard");
stage.setScene(scene);
stage.show();

虽然注意到一个更合适的MVC或其他架构在这里会更好。我看到你有一些模型类,这很好,但哪个帐户当前登录应该在模型中被跟踪。然后“帐户视图”可以简单地查询模型以获得该信息,而不是直接获得Account。也就是说,为了在控制器之间传递所需的模型示例,你可能仍然需要做一些类似于上面的事情。
另外,奇怪的是需要给出acc.getModel(...)(我假设是)一个JDBC ConnectionStatement作为参数。与loginModel对象类似的奇怪之处。使用SQL数据库的事实是一个实现细节。方法签名不应该暴露这样的细节。最多,模型类的构造函数应该接受一个Connection(尽管可能需要另一个类来管理Connection)。然后方法在内部使用该Connection
我还应该指出,您正在 *JavaFX应用程序线程 * 上执行数据库访问操作。或者,如果不是,那么您正在阻塞FX线程,而数据库操作在后台线程上完成。任何一个都是不好的。所有数据库操作和其他I/O操作都应该在后台线程上执行,FX线程必须保持空闲以完成其工作。有关详细信息,请参阅JavaFX中的并发。

相关问题