首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >JavaFX:如何在初始化时从控制器获取stage?

JavaFX:如何在初始化时从控制器获取stage?
EN

Stack Overflow用户
提问于 2012-11-06 15:18:36
回答 7查看 159K关注 0票数 97

我想从我的控制器类中处理阶段事件(即隐藏)。所以我要做的就是通过添加一个监听器

代码语言:javascript
代码运行次数:0
运行
复制
((Stage)myPane.getScene().getWindow()).setOn*whatIwant*(...);

但问题是初始化在初始化后立即开始。

代码语言:javascript
代码运行次数:0
运行
复制
Parent root = FXMLLoader.load(getClass().getResource("MyGui.fxml"));

在此之前

代码语言:javascript
代码运行次数:0
运行
复制
Scene scene = new Scene(root);
stage.setScene(scene);

因此,.getScene()返回null。

我自己找到的唯一解决办法是向myPane.sceneProperty()添加一个侦听器,当它变为非空时,我得到scene,添加到它的.windowProperty()我的天哪!侦听器处理,我最终检索阶段。这一切都以设置所需的侦听器来上演事件而结束。我觉得听众太多了。这是解决我问题的唯一方法吗?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-11-06 16:18:22

您可以在通过getController()初始化之后从FXMLLoader获取控制器的实例,但是您需要实例化一个FXMLLoader,而不是使用静态方法。

之后,我会在直接调用load()到控制器之后通过这个阶段:

代码语言:javascript
代码运行次数:0
运行
复制
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyGui.fxml"));
Parent root = (Parent)loader.load();
MyController controller = (MyController)loader.getController();
controller.setStageAndSetupListeners(stage); // or what you want to do
票数 123
EN

Stack Overflow用户

发布于 2015-07-29 04:48:08

您所需要做的就是给AnchorPane一个ID,然后您就可以从中获得Stage

代码语言:javascript
代码运行次数:0
运行
复制
@FXML private AnchorPane ap;
Stage stage = (Stage) ap.getScene().getWindow();

在这里,您可以添加所需的Listener

编辑:正如下面的EarthMind所述,它不一定是AnchorPane元素;它可以是您定义的任何元素。

票数 118
EN

Stack Overflow用户

发布于 2015-06-18 16:19:19

我知道这不是你想要的答案,但我认为提出的解决方案并不好(而你自己的方式是)。为什么?因为它们依赖于应用程序状态。在JavaFX中,控件、场景和舞台彼此不依赖。这意味着控件可以在不添加到场景的情况下存在,场景可以在不附加到舞台的情况下存在。然后,在瞬间t1,控件可以附加到场景,并且在瞬间t2,场景可以被添加到阶段(这就解释了为什么它们是彼此的可观察属性)。

因此,建议获取控制器引用并调用方法,将阶段传递给它的方法会向您的应用程序添加一个状态。这意味着您需要在创建stage之后的适当时刻调用该方法。换句话说,你现在需要遵循一个顺序: 1-创建stage 2-通过一个方法将这个创建的stage传递给控制器。

您不能(或不应该)在此方法中更改此顺序。所以你失去了无国籍状态。而在软件中,一般来说,状态是邪恶的。理想情况下,方法不需要任何调用顺序。

那么什么才是正确的解决方案呢?有两种选择:

1-你的方法,在控制器中侦听属性来获得舞台。我认为这是正确的方法。如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
pane.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) {
                // stage is set. now is the right time to do whatever we need to the stage in the controller.
                ((Stage) newWindow).maximizedProperty().addListener((a, b, c) -> {
                    if (c) {
                        System.out.println("I am maximized!");
                    }
                });
            }
        });
    }
});

2-在创建Stage的地方做你需要做的事情(这不是你想要的):

代码语言:javascript
代码运行次数:0
运行
复制
Stage stage = new Stage();
stage.maximizedProperty().addListener((a, b, c) -> {
            if (c) {
                System.out.println("I am maximized!");
            }
        });
stage.setScene(someScene);
...
票数 33
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13246211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档