为什么formWindowClosed在处理后在JDialog中被触发两次

时间:2014-04-27 04:57:47

标签: java swing

Show prompt before closing JFrame

我希望在我们真正退出应用之前提示用户输入。到目前为止,以下技术适用于JFrame

public class JavaApplication1 extends javax.swing.JFrame {

    public JavaApplication1() {
        this.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });        
    }

    private void formWindowClosing(java.awt.event.WindowEvent evt) {                                
        System.out.println("formWindowClosing : Are you sure you want to quit?");
        if (true)
            this.dispose();
    }

    private void formWindowClosed(java.awt.event.WindowEvent evt) {
        System.out.println("formWindowClosed");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JavaApplication1 m = new JavaApplication1();

                m.setSize(300, 200);

                m.setVisible(true);
            }
        });
    }
}

将打印以下内容

formWindowClosing : Are you sure you want to quit?
formWindowClosed

但是,当我从JFrame更改为JDialog时,formWindowClosed会被调用两次!

formWindowClosing : Are you sure you want to quit?
formWindowClosed
formWindowClosed

这里是代码

public class JavaApplication1 extends javax.swing.JDialog {

    public JavaApplication1() {
        this.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });        
    }

    private void formWindowClosing(java.awt.event.WindowEvent evt) {                                
        System.out.println("formWindowClosing : Are you sure you want to quit?");
        if (true)
            this.dispose();
    }

    private void formWindowClosed(java.awt.event.WindowEvent evt) {
        System.out.println("formWindowClosed");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JavaApplication1 m = new JavaApplication1();

                m.setSize(300, 200);

                m.setVisible(true);
            }
        });
    }
}

我可以知道为什么会这样吗?这是一个错误吗?我怎么能阻止这个?我不想使用System.exit,因为此对话框可能是子对话框,而不是主应用程序对话框。

1 个答案:

答案 0 :(得分:2)

当事件是JDialog时,事件来自两个不同的来源。我更新了你的窗口关闭方法,以提供这样的堆栈跟踪:

private void formWindowClosed(java.awt.event.WindowEvent evt) {
    Exception e = new Exception();
    e.printStackTrace();
    System.out.println("formWindowClosed");
}

您可以在堆栈跟踪中告知事件的来源:   java.awt.AWTEventMulticaster.windowClosed来自java.awt.Window.processWindowEvent,另一来自formWindowClosing : Are you sure you want to quit? java.lang.Exception at JavaApplication1.formWindowClosed(JavaApplication1.java:25) at JavaApplication1.access$0(JavaApplication1.java:24) at JavaApplication1$1.windowClosed(JavaApplication1.java:10) at java.awt.AWTEventMulticaster.windowClosed(Unknown Source) at java.awt.Window.processWindowEvent(Unknown Source) at javax.swing.JDialog.processWindowEvent(Unknown Source) at java.awt.Window.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Window.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$200(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue$4.run(Unknown Source) at java.awt.EventQueue$4.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) formWindowClosed java.lang.Exception at JavaApplication1.formWindowClosed(JavaApplication1.java:25) at JavaApplication1.access$0(JavaApplication1.java:24) at JavaApplication1$1.windowClosed(JavaApplication1.java:10) at java.awt.Window.processWindowEvent(Unknown Source) at javax.swing.JDialog.processWindowEvent(Unknown Source) at java.awt.Window.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Window.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$200(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue$4.run(Unknown Source) at java.awt.EventQueue$4.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) formWindowClosed 。希望这会有所帮助。

完整堆栈输出:

{{1}}