我开始探索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());
这是错误的。确切地说,fieldRegisterUsername
是null
。
为什么使用lookup(String id)
方法而不是@FXML
注释找到某些元素?
答案 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
。