4

I have a JFrame that spawns two JDialogs. Each of the three windows needs to be focusable (and are the way I currently have it written) but that JFrame won't go atop the dialogs. When you click on either dialog, they'll pop on top of each other (like one would expect), but that JFrame just refuses to come to the front.

I need them to remain JDialogs (as opposed to being JFrames themselves) since most of the current behavior is desirable (i.e. when another window/application blocks any or all of the windows, if you select any of the windows they all come to the front (whereas three JFrames would result in only the selected one coming forward)).

My JDialogs constructors are to this effect:

SubDialog(JFrame parent /*, a handful, ofOther arguments */){
    super(parent, ModalityType.MODELESS); //not even the modeless helped
    setAlwaysOnTop(false); //not even the not always on top helped
    setUndecorated(true); //maybe this has something to do with it (unlikely, just fyi)?

    //some simple variable assignments

}

I even tried tossing a setAlwaysOnTop(true) in my JFrame. No dice. I was getting desperate and even tried one of these numbers:

MyJFrame(String title){
    super(title);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    addWindowFocusListener(new WindowAdapter(){
        public void windowGainedFocus(WindowEvent e){
            final Window w = e.getWindow();

            //PLEASE come to the front
            w.toFront();

            //even MOAR desperation
            SwingUtilities.invokeLater(new Runnable(){
                public void run(){
                    w.toFront(); //STILL no dice.
                }
            });
        }
    });
}

Thoughts? I got nothin'.

captainroxors
  • 718
  • 7
  • 18
  • 1
    I think you mean "ModalityType.MODELESS", not "ModilityType.MODELESS"? Also, try calling setModal(false); – dberm22 Mar 07 '14 at 20:26
  • Oops. Good eye. Spelling fixed. Setting ModalityType.MODELESS is identical to calling setModal(false). In fact, calling setModal(false) actually changes the modality type to MODELESS. I still tried it anyways, just in case. No dice. – captainroxors Mar 07 '14 at 20:56

2 Answers2

5

How to make a JDialog not always on top of parent

As stated in this Q&A: setModal issue with 2 Jdialogs within a Jframe:

This behaviour depends on how native windowing system handles focused and active windows. Having said this if you call for instance toFront() it will attempt to place the window at the top of the stack BUT some platforms do not allow windows which own other windows to appear on top of its children. The same happens when you call toBack() method. See the javadocs for more details.

For instance on Windows 7 parent dialog becomes focused but its children still showing (not focused) at the top. As mentioned above it's up to the windowing system decide how to handle this matter.

Community
  • 1
  • 1
dic19
  • 17,821
  • 6
  • 40
  • 69
  • 3
    In other words, "It can't be done [cleanly]". I was afraid of that. – captainroxors Mar 10 '14 at 16:06
  • @captainroxors unfortunately you're right. Just a workaround would be creating MODELESS dialogs *without* parent. Then you could take the frame to the front. – dic19 Mar 10 '14 at 16:12
0

It is very easy to achieve this, see the following code:

    JFrame frame = new JFrame();
    frame.setBounds(0,0,400,200);
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

// Special attention to this line, do not use same JFrame, create a dummy JFrame
// If you want to save memory you can also use new JDialog((JFrame)null)
    JDialog jd = new JDialog(new JFrame());
    jd.setModalityType(Dialog.ModalityType.MODELESS);
    jd.setBounds(0,0,100, 100);
    jd.setVisible(true);
Sourabh Bhat
  • 1,793
  • 16
  • 21
  • 1
    Well, yeah, that makes it so the dialogs and the frame can flow on top of each other, but now they're no longer related. Creating that dummy JFrame is the equivalent of not passing a parent frame into the constructor. This destroys the original behavior I mentioned "i.e. when another window/application blocks any or all of the windows, if you select any of [my application's] windows they ALL come to the front" (emphasis added). I may as well have three independent JFrames at that point. – captainroxors Mar 07 '14 at 21:48
  • Let me reframe your question. So if A is a `JFrame`, B and C are `JDialog` with parent A, and D is another `JFrame`. What you want is: 1) If A is selected when B & C are above then B & C must go below, 2) If D is active and A is clicked-upon B & C must popup? I wonder why do you want such a behaviour? – Sourabh Bhat Mar 07 '14 at 22:06
  • Rather than think of JFrame D (I'm assuming you meant residing in the same JVM), I'm meaning a completely different application running, e.g. Photoshop, Firefox, Windows Explorer (nothing even remotely related to my Java application). So yes, I definitely want B & C to show up when A is selected (i.e. the whole application comes in front of all others), and since A was selected, I expect it to go atop B & C. Does that make sense? Apologies for not conveying my intention clearly. – captainroxors Mar 07 '14 at 23:38