wait for jdialog to close

14,708

Solution 1

Again, the key is is the dialog modal or not?

If it's modal, then there's no need for a WindowListener as you will know that the dialog has been dealt with since code will resume immediately below your call to setVisible(true) on the dialog. i.e., this should work:

projectDialog = new FilePathDialog();   
projectDialog.setVisible(true);
doWork(); // will not be called until the dialog is no longer visible

If on the other hand it's mode-less, then a WindowListener should work, and you've likely got another problem in code not shown here, and you'll want to post an sscce for us to analyze, run, and modify.

Edit for gpeche
Please check out this SSCCE that shows that the 3 types of default closing parameters will trigger the window listener:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DialogClosing {
   private static void createAndShowGui() {
      JFrame frame = new JFrame("DialogClosing");

      JPanel mainPanel = new JPanel();
      mainPanel.add(new JButton(new MyAction(frame, JDialog.DISPOSE_ON_CLOSE, "DISPOSE_ON_CLOSE")));
      mainPanel.add(new JButton(new MyAction(frame, JDialog.HIDE_ON_CLOSE, "HIDE_ON_CLOSE")));
      mainPanel.add(new JButton(new MyAction(frame, JDialog.DO_NOTHING_ON_CLOSE, "DO_NOTHING_ON_CLOSE")));

      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MyAction extends AbstractAction {
   private JDialog dialog;
   private String title;

   public MyAction(JFrame frame, int defaultCloseOp, final String title) {
      super(title);
      dialog = new JDialog(frame, title, false);
      dialog.setDefaultCloseOperation(defaultCloseOp);
      dialog.setPreferredSize(new Dimension(300, 200));
      dialog.pack();
      dialog.addWindowListener(new WindowAdapter() {
         @Override
         public void windowClosed(WindowEvent e) {
            System.out.println(title + " window closed");
         }
         @Override
         public void windowClosing(WindowEvent e) {
            System.out.println(title + " window closing");
         }
      });

      this.title = title;
   }

   @Override
   public void actionPerformed(ActionEvent arg0) {
      dialog.setVisible(true);
   }
}

Solution 2

Javadoc for WindowListener.windowClosed():

Invoked when a window has been closed as the result of calling dispose on the window.

And for JDialog.setDefaultCloseOperation():

Sets the operation which will happen by default when the user initiates a "close" on this dialog. The possible choices are:

  • DO_NOTHING_ON_CLOSE - do not do anything - require the program to handle the operation in the windowClosing method of a registered WindowListener object.
  • HIDE_ON_CLOSE - automatically hide the dialog after invoking any registered WindowListener objects
  • DISPOSE_ON_CLOSE - automatically hide and dispose the dialog after invoking any registered WindowListener objects

The value is set to HIDE_ON_CLOSE by default.

That suggests that you should call projectDialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); after instantiating FilePathDialog.

Solution 3

answer to your question

add WindowListener to your JDialog (JDialog.DO_NOTHING_ON_CLOSE) , on windowClosing event to try to run your code, if ends with success then call dispose(), or setVisible(false)

I don't agreed with your idea, another workaround

create only one JDialog (JDialog.DO_NOTHING_ON_CLOSE) with WindowListener, and re-use that for another Action, final action will be always setVisible(false), if your code ends with success, then remove the child(s) from JDialog, your JDialog is prepared for another job

Share:
14,708
Varun Singh
Author by

Varun Singh

Updated on June 14, 2022

Comments

  • Varun Singh
    Varun Singh almost 2 years

    I have a class FilePathDialog which extends JDialog and that class is being called from some class X. Here is a method in class X

        projectDialog = new FilePathDialog();   
        projectDialog.setVisible(true);
    
        projectDialog.addWindowListener(new WindowAdapter() {            
            public void windowClosing(WindowEvent e) {
                System.out.println("Window closing");
                try {
                    doWork();
                } catch (Throwable t) {
                    t.printStackTrace();
                }                
            }
    
            public void windowClosed(WindowEvent e) {
                System.out.println("Window closed");
                try {
                    doWork();
                } catch (Throwable t) {
                    t.printStackTrace();
                }                
            }
        });     
    

    doWork never gets called when the JDialog window closes. All I'm trying to do is wait for the JDialog to close before it proceeds in the method. I also tried using SwingWorker and Runnable but that did not help.

  • Hovercraft Full Of Eels
    Hovercraft Full Of Eels over 12 years
    All default closing types listed above will trigger either windowClosing or windowClosed methods or both in the WindowListener. Please see my answer for an SSCCE that demonstrates that this is so.
  • gpeche
    gpeche over 12 years
    @Hovercraft Full Of Eels oh yes, I did not see the call to doWork() inside windowClosing()