【问题标题】:Javafx - how to acces FXML "objects"Javafx - 如何访问 FXML“对象”
【发布时间】:2017-08-24 14:39:44
【问题描述】:

我在我的 fxml 文件中声明了一些 JavaFX 组件。

当按下按钮时如何获取字段(用户名、密码)的值? (执行登录)。

  Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
  stage.setTitle("Login");
  stage.setScene(new Scene(root,400,300));
  stage.show();

或者这是完全错误的做法?

我的问题:

  1. 在 fxml 文件中声明所有字段是个好主意吗?
  2. 如何让对象访问值?
  3. 如果方法完全错误,怎么办? (我想使用场景构建器)

编辑: https://hastebin.com/qexipogoma.xml

【问题讨论】:

  • 请发布您的 FXML 文件和控制器代码。
  • 您需要为这些项目提供fx:id,并在您的控制器中使用@FXML private TextField *fx:id goes here*; 引用它们。我建议您通过一些教程阅读如何做到这一点。
  • 请不要发布代码链接:在问题中发布代码。

标签: java javafx


【解决方案1】:
Scene scene = stage.getScene();
Button btn = (Button) scene.lookup("#myBtnID");
TextField txt = (TextField ) scene.lookup("#myTxtID");

您正在寻找:

txt.getText();

btn.setOnAction( lambda here );

文档:

Button

TextField

编辑: 以这种方式声明 ids

<TextField fx:id="myTxtID" ...  />

【讨论】:

  • 是按钮 id 吗?我在这里看不到一个:hastebin.com/qexipogoma.xml
  • 那么你应该在你的 fxml 中定义它......否则你可以查看你所有的父子元素并查找 TextField 的实例并猜测哪个是哪个......但是普通人只是分配 ID 和直接查
  • 这行不通。除非应用了 CSS,否则查找将返回 null,这在默认情况下不会发生,直到第一次布局传递发生。查找通常非常脆弱;正确的方法是定义一个控制器类并将字段注入其中。如果你真的想这样破解它,从 FXML 加载器中获取命名空间,并在加载 FXML 后从命名空间中获取对象。
  • ofc 它可以工作...我同意并且通常也使用单独的控制器,但查找确实有效...并且为 ONE 按钮创建单独的控制器似乎过度...
  • 它仅在场景已渲染时才有效:您发布的代码中没有任何内容可以保证这一点。如果您要在加载 FXML 的位置访问控件,为什么不使用始终有效的 FXML 加载器命名空间,而不是依赖于您无法控制的任意时间的机制?跨度>
【解决方案2】:

在 fxml 文件中声明所有字段是个好主意吗?

这取决于您需要什么。在这种情况下,您不需要动态添加/删除场景的任何部分。您可能会在成功登录时替换窗口/场景。通过 fxml 创建这个场景应该没有任何问题。

如何让对象访问值?

使用带有 fxml 的控制器并通过该控制器访问值。

<AnchorPane fx:controller="mypackage.LoginController" ...>
   <children>
      ...
      <TextField fx:id="username" ... />
      ...
      <PasswordField fx:id="password" ... />
      ...
      <Button onAction="#login" ... />
   </children>
</AnchorPane>
package mypackage;

...

public class LoginController {

    private boolean login = false;

    @FXML
    private TextField username;

    @FXML
    private PasswordField password;

    @FXML
    private void login() {
        // regular close the login window
        login = true;
        password.getScene().getWindow().hide();
    }

    public String getUsername() {
        return username.getText();
    }

    public String getPassword() {
        return password.getText();
    }

    public boolean isLogin() {
        return login;
    }

    public void resetLogin() {
        // allow reuse of scene for invalid login data
        login = false;
    }

}
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
Stage stage = new Stage(new Scene(loader.load()));
LoginController controller = loader.getController();

boolean loginSuccess = false;

stage.showAndWait();

if (controller.isLogin()) {
    if (checkLogin(controller.getUsername(), controller.getPassword())) {
        // handle login success
    } else {
        // handle invalid login
    }
}

【讨论】:

    【解决方案3】:

    尝试使用SceneBuilder。它将生成一个 FXML 文件和一个兼容的控制器。这将为您提供一个良好的开端。

    【讨论】:

      猜你喜欢
      • 2015-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-02
      • 2020-07-17
      • 1970-01-01
      • 2013-07-22
      • 1970-01-01
      相关资源
      最近更新 更多