确定何时从节点内部关闭JavaFX Stage

时间:2019-02-21 14:20:12

标签: javafx-8

我有一个SplitPane,其中有一些显示动态数据的选项卡,因此每当关闭选项卡时,我都想确保所有与数据的连接都已关闭。这是通过侦听选项卡中节点的sceneProperty来完成的,当SceneProperty更改为null时,由于选项卡已关闭,因此连接已关闭。

将选项卡从SplitPane移到其自己的窗口中的可能性将其全部改变了一点。现在,当SceneProperty更改时,计划安排一个任务等待一秒钟,然后检查Node上的SceneProperty是否仍然为空,然后关闭连接。所有这些都是为了避免在将选项卡转移到其自己的窗口时关闭连接,因为在此期间,SceneProperty会非常短暂地变为null。这仍然可以关闭选项卡,但是奇怪的是,当节点具有自己的窗口时,它不起作用,这显然是由于即使关闭窗口后,窗口rootNode上的SceneProperty也不为空。

现在我想知道那怎么可能...?

这基本上是所有代码

// somewhere in the constructor
rootNode.sceneProperty().addListener((observable, oldValue, newValue) -> subscriptionChange(newValue));

private void subscriptionChange(Scene newValue) {
    if (newValue == null) {
        scheduleUnsubscribeTask();
    }
}

private void scheduleUnsubscribeTask() {
    UnsubscribeTask unsubscribeTask = new UnsubscribeTask(this::handleUnsubscription);
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(1);
scheduledPool.schedule(unsubscribeTask, TTL_MS, TimeUnit.MILLISECONDS);
}

private void handleUnsubscription() {
    if (paneMain.getScene() == null) {
       closeConnection();
   }
}

1 个答案:

答案 0 :(得分:0)

  

现在我想知道那怎么可能...?

关闭Window对关联的Scene无效。 scene属性也独立于要添加到窗口中的场景;它只是表明节点所在的节点结构的根是否是场景的根。

如果要检查节点是否属于所示场景,我建议使用Bindings.selectBoolean。否则,您需要(取消)注册/移动3个侦听器(Node.sceneScene.windowWindow.showing属性)。

private BooleanBinding showing;
showing = Bindings.selectBoolean(button.sceneProperty(), "window", "showing");
showing.addListener((o, oldValue, newValue) -> {
    if (!newValue) {
        scheduleUnsubscribeTask();
    }
});

...

private void handleUnsubscription() {
    if (!showing.get()) {
       closeConnection();
   }
}

但是,我建议改为为场景内容引入一些生命周期。这样,您就可以完全控制场景所需的资源。