0

Show prompt before closing JFrame

I wish to prompt user input, before we really quit the app. So far, the following technique works fine for 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);
            }
        });
    }
}

The following will be printed

formWindowClosing : Are you sure you want to quit?
formWindowClosed

However, when I change from JFrame to JDialog, formWindowClosed is called twice!

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

Here the code

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);
            }
        });
    }
}

May I know why it happen such? Is this a bug? How can I prevent this? I do not want to use System.exit, as this dialog may be child dialog, not the main application dialog.

Community
  • 1
  • 1
Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875

1 Answers1

2

The events come from two different sources when it is a JDialog. I updated your window closed method to provide a stack trace like this:

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

And you can tell in the stack traces where the events originate: java.awt.AWTEventMulticaster.windowClosed and the other from java.awt.Window.processWindowEvent. Hope this helps.

Full stack output:

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
Jeff Ward
  • 1,109
  • 6
  • 17