(James_D向我展示了解决方案。我将详细说明它对我的帮助以及我在这个问题的最后所做的工作。希望其他人认为它很有用。)
我错误的初步方法:
我的程序中有几个FXML文件及其控制器。我加载了FXML文件并更改了场景。它导致窗口大小在最大化时发生变化。
然后this回答显示我应该改变根。
目前的方法和问题:
我尝试了答案中给出的代码,它完美无瑕。首先,我在start方法中设置了一个root,并在一段时间延迟后切换到anther root。它只是检查。它看起来像这样:
package com;
import java.io.IOException;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Launcher extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
StackPane root = FXMLLoader.load(getClass().getResource("/com/Scene2.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setMaximized(true);
stage.show();
Timeline timeline2 = new Timeline(new KeyFrame(Duration.millis(1000), e2 -> {
try {
StackPane root2 = FXMLLoader.load(getClass().getResource("/com/Scene1.fxml"));
scene.setRoot(root2);
} catch (IOException e1) {
e1.printStackTrace();
}
}));
timeline2.play();
}
}
在我的实际程序中,start方法加载FXML文件。稍后我点击屏幕上的按钮或其他应该更改根的内容。所以我必须在控制器中使用类似的代码。但要设置根,我需要得到现场。在start方法中,场景已经创建并可用。我无法弄清楚如何在控制器中获得它。所以我尝试在控制器中创建一个新场景。但它不起作用。它不会抛出异常或任何东西。当我按下按钮时,程序根本不做任何事情。这是控制器中的相关代码。
public void changeRoot(ActionEvent event) throws IOException {
try {
Parent root2 = FXMLLoader.load(getClass().getResource("/com/Scene2.fxml"));
// I added the line below.
Scene scene = new Scene(root2);
scene.setRoot(root2);
} catch (IOException e1) {
e1.printStackTrace();
}
}
解决方案:
那么。从下面的注释中可以看出,我可以通过在当前场景中的任何节点上调用getScene()来获取场景。在我的示例代码中,我在当前屏幕上有一个按钮。按钮是一个节点。所以我用它来获取场景。我只是分享控制器类的代码,所以你知道我的意思。
package com;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Scene1Controller implements Initializable {
@FXML
private Button button;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
public void changeRoot(ActionEvent event) throws IOException {
try {
Parent root2 = FXMLLoader.load(getClass().getResource("/com/Scene2.fxml"));
button.getScene().setRoot(root2); // Here I get the scene using the button and set the root.
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
现在你应该记住一些事情。您必须确保为FXML中的节点提供fx:id。它应该与控制器中节点的给定变量名匹配。例如,在我的控制器中,我有一个Button。我已将其命名为“按钮”。我还确保FXML文件中按钮的ID为“按钮”。设置fx:id非常容易。我使用了Gluon Scene Builder。 (有时我在那里做的更改不会立即在Eclipse中更新。刷新项目确保更新也在Eclipse中更新。)