简体   繁体   中英

How do I get a reference to the currently displayed Java Swing JDialog box?

I am using a Java Swing based framework that shows popup messages using Java Swing JDialog boxes. I need to get a reference the them so I cam close them programatically. The framework creates dialog boxes but doesn't keep a reference to them. Can I get a reference to the currently displayed box?

Thanks.

Try this :

import java.awt.Window;
import javax.swing.JDialog;

public class Test {
    public static void main(String[] args) {
        JDialog d = new JDialog((Window)null,"Demo Dialog");
        for (Window w : JDialog.getWindows()) {
            if ( w instanceof JDialog) {
                System.out.println(((JDialog)w).getTitle());
            }
        }
    }
}

And if you are puzzled by the :

(Window)null

cast, simply try to compile without it :)

(BTW passing a null window to the constructor creates an unowned dialog)

EDIT: Please note that this will give you references to ALL dialogs regardless of whether they are visible as the code demonstrates. To fix it simply query the dialog on whether it is visible by using isVisible()

if you want to get a reference to the front-most JDialog, then you have to listen to AWT events and update this reference "live" and store it somewhere.

Here's what I do in my own Swing framework:

public class ActiveWindowHolder
{
    public DefaultActiveWindowHolder()
    {
        _current = null;
        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener()
        {
            public void eventDispatched(AWTEvent e)
            {
                DefaultActiveWindowHolder.this.eventDispatched(e);
            }
        }, AWTEvent.WINDOW_EVENT_MASK);
    }

    public Window getActiveWindow()
    {
        return _current;
    }

    private void eventDispatched(AWTEvent e)
    {
        switch (e.getID())
        {
            case WindowEvent.WINDOW_ACTIVATED:
            _current = ((WindowEvent) e).getWindow();
            break;

            case WindowEvent.WINDOW_DEACTIVATED:
            _current = null;
            break;

            default:
            // Do nothing (we are only interested in activation events)
            break;
        }
    }

    private Window _current;    
}

Just make sure you instantiate ActiveWindowHandler in your main thread before showing any component; from that point on every call to ActiveWindowHandler.getActiveWindow() will return the front-most Window (either JDialog of JFrame ).

You can get a reference to all of your child windows using getWindows() method on the Window class.

public static Window[] getWindows()

    Returns an array of all Windows, both owned and ownerless, created by this application. If called from an applet, the array includes only the Windows accessible by that applet.

Be carefull as I suspect one of the windows returned will be your top level frame/window. You can check window attributes such as title to determine which is the dialogue you want to close.

There are also more specific versions: getOwnedWindows() and getOwnerlessWindows() depending on your needs.

I don't see a way to know what is currently open as a child of a frame - I only see methods for getting the parent frames.

Can you alter the current classes calling the dialog boxes? If so, you could add a container to keep track of things as they open and close and add some methods for accessing that container.

Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();

You can then check and cast it to JDialog.

But like I said in your previous question - you have to change your approach.

If you create the JDialog explicitly rather than using JOptionPane.showXXX you will already have a reference to the dialog. This would definitely be my preferred approach; eg

JDialog dlg = new JDialog(null, "My Dialog", false); // Create non-modal dialog.
dlg.setLayout(new BorderLayout());
dlg.add(myPanel, BorderLayout.CENTER);
dlg.pack();
dlg.setLocationRelativeTo(null);
dlg.setVisible(true);

either set the dialog as modal, which makes your life really easy...
OR, when you're initialising your JDialog have the following:

JDialog d = new JDialog();  
d.addWindowListener(new WindowAdapter(){
    public void windowClosed(WindowEvent e){
        dialogClosedAlertFunction(); //goes wherever you want it to go
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM