Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MetalBeetle/630981 to your computer and use it in GitHub Desktop.
Save MetalBeetle/630981 to your computer and use it in GitHub Desktop.
Unreliable Swing modal dialog show/hide, about 1 in 4 times the window stays visible
// This is supposed to show a modal dialog and then hide it again. In practice,
// this works about 75% of the time, and the other 25% of the time, the dialog
// stays visible.
// This always prints
// setVisible(true) about to happen
// setVisible(false) about to happen
// setVisible(false) has just happened
// even when the dialog stays visible.
package modalproblemdemo;
import java.awt.Frame;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
public class Main {
public static void main(String[] args) {
final Dialogs d = new Dialogs();
new Thread() {
@Override
public void run() {
d.show();
d.hide();
}
}.start();
}
static class Dialogs {
final JDialog dialog;
public Dialogs() {
dialog = new JDialog((Frame) null, "Hello World", /*modal*/ true);
dialog.setSize(400, 200);
}
public void show() {
SwingUtilities.invokeLater(new Runnable() { public void run() {
dialog.setLocationRelativeTo(null);
System.out.println("setVisible(true) about to happen");
dialog.setVisible(true);
}});
}
public void hide() {
SwingUtilities.invokeLater(new Runnable() { public void run() {
System.out.println("setVisible(false) about to happen");
dialog.setVisible(false);
System.out.println("setVisible(false) has just happened");
}});
}
}
}
@tonyrushbrook
Copy link

I believe the rapid show and hide results in a modal dialog which can invoke its own demise. As the dialog becomes visible the EDT checks for pending 'invokeLater' events and may see its own hide event. Not surprised swing gets confused. Using 'invokeAndWait' on 'show' should resolve.

@hakanai
Copy link

hakanai commented Jan 18, 2019

Hmm, I was seeing similar behaviour in an application I'm maintaining, and this appears to be exactly the same symptom based on the description, but when I run this actual test program, the issue never happens for me, so I'm guessing there is some subtle timing involved as well. The actual application I reproduced it in is using invokeLater for both the show and the hide also, so there's strong evidence that it's the same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment