如何在不调整JavaFX窗口大小的情况下从控制器切换根目录?

时间:2018-04-08 18:49:27

标签: java javafx root fxml

(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中更新。)

0 个答案:

没有答案