切换 FXML 场景
Switch FXML scene
我正在完成我的程序的一部分,其中涉及将用户从登录屏幕 (FIRST fxml) 发送到第二个屏幕。这应该在程序加载时发生(基于 rememb运行ce)。
当我 运行 程序时,它加载了第一个和第二个 fxml,但继续显示第一个 fxml(当它应该显示第二个时)。我可以使用具有相同代码的输入(I.E 按钮)从第一个屏幕转到第二个屏幕。
每次我设置场景时,我都尝试使用不同的加载器并使用 .show() 方法,但是 none 这些(或其许多变体)都有效。
我在调用这些方法时进行了打印 - 这就是我确定它们已加载的方式(打印行):
- 启动方法(主应用程序启动(阶段)方法)
- INIT1 METHOD(第一个控制器初始化方法)
- INIT2 METHOD(第二个控制器初始化方法的开始)
- 已加载输入UI(第二个控制器初始化方法结束)
- INIT2 METHOD(每当我在文本上按回车时,这两行都会再次出现)
- 加载输入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() 先出现)似乎是:
- 第一个UI代码是运行(从头开始)并初始化(未显示)。
- secondUI 代码是 运行(从 firstUI 初始化)并初始化(未显示)。
- secondUI 初始化代码完成并显示 firstUI。
- 只有按下输入(具有相同的开关代码)才会从第一个UI切换到第二个UI。
您不需要加载程序的引用来更改场景。
你可以有一个简单的 Main
像:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(new FXMLLoader().load(getClass().getResource("/res/screenOne.fxml"))));
primaryStage.show();
}
public static void main(String[] args) {
launch(null);
}
}
其中 screenOne.fxml
可以(注意窗格的 fx-id)。
(要进行测试,您需要使用正确的控制器路径进行编辑):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane fx:id="main" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="FirstUI">
<children>
<Label layoutX="155.0" layoutY="132.0" text="Screen 1">
<font>
<Font size="24.0" />
</font>
</Label>
<Button layoutX="264.0" layoutY="246.0" mnemonicParsing="false" onAction="#changeScene" prefHeight="26.0" prefWidth="102.0" text="Change Scene" />
</children>
</AnchorPane>
FirstUI
使用main
更新场景:
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.Pane;
public class FirstUI {
@FXML Pane main;
public void changeScene(ActionEvent e) {
try {
main.getScene().setRoot(new FXMLLoader().load(getClass().getResource("/res/screenTwo.fxml")));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
要使这里的代码成为 MRE 是 screenTwo.fxml
:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/10.0.1"
xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label layoutX="155.0" layoutY="132.0" text="Screen 2">
<font>
<Font size="24.0" />
</font>
</Label>
</children>
</AnchorPane>
我正在完成我的程序的一部分,其中涉及将用户从登录屏幕 (FIRST fxml) 发送到第二个屏幕。这应该在程序加载时发生(基于 rememb运行ce)。
当我 运行 程序时,它加载了第一个和第二个 fxml,但继续显示第一个 fxml(当它应该显示第二个时)。我可以使用具有相同代码的输入(I.E 按钮)从第一个屏幕转到第二个屏幕。
每次我设置场景时,我都尝试使用不同的加载器并使用 .show() 方法,但是 none 这些(或其许多变体)都有效。
我在调用这些方法时进行了打印 - 这就是我确定它们已加载的方式(打印行):
- 启动方法(主应用程序启动(阶段)方法)
- INIT1 METHOD(第一个控制器初始化方法)
- INIT2 METHOD(第二个控制器初始化方法的开始)
- 已加载输入UI(第二个控制器初始化方法结束)
- INIT2 METHOD(每当我在文本上按回车时,这两行都会再次出现)
- 加载输入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() 先出现)似乎是:
- 第一个UI代码是运行(从头开始)并初始化(未显示)。
- secondUI 代码是 运行(从 firstUI 初始化)并初始化(未显示)。
- secondUI 初始化代码完成并显示 firstUI。
- 只有按下输入(具有相同的开关代码)才会从第一个UI切换到第二个UI。
您不需要加载程序的引用来更改场景。
你可以有一个简单的 Main
像:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(new FXMLLoader().load(getClass().getResource("/res/screenOne.fxml"))));
primaryStage.show();
}
public static void main(String[] args) {
launch(null);
}
}
其中 screenOne.fxml
可以(注意窗格的 fx-id)。
(要进行测试,您需要使用正确的控制器路径进行编辑):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane fx:id="main" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="FirstUI">
<children>
<Label layoutX="155.0" layoutY="132.0" text="Screen 1">
<font>
<Font size="24.0" />
</font>
</Label>
<Button layoutX="264.0" layoutY="246.0" mnemonicParsing="false" onAction="#changeScene" prefHeight="26.0" prefWidth="102.0" text="Change Scene" />
</children>
</AnchorPane>
FirstUI
使用main
更新场景:
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.Pane;
public class FirstUI {
@FXML Pane main;
public void changeScene(ActionEvent e) {
try {
main.getScene().setRoot(new FXMLLoader().load(getClass().getResource("/res/screenTwo.fxml")));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
要使这里的代码成为 MRE 是 screenTwo.fxml
:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/10.0.1"
xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label layoutX="155.0" layoutY="132.0" text="Screen 2">
<font>
<Font size="24.0" />
</font>
</Label>
</children>
</AnchorPane>