Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javafx popup won't hide behind other application upon losing focus

So my question, as stated (sort of) in the title, is about the behaviour in some respects of the Javafx (namely 2.2) Popup. Most of the time, you get a popup, and you give it a window to act as it's parent, you give it some scene, and it tends to act relatively independently.

This is all fine, however, in my case, I needed a popup that would anchor itself to a particular stage (window), at a particular location, when an event happened. That popup would then, in turn, disappear when the window disappeared (minimize, off screen, whatever), moved when it would, and in all essence and functionality, be a physical extension of the window, just with a custom shape.

Now of course, there are a lot of nuances with that, and everything for the most part, works great. The only thing I can't seem to figure out is that normally in a platform like Windows 7 64 bit, say. You open two programs, alright. Then if the programs are overlapping a little bit, whichever has focus gets to have the entire program displayed, whereas the other one gives the impression of being 'behind' the other window. (Whether or not windows actually renders application graphics 'behind' a window when another has focus on the same spot, I'm not sure.). Normally, javafx also supports this functionality just fine. But for some reason, The Popup class in javafx (see docs here) doesn't do that. It's always on top of whatever it's displayed with, without exception. For the point of completeness, here's my pretty straightforward popup code (at least the part pertaining to showing it and it's properties):

        Popup myPop = new Popup();
        //************************Popup Property Setter**************************
        //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
        myPop.setWidth(width);
        myPop.setHeight(initialHeight);
        myPop.setAutoHide(false);
        myPop.setAutoFix(false);
        myPop.setHideOnEscape(false);
        myPop.setX(xLocation);
        myPop.setY(yLocation);
        //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
        //**********************end of Popup Properties**************************
        myPop.getContent().add(main_anchor);
        myPop.show(FileChooserWindow.get_stage());

main anchor has some various components i include inside of the 'myPop' popup, and FileChooserWindow is a non-null parent window that will be open at the time of this method calling without exception.

Here is a screenshot as well of the behaviour I'm referring to. Notice the highlighted text in the pdf, that is where my cursor currently has focus. Also, the window that the popup is anchored to can be seen in the back of the pdf poking out from the left. Image Of the stubborn popup

Any help you guys can give would be much appreciated. I really hope I don't have to check for active processes and their location relative to the popup, that's getting dangerously close to my knowledge border, and sounds like a total PITA.

like image 948
WillBD Avatar asked Oct 20 '22 14:10

WillBD


1 Answers

So, after toying with this for a few more days, I have a rough workaround, although it is a hack in the full meaning of the term.

Although the popup behaviour is still mystifying me, I can simulate a fix in this behaviour by adding a changeListener to the stage to which it is attached (since I didn't want the popup to close if it's parent window had focus, only if anything BUT the popup and it's parent got focus).

See code as follows:

FileChooserWindow.get_stage().focusedProperty().addListener(new ChangeListener<Boolean>(){
            @Override
            public void changed(ObservableValue<? extends Boolean> ov, Boolean oldValue, Boolean newValue) {
                if (!newValue){
                    if(AutogenPopup.popupReturner().focusedProperty().get()){
                        AutogenPopup.popupReturner().hide();
                    }
                }else{
                    if(FileChooserController.refreshAutoPopup && FileChooserController.autoGen_flag){
                        AutogenPopup.popupReturner().show(FileChooserWindow.get_stage());
                    }
                }
            }

        });

never mind some of those flags that I'm checking against, they are simply some internal tools to make sure that the popup only appears when the program is in the proper state.

Now, one interesting thing to note. The AutogenPopup.popupReturner().focusedProperty().get() Seemed to be returning true when the popup's parent window LOST focus. Which is quite counter-intuitive to me, and in my opinion, is even a touch buggy. Now, this does not simulate the behaviour of a modern operating system where a window can slide in and out of focus incrementally, since the popup will just completely disappear upon it's parent window losing focus. But seeing as how my popup just displays additional text entry on the side of the main window, this is an acceptable compromise until I think of a better solution. (Perhaps the better solution is not to use a popup at all, and instead skin a window to act in a popup-y fashion).

Anyway, I hope this helps someone, maybe eventually there will be a more fine-grained way to control this popup functionality.

like image 100
WillBD Avatar answered Nov 02 '22 06:11

WillBD