Created
October 17, 2010 16:21
-
-
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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"); | |
}}); | |
} | |
} | |
} |
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
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.