JavaFX:在窗格上触发不可见/已销毁
JavaFX: Trigger on Pane not visible / destroyed
我想用可变内容填充一个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.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
被摧毁(例如 Platform.exit()
)
我可能需要在这些事件中调用一个函数来进行清理。但是我认为如果窗格自己检测到此类事件会更安全。
首先请注意,varPane.getChildren().removeAll()
并不像您想象的那样。你需要
varPane.getChildren().clear();
您可以检查窗格的 parentProperty()
是否更改为空:
myPane.parentProperty().addListener((obs, oldParent, newParent) -> {
if (newParent == null) {
System.out.println("Pane closed: " + newV);
}
});
检查包含窗格的 window 是否隐藏(关闭)要困难得多。您可以创建以下监听器链(基本上监听窗格的 sceneProperty()
以监听场景的 windowProperty()
以监听 window 的 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);
您可能更喜欢使用绑定框架,例如 ReactFX 的一部分。使用 ReactFX,您可以用
涵盖这两种情况
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));
我想用可变内容填充一个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.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
被摧毁(例如Platform.exit()
)
我可能需要在这些事件中调用一个函数来进行清理。但是我认为如果窗格自己检测到此类事件会更安全。
首先请注意,varPane.getChildren().removeAll()
并不像您想象的那样。你需要
varPane.getChildren().clear();
您可以检查窗格的 parentProperty()
是否更改为空:
myPane.parentProperty().addListener((obs, oldParent, newParent) -> {
if (newParent == null) {
System.out.println("Pane closed: " + newV);
}
});
检查包含窗格的 window 是否隐藏(关闭)要困难得多。您可以创建以下监听器链(基本上监听窗格的 sceneProperty()
以监听场景的 windowProperty()
以监听 window 的 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);
您可能更喜欢使用绑定框架,例如 ReactFX 的一部分。使用 ReactFX,您可以用
涵盖这两种情况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));