JavaFX FXML访问使用lookup()方法成功,但不能使用@FXML注释

时间:2016-06-12 16:47:02

标签: java javafx fxml

我开始探索JavaFX FXML应用程序技术。

我使用在Main类中访问的一个主要阶段,其Main.getStage()在应用程序的开头使用覆盖方法public void start(Stage stage)调用。内置两个public static Scene以在切换时保持持久性。

@Override
public void start(Stage stage) throws Exception {
    STAGE = stage;
    LOGIN = new Scene(FXMLLoader.load(getClass().getResource("Login.fxml")));
    REGISTER = new Scene(FXMLLoader.load(getClass().getResource("Register.fxml")));

    STAGE.setScene(LOGIN);
    STAGE.setTitle("FXApplication");
    STAGE.show();
}

public static Stage getStage() {
    return STAGE;
}

两个场景都具有相同的控制器类MainController。使用:

  • fx:id="buttonLoginRegister"的按钮转到REGISTER场景
  • fx:id="buttonRegisterBack"的按钮返回LOGIN

并且两者都具有相同的onClick事件handleButtonAction(ActionEvent event)。 TextFields是用于登录/注册的用户名的字段。

@FXML private Button buttonLoginRegister;
@FXML private Button buttonRegisterBack;
@FXML private TextField fieldLoginUsername;
@FXML private TextField fieldRegisterUsername;

@FXML
private void handleButtonAction(ActionEvent event) throws IOException {

    Stage stage = Main.getStage();

    if (event.getSource() == buttonLoginRegister) {     
        stage.setScene(Main.REGISTER);
        stage.show();

        // Setting the text, the working way
        TextField node = (TextField) stage.getScene().lookup("#fieldRegisterUsername");
        node.setText(fieldLoginUsername.getText());

        // Setting the text, the erroneous way
        // fieldRegisterUsername.setText(fieldLoginUsername.getText());

    } else {
        stage.setScene(Main.LOGIN);
        stage.show();
    }
}

我的目标是将LOGIN TextField中的值复制到REGISTER场景中的值。它使用上面的代码很好。然而,首先我尝试使用以下方法访问另一个场景中的元素:

fieldRegisterUsername.setText(fieldLoginUsername.getText());

这是错误的。确切地说,fieldRegisterUsernamenull

为什么使用lookup(String id)方法而不是@FXML注释找到某些元素?

1 个答案:

答案 0 :(得分:2)

正如我在评论中提到的,在不同视图之间共享控制器很少是个好主意,我强烈建议您为每个视图创建一个单独的控制器。

至于你的问题本身 - 你有两个控制器类实例,每次调用npm install --production时都有一个实例。据推测,一个视图具有FXMLLoader.load TextField,而另一个视图具有fieldLoginUsername 如果满足fieldRegisterUsername语句的条件,则表示活动场景是Login场景,因此处理它的控制器是具有if的场景,因此fieldLoginUsername自然会为null 。

但是在fieldRegisterUsername子句中的第一行,您将活动场景更改为Register 1,因此当您调用if时,您指的是其控制器是Register控制器的场景,确实有scene#lookup的人。

如果你在更改活动场景之前调用fieldRegisterUsername,你会发现它也返回null。

如果必须对控制器使用相同的类,则可能需要确保只有该类的一个实例。这将需要使用scene#lookup