JavaFX:窗格上的触发器不可见/已销毁

JavaFX:窗格上的触发器不可见/已销毁,javafx,eventtrigger,pane,Javafx,Eventtrigger,Pane,我想用可变内容填充窗格varPane。实现与此类似 Pane varPane = new Pane(); // .. someProperty.addListener(( obsv, oldV, newV) -> { varPane.getChildren().clear(); // Remove old Property Pane Content Pane propPane = getNewPane(newV); // Get new content

我想用可变内容填充窗格varPane。实现与此类似

Pane varPane = new Pane();
// ..

someProperty.addListener(( obsv, oldV, newV) -> {
    varPane.getChildren().clear();    // Remove old Property Pane Content
    Pane propPane = getNewPane(newV);     // Get new content
    varPane.getChildren().add(propPane);  // add Content
});
生成的窗格如下所示:

public Pane getNewPane(Object newV){
       Pane myPane = new Pane();

       // Add dummy Content
        myPane.getChildren().add(new Label(newV.toString()))

        // Here I need some listener
        // somthing like [not working]:
        myPane.setOnClosed( System.out.println("Pane closed: " + newV.toString() );

        return myPane;
}
如上所述,我需要在不再使用窗格后执行一些清理。然而,我找不到正确的方法来实现这样一个侦听器

如果出现以下情况,则应触发侦听器:

varPane的内容已更改,旧窗格不再可见,或者 如果varPane被破坏,例如在平台上。退出 我可以要求在这些事件上调用一个函数进行清理。不过,我认为如果窗格自己检测到此类事件,会更安全。

首先请注意,它不会按照您的想法进行操作。你需要

varPane.getChildren().clear();
您可以检查窗格的parentProperty是否更改为null:

myPane.parentProperty().addListener((obs, oldParent, newParent) -> {
    if (newParent == null) {
         System.out.println("Pane closed: " + newV);
    }
});
检查包含窗格的窗口是否隐藏或关闭相当困难。您可以创建以下侦听器链,基本上侦听窗格的sceneProperty,以便侦听场景的windowProperty,以便侦听窗口的showingProperty:

ChangeListener<Boolean> showingListener = (obs, wasShowing, isNowShowing) -> {
    if (! isNowShowing) {
        System.out.println("Window containing "+newV+" hidden");
    }
};
ChangeListener<Window> windowListener = (obs, oldWin, newWin) -> {
    if (oldWin != null) {
        oldWin.showingProperty().removeListener(showingListener);
    }
    if (newWin != null) {
        newWin.showingProperty().addListener(showingListener);
    }
};
ChangeListener<Scene> sceneListener = (obs, oldScene, newScene) -> {
    if (oldScene != null) {
        oldScene.windowProperty().removeListener(windowListener);
        if (oldScene.getWindow() != null) {
            oldScene.getWindow().showingProperty().removeListener(showingListener);
        }
    }
    if (newScene != null) {
        newScene.windowProperty().addListener(windowListener);
        if (newScene.getWindow() != null) {
            newScene.getWindow().showingProperty().addListener(showingListener);
        }
    }
};
myPane.sceneProperty().addListener(sceneListener);
EventStreams.changesOf(Val
    .flatMap(myPane.sceneProperty(), Scene::windowProperty)
    .flatMap(Window::showingProperty)
    .orElseConst(false))
    .filter(c -> ! c.getNewValue())
    .observe(v -> System.out.println("Pane closed: "+newV));