为了账号安全,请及时绑定邮箱和手机立即绑定

JavaFX:如何在初始化期间从控制器获得阶段?

JavaFX:如何在初始化期间从控制器获得阶段?

婷婷同学_ 2019-11-29 09:23:54
我想处理控制器类中的舞台事件(即隐藏)。所以我要做的就是通过添加一个监听器((Stage)myPane.getScene().getWindow()).setOn*whatIwant*(...);但问题是初始化是在之后立即开始的Parent root = FXMLLoader.load(getClass().getResource("MyGui.fxml"));和之前Scene scene = new Scene(root);stage.setScene(scene);因此.getScene()返回null。我自己发现的唯一解决方法是将侦听器添加到myPane.sceneProperty(),当它变为不为null时,我得到场景,将其添加到.windowProperty()我的!该死!侦听器处理,这是我终于检索到的阶段。最后,设置所需的侦听器来安排事件。我认为听众太多。这是解决我的问题的唯一方法吗?
查看完整描述

3 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

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


之后load()直接调用控制器后,我将通过阶段:


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


查看完整回答
反对 回复 2019-11-29
?
GCT1015

TA贡献1827条经验 获得超4个赞

您只需要提供AnchorPane一个ID,然后您就可以从中获得ID Stage。


@FXML private AnchorPane ap;

Stage stage = (Stage) ap.getScene().getWindow();

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


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


查看完整回答
反对 回复 2019-11-29
?
子衿沉夜

TA贡献1828条经验 获得超3个赞

我知道这不是您想要的答案,但是IMO提出的解决方案不是很好(您自己的方式是)。为什么?因为它们取决于应用程序状态。在JavaFX中,控件,场景和舞台彼此不依赖。这意味着控件可以生存而无需添加到场景中,而场景可以存在而无需附加到舞台上。然后,在时刻t1,控件可以附加到场景,而在时刻t2,可以将该场景添加到舞台(这说明了为什么它们是彼此可观察的属性)。


因此,建议获取控制器引用并调用方法,将阶段传递给它的方法会为您的应用程序添加状态。这意味着您需要在创建阶段之后的适当时候调用该方法。换句话说,您需要立即执行以下命令:1-创建阶段2-通过一种方法将该创建的阶段传递给控制器。


您不能(或不应)以这种方式更改此顺序。因此,您失去了无国籍状态。在软件中,状态通常是邪恶的。理想情况下,方法不需要任何调用顺序。


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


1-您的方法,在控制器的侦听属性中获得舞台。我认为这是正确的方法。像这样:


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(那不是您想要的):


Stage stage = new Stage();

stage.maximizedProperty().addListener((a, b, c) -> {

            if (c) {

                System.out.println("I am maximized!");

            }

        });

stage.setScene(someScene);

...


查看完整回答
反对 回复 2019-11-29
  • 3 回答
  • 0 关注
  • 680 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信