how to monitor the close event of a JDialog?

xuqin1019 picture xuqin1019 · Aug 5, 2013 · Viewed 8.2k times · Source

I have got a tricky problem. I need to pop a confirm message box for user to decide close or not when someone click the close sign on the right upper corner of the window. But It doesn't work. Whatever you choose in the pop message box , the dialog will always be closed. But the same logic works fine when I create a JFrame.

Below is my code in my netbeans IED. I just use a WindowAdpter to catch the close event, plz igore the dummy code generated by neatbean.

Thanks.

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;


public class TestClosingDialog extends javax.swing.JDialog {

    public TestClosingDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();


        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                int a = JOptionPane.showConfirmDialog(null,"Are you sure you need to close?", "Tip", JOptionPane.YES_NO_OPTION);
                if (a == 0) {  
                    System.out.println("yes " + a);
                    System.exit(0);  //close 
                } else if (a==1) {
                    System.out.println("no " + a);
                } 
            }
       });
    }

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 400, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 300, Short.MAX_VALUE)
    );

    pack();
}// </editor-fold>                        

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(TestClosingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(TestClosingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(TestClosingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(TestClosingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the dialog */
    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            TestClosingDialog dialog = new TestClosingDialog(new JFrame(), true);
            dialog.setVisible(true);
        }
    });
}
// Variables declaration - do not modify                     
// End of variables declaration                   
 }

Answer

MadProgrammer picture MadProgrammer · Aug 5, 2013

Change setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); to setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING);

This will require you to manually dispose of the dialog. Depending on your needs, you would simply need to change System.exit(0); to dispose();

I would, personally, advise against extending directly from a top level container like JDialog, but that's just me.

I prefer to use, something like, a JPanel that has a helper method that can display an dialog. This method would create the dialog and add the panel to it, for example