setScene() 方法,JavaFX

setScene() method, JavaFX

我有一个包含少量 fxml 文件的程序,因此在程序的不同点显示不同的场景和布局。

some point in a program:
mainStage.setScene(FXMLScene1);
...
later in a program:
mainStage.setScene(FXMLScene2);
...
later in a program:
mainStage.setScene(FXMLScene2);

我想知道当我多次使用 setScene() 时旧场景会发生什么情况?

有很复杂的场景切换方法(像这样https://blogs.oracle.com/acaicedo/entry/managing_multiple_screens_in_javafx1),我的解决方案只是在MainApplicationclass静态引用主舞台,这样我就可以在任何地方管理它。

public class MainApplication extends Application {
    public static Stage parentWindow;
    @Override
    public void start(Stage stage) throws Exception {
        parentWindow = stage;

所以这让我怀疑我的概念是否一切正常...

您不必创建场景来翻转屏幕。可以直接在当前场景设置根节点,使用setRoot() of the Scene.

这将使您免于每次都想更改应用程序内容而创建场景实例的痛苦。

你可以使用它:

Parent root = FXMLLoader.load(getclass.getResource("some-fxml.fxml"));
scene.setRoot(root);

请记住要设置为根元素的 FXML 中使用的父元素。来自文档

The application must specify the root Node for the scene graph by setting the root property. If a Group is used as the root, the contents of the scene graph will be clipped by the scene's width and height and changes to the scene's size (if user resizes the stage) will not alter the layout of the scene graph. If a resizable node (layout Region or Control is set as the root, then the root's size will track the scene's size, causing the contents to be relayed out as necessary.

N.B. 请仔细阅读您提供的 EXAMPLE,它使用 setScreen( ) 而不是 setScene( )。整个例子只有一个 Scene 和许多 Screens,其中屏幕可以被认为是任何 child of the scene graph

根据评论补充数据

如果你浏览场景javadoc,你会发现Scene resizes itself to the root size, if no predefined size is present

The scene's size may be initialized by the application during construction. If no size is specified, the scene will automatically compute its initial size based on the preferred size of its content. If only one dimension is specified, the other dimension is computed using the specified dimension, respecting content bias of a root.

不同的FXML有不同的大小

如果您想将不同的 FXML 设置为 ROOT 节点,并且每个节点都有不同的 sizes.Futhermore,您希望根据加载的每个 FXML 重新调整舞台大小,那么您将不得不重新初始化场景,没有别的办法。

Parent root = FXMLLoader.load(getclass.getResource("some-fxml.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);

如果你在你的舞台上设置了一个新场景并且没有引用旧场景或其中的对象,旧场景将被垃圾收集并且所有与之相关的资源都将被丢弃(每当垃圾收集器在Java 虚拟机决定这样做)。如果您保留对旧场景的引用(例如,将其分配给应用程序中的静态最终变量),那么旧场景资源将保留在内存中,直到您的应用程序终止。

If I change the root, how to make Stage change to the new size(size of Layout)?

使用 stage.sizeToScene(),这将: "Set the width and height of this Window to match the size of the content of this Window's Scene." 调用此调用时调整舞台大小的过程类似于最初显示舞台时的过程,但会针对当前场景的内容和布局约束进行更新。

所使用的算法记录在Scene javadoc中:"The scene's size may be initialized by the application during construction. If no size is specified, the scene will automatically compute its initial size based on the preferred size of its content. If only one dimension is specified, the other dimension is computed using the specified dimension, respecting content bias of a root."

what is better, to change the whole scene, or just a root?

我认为这没有太大区别,请选择对您最有意义的策略。