JDK-8088846 : PopupWindow does not disappear when associated Control is not visible.
  • Type: Bug
  • Component: javafx
  • Sub-Component: scenegraph
  • Affected Version: 8
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2013-02-18
  • Updated: 2016-07-11
  • Resolved: 2016-07-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Fixed
Related Reports
Blocks :  
Relates :  
Description
A Popup/PopupWindow is associated with a Node with show(node,x,y).
It also can be associated with a Window,  show(window)

What should happen when that node is no longer present on the screen? In the attached sample program, the Scene is changed out when the button is clicked, making the associated Node no longer visible on the Screen, and yet the Popup stays visible.

There is code in quantum (GlassScreen) that can have issues with an NPE in a related circumstance (RT-27455).
    @Override public void sceneChanged() {
        if (glassStage instanceof PopupStage) {
            ((PopupStage)glassStage).getOwnerScene().sceneChanged();
        }
The NPE is because getOwnderScene() becomes NULL - showing an issue, because we should either track the Window not the Scene - or take down the PopupWindow when the OwnerScene becomes null. 

But what is the correct behavior here? I would think that when the Node is destroyed or has a visibility change, the popup would too. If associated with a Window, then it would be tied to the Window.
And where do we want to handle this behavior - Quantum and/or Controls ?
Comments
Changeset: a1cfa82b3dfa Author: ckyang Date: 2016-07-11 14:41 -0700 URL: http://hg.openjdk.java.net/openjfx/9-dev/rt/rev/a1cfa82b3dfa
11-07-2016

+1
10-07-2016

Please review the proposed fix: http://cr.openjdk.java.net/~ckyang/JDK-8088846/webrev.00/
09-07-2016

I think I ran into the same problem: showing a ContextMenu from a JFXPanel. When the JFXPanel is removed from its Swing container, the context menu remains visible. Clicking on it causes this: java.lang.NullPointerException at com.sun.javafx.tk.quantum.GlassScene.sceneChanged(GlassScene.java:269) at com.sun.javafx.tk.quantum.ViewScene.sceneChanged(ViewScene.java:156) at com.sun.javafx.tk.quantum.PopupScene.sceneChanged(PopupScene.java:30) at com.sun.javafx.tk.quantum.GlassScene.markDirty(GlassScene.java:136) at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2210) at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:363) at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:460) at com.sun.javafx.tk.quantum.QuantumToolkit$9.run(QuantumToolkit.java:329) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29) at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73) at java.lang.Thread.run(Unknown Source) As a workaround I am extending JFXPanel to add this: @Override public void removeNotify() { Platform.runLater(new Runnable() { @Override public void run() { contextMenu.hide(); } }); super.removeNotify(); }
09-07-2013

Changing component to Scenegraph: When a scene of a Stage is swapped, the old scene's contents visible property is unchanged.
05-03-2013

The fact that impl_treeVisibleProperty() does not change when the scene is reset seems like a bug.
26-02-2013

impl_treeVisibleProperty() is protected in Node. Would have been nice if it were not. Also, when the scene is swapped the owner node's visible Property is not changed (part of the old scene) even though not visible anymore.
26-02-2013

FX can use impl_treeVisibleProperty() to hide the popup. This would be better than forcing the application to do it.
26-02-2013

Who should hide the popup? The application or FX?
26-02-2013

It's possible that Quantum has a bug or some bogus code. The application (in this case a virtual keyboard), would like the popup to be hidden when the node that it was popping up for is no longer visible for some reason. A node may be no longer visible when: 1) the node was hidden 2) a parent of the node was hidden 3) the scene was swapped out (i.e. setScene() is called with a new scene or null) 4) the stage was hidden Whose responsibility is it to hide the popup?
26-02-2013

ChangeScenePopup swaps the scene for me on my Mac desktop. HelloApopup and ChangeScenePopup both fail to hide the popup when the scene is changed. The patch seems to work when the node is explicitly hidden. Does the patch work when a parent of the node is hidden?
26-02-2013

Here is part of my base problem. I assumed that a nextPopup.show(popupParent, popupX, popupY); would tie the Popup to the parent node, but it really is just a convenience method for nextPopup.show(popupParent.getWindow(), x, y) which means that the popup is tied to the Window and could care less about the Node popupParent. The Window here is unchanging - it is only the Scene on that Window that changes. Of course, there is the documentation that says... "The popup is associated with the specified owner node." In the case of the VKB - there is a field in the GlassStagep which ties back to the parentScene which at some point may be disposed, causing a NPE. Perhaps that is the real problem, that we have that dependency.
26-02-2013

The ChangeScenePopup certainly does switch scenes - so maybe part of the problem lies in Quantum. This line here: stage.setScene(current); is used to toggle between scenes. But.... I am pretty sure there is no plumbing in Quantum to tell the old scene that anything happened. So my next question is what events would expect or like to see when Quantum swaps the Scene out ?
22-02-2013

Thanks Jonathan. I have tested it, will test some more before I check it in.
22-02-2013

Patch looks fine to me, although I haven't applied it locally. Assuming you've tested it's +1 from me.
22-02-2013

I have incorporated your feedback Jonathan, and have attached a new patch. This one creates one instance of the ChangeListener; adds on call to show() and removes on call to hide().
22-02-2013

Two comments: 1) It looks like the patch could extract out the ChangeListener for both cases and use one instance for both? 2) Should we remove the two listeners from the owner so as to not leak memory? For example, when the owner is changed or when the popup is not showing?
21-02-2013

Firstly, the attached sample does not seem to actually switch scenes at all. I added the following at the end of handle method in PopupActionHandler and I dont see the expected output. popupParent.visibleProperty().addListener(new ChangeListener<Boolean>() { @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) { System.out.println("popup parent visible = "+t1); } }); popupParent.sceneProperty().addListener(new ChangeListener<Scene>() { @Override public void changed(ObservableValue<? extends Scene> ov, Scene t, Scene t1) { System.out.println("popup parent's scene changed !!"); } }); So the parent node is always visible, and the scene isn't switched either. I have attached a simpler test case that actually tries to either make the parent node not visible or switch scene on the parent's stage. In that case, yes currently the popup stays visible and it should actually hide. I have also attached a patch which does that. Would like someone else to take a look and review it.
21-02-2013

If the popup should be closed then I would think it should be done in controls. Jonathan: if you think it needs to be done by quantum, then go ahead and throw it back to us.
18-02-2013