【发布时间】:2019-08-31 05:01:51
【问题描述】:
我正在完成我的程序的一部分,该程序涉及将用户从登录屏幕 (FIRST fxml) 发送到第二个屏幕。这应该在程序加载时发生(基于记忆)。
当我运行程序时,它会加载 FIRST 和 SECOND fxml,但会继续显示 FIRST fxml(当它应该显示 SECOND 时)。我可以使用具有相同代码的输入(IE 按钮)从第一个屏幕转到第二个屏幕。
我每次设置场景时都尝试使用不同的加载器并使用 .show() 方法,但这些(或其许多变体)都不起作用。
我在调用方法时打印 - 这就是我确定它们已加载的方式(打印行):
- START METHOD(主应用程序启动(Stage)方法)
- INIT1 METHOD(第一个控制器初始化方法)
- INIT2 METHOD(第二个控制器初始化方法的开始)
- 已加载输入 UI(第二个控制器初始化方法结束)
- INIT2 METHOD(每当我在文本上按 Enter 键时,这两行都会再次出现)
- 已加载输入 UI(此时它会切换到新的 FXML)
这是我的代码结构的最小表示:
public class Main extends Application {
private static final FXMLLoader loader = new FXMLLoader();
private static Stage mainStage;
@Override
public void start(Stage primaryStage) throws Exception {
System.out.println("START METHOD");
mainStage = primaryStage; //Copy Reference
primaryStage.setScene(new Scene(Main.getLoader().load(Main.class.getResource("/res/screenOne.fxml"))));
primaryStage.show();
}
public static FXMLLoader getLoader() {
return loader;
}
public static Stage getStage() {
return mainStage;
}
}
/**
* FXML Controller class
*/
public class firstUI implements Initializable {
@Override
public void initialize(URL url, ResourceBundle rb) {
System.out.println("INIT1 METHOD");
try {
Parent root = Main.getLoader().load(getClass().getResource("/res/screenTwo.fxml"));
Main.getStage().setScene(new Scene(root));
} catch (Exception ex) {
Logger.getLogger(mainUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
/**
* FXML Controller class
*/
public class secondUI implements Initializable {
@Override
public void initialize(URL url, ResourceBundle rb) {
System.out.println("INIT2 METHOD");
System.out.println("Loaded Input UI");
}
}
再次,我希望代码加载第一个UI,然后从第一个UI 加载第二个。
输出(如果 stage.show() 先出现,则在调试中)似乎是:
- firstUI 代码运行(从开始)并初始化(未显示)。
- secondUI 代码运行(从 firstUI init)并初始化(未显示)。
- secondUI 初始化代码完成并显示 firstUI。
- 只有当输入(具有相同的开关代码)被按下时,它才会从 firstUI 切换到 secondUI。
【问题讨论】:
-
欢迎来到 SO。最小的表示是好的(我认为不需要 secondUI 来演示这个问题)。考虑添加 fxml 文件的最小表示以使代码为minimal reproducible example。
-
initialize方法在load返回之前运行。您先设置第二个场景,然后再将其替换为第一个场景。此外,您不能重用FXMLLoader实例(至少不能不跳过一些圈子)。这样做的唯一原因是您正在使用staticload方法。此外,在视图的初始化中混合登录逻辑是一个坏主意。您正在加载不需要加载的场景。将逻辑和例如分开会更好。在start中做这样的事情:if(loginRequired()) gotoLogin(); else gotoMain();