Disposed modal-dialog steals focus
The problem in which I need some help touches modal Dialog. The code that I pasted at the end builds a simple JFrame with one button. The button launches an Action that creates and runs my Test-class. The test performs two calls to SwintUtilities.invokeLater. The first one makes the modal-dialog visible, the second one hides and disposes the dialog. This way pressing the button will show the modal-dialog which will be hidden short moment later.
However if you run the program and presses the button many times the strange behaviour can be observed - the modal dialog appears and disappears but the JFrame does not get the focus back. It is not easily reproducible - I need to press the button about 30 times on average to see the bug. I noticed also that it is easier to reproduce the bug if CPU load is high. It is not necessary to press the button quickly, I reproduced it even when making one click per 10 seconds.
If you can point out any flaw in my code I would be really greatful.
I observer the described bug with sun-jdk-1.5.0.10, ibm-jdk-1.5.0.3 (both at Linux machine).
I could not reproduce it at blackdown-jdk-1.4.2.03 but I noticed that sometimes the button stays pressed for about 3 seconds as if something hogs the EventDispatchingThread.
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
publicclass Main{
publicstaticvoid main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
publicvoid run(){
final JFrame frame =new JFrame();
Action action =new MyAction(frame);
action.putValue(Action.NAME,"GO");
frame.getContentPane().add(new JButton(action));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setSize(200,100);
frame.setVisible(true);
}
});
}
publicstaticclass MyActionextends AbstractAction{
privatefinal JFrame frame;
public MyAction(JFrame frame){
this.frame = frame;
}
publicvoid actionPerformed(ActionEvent event){
new TestIt(frame).testDialog();
}
}
publicstaticclass TestIt{
private JDialog dialog;
private JFrame owner;
public TestIt(JFrame frame){
JFrame owner = frame;
}
privatevoid show(){
JPanel panel =new JPanel();
panel.add(new JLabel("This is a label"));
panel.add(new JLabel("message"));
this.dialog =new JDialog(this.owner,"title",true);
this.dialog.getContentPane().add(panel);
this.dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
this.dialog.setLocationRelativeTo(null);
this.dialog.pack();
this.dialog.setVisible(true);
this.dialog.dispose();
}
privatevoid hide(){
this.dialog.setVisible(false);
}
publicvoid testDialog(){
SwingUtilities.invokeLater(new Runnable(){
publicvoid run(){
show();
}
});
SwingUtilities.invokeLater(new Runnable(){
publicvoid run(){
hide();
}
});
}
}
}

