wait for jdialog to close
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
Varun Singh
Updated on June 14, 2022Comments
-
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 over 12 yearsAll 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 over 12 years@Hovercraft Full Of Eels oh yes, I did not see the call to
doWork()
insidewindowClosing()