简体   繁体   English

如何获得对当前显示的Java Swing JDialog框的引用?

[英]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. 我正在使用基于Java Swing的框架,该框架使用Java Swing JDialog框显示弹出消息。 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() 要解决此问题,只需使用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. 如果要获取对最前面的JDialog的引用,则必须侦听AWT事件并“实时”更新此引用并将其存储在某个地方。

Here's what I do in my own Swing framework: 这是我在自己的Swing框架中所做的事情:

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; 只需确保在显示任何组件之前在主线程中实例化ActiveWindowHandler from that point on every call to ActiveWindowHandler.getActiveWindow() will return the front-most Window (either JDialog of JFrame ). ActiveWindowHandler.getActiveWindow()起,每次对ActiveWindowHandler.getActiveWindow()调用都将返回最前面的窗口( JFrame JDialog )。

You can get a reference to all of your child windows using getWindows() method on the Window class. 您可以使用Window类上的getWindows()方法获得对所有子窗口的引用。

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. 还有更具体的版本:getOwnedWindows()和getOwnerlessWindows()取决于您的需求。

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(); 窗口w = KeyboardFocusManager.getCurrentKeyboardFocusManager()。getFocusedWindow();

You can then check and cast it to JDialog. 然后,您可以检查并将其投射到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. 如果您显式创建JDialog而不是使用JOptionPane.showXXX您将已经具有对该对话框的引用。 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时,请执行以下操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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