JavaFX - getScene() returns 空
JavaFX - getScene() returns null
我刚开始使用 JavaFX Scene Builder 构建一个小应用程序。
它由属于 'login.fxml' 的控制器 class 'Login.java' 组成,其中 FXML 文件 'registrierung.fxml' 通过名为 [=29] 的方法加载=]:
public class Login {
@FXML
private void registrationClicked(ActionEvent event){
try{
((Node) (event.getSource())).getScene().getWindow().hide();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/fxml/registrierung.fxml"));
Parent root = (Parent) loader.load();
Stage stage = new Stage();
Scene scene = new Scene(root);
stage.setTitle("Registration");
stage.setScene(scene);
stage.setResizable(false);
stage.show();
} catch(IOException e){
e.printStackTrace();
}
}
现在我想通过根节点 vboxRoot:
在控制器 class 'Registrierung.java' 中获取对 'registrierung.fxml' 阶段的引用
@FXML
private VBox vboxRoot;
Stage stage = (Stage) vboxRoot.getScene().getWindow();
但是 'getScene()' 总是导致 NullPointerException。两个 FXML 文件的控制器 classes 在 Scene Builder 中进行了调整。
这就是我在 'registrierung.fxml' 中设置 rood 节点的方式:
<VBox fx:id="vboxRoot" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="267.0" prefWidth="355.0" stylesheets="@../css/styles.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="businesslogik.Registrierung">
我做错了什么?
您正在尝试获取尚未初始化的对象的场景。如果您在
中执行相同的操作
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
Stage stage = (Stage) vboxRoot.getScene().getWindow();
}
或者如果您有一个在您单击某物时触发的事件(在场景加载后执行)
@FXML
private void action(ActionEvent event) throws IOException {
Stage stage = (Stage) vboxRoot.getScene().getWindow();
}
这行得通!
我已经 运行 解决了这个问题,并且通过调用这样的方法找到了(当场景变得可见并附加到节点时,这将触发):
private void determinePrimaryStage() {
rootPane.sceneProperty().addListener((observableScene, oldScene, newScene) -> {
if (oldScene == null && newScene != null) {
// scene is set for the first time. Now its the time to listen stage changes.
newScene.windowProperty().addListener((observableWindow, oldWindow, newWindow) -> {
if (oldWindow == null && newWindow != null) {
primaryStage = (Stage)newWindow;
}
});
}
});
}`
那我以后可以做这样的事情:
if(primaryStage == null) {
Platform.runLater(()-.{......
}else {
//do whatever
}
希望对您有所帮助。
实现 Initializable 接口对我不起作用(Java 8)。
getScene() 方法总是为我返回 null。所以我必须执行以下操作:
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyGui.fxml"));
Parent root = (Parent)loader.load();
//do stage and scene stuff - i skip it here
MyController controller = (MyController)loader.getController();
stage.setOnShown(controller::adjustUI);
在控制器中我有:
public void adjustUI(WindowEvent event) {
Scene scene = myComponent.getScene();
//do stuff and do ui adjustments here
}
我刚开始使用 JavaFX Scene Builder 构建一个小应用程序。
它由属于 'login.fxml' 的控制器 class 'Login.java' 组成,其中 FXML 文件 'registrierung.fxml' 通过名为 [=29] 的方法加载=]:
public class Login {
@FXML
private void registrationClicked(ActionEvent event){
try{
((Node) (event.getSource())).getScene().getWindow().hide();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/fxml/registrierung.fxml"));
Parent root = (Parent) loader.load();
Stage stage = new Stage();
Scene scene = new Scene(root);
stage.setTitle("Registration");
stage.setScene(scene);
stage.setResizable(false);
stage.show();
} catch(IOException e){
e.printStackTrace();
}
}
现在我想通过根节点 vboxRoot:
在控制器 class 'Registrierung.java' 中获取对 'registrierung.fxml' 阶段的引用@FXML
private VBox vboxRoot;
Stage stage = (Stage) vboxRoot.getScene().getWindow();
但是 'getScene()' 总是导致 NullPointerException。两个 FXML 文件的控制器 classes 在 Scene Builder 中进行了调整。
这就是我在 'registrierung.fxml' 中设置 rood 节点的方式:
<VBox fx:id="vboxRoot" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="267.0" prefWidth="355.0" stylesheets="@../css/styles.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="businesslogik.Registrierung">
我做错了什么?
您正在尝试获取尚未初始化的对象的场景。如果您在
中执行相同的操作@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
Stage stage = (Stage) vboxRoot.getScene().getWindow();
}
或者如果您有一个在您单击某物时触发的事件(在场景加载后执行)
@FXML
private void action(ActionEvent event) throws IOException {
Stage stage = (Stage) vboxRoot.getScene().getWindow();
}
这行得通!
我已经 运行 解决了这个问题,并且通过调用这样的方法找到了(当场景变得可见并附加到节点时,这将触发):
private void determinePrimaryStage() {
rootPane.sceneProperty().addListener((observableScene, oldScene, newScene) -> {
if (oldScene == null && newScene != null) {
// scene is set for the first time. Now its the time to listen stage changes.
newScene.windowProperty().addListener((observableWindow, oldWindow, newWindow) -> {
if (oldWindow == null && newWindow != null) {
primaryStage = (Stage)newWindow;
}
});
}
});
}`
那我以后可以做这样的事情:
if(primaryStage == null) {
Platform.runLater(()-.{......
}else {
//do whatever
}
希望对您有所帮助。
实现 Initializable 接口对我不起作用(Java 8)。 getScene() 方法总是为我返回 null。所以我必须执行以下操作:
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyGui.fxml"));
Parent root = (Parent)loader.load();
//do stage and scene stuff - i skip it here
MyController controller = (MyController)loader.getController();
stage.setOnShown(controller::adjustUI);
在控制器中我有:
public void adjustUI(WindowEvent event) {
Scene scene = myComponent.getScene();
//do stuff and do ui adjustments here
}