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();

}

});

}

}

}

[6365 byte] By [mikocha] at [2007-10-3 11:46:31]
# 1

> public static class TestIt {

>private JDialog dialog;

> private JFrame owner;

>public TestIt(JFrame frame) {

>JFrame owner = frame;

>}

This isn't related to the problem, but you do have a bug in your constructor for TestIt. Instead of

JFrame owner = frame;

you should have

this.owner = frame;

The way you have it, it is declaring a new local variable that shadows the member variable. Since you don't make any references to 'frame' anywhere in the TestIt class, this hasn't caused an exception yet. However, if you did try to reference 'frame' you would throw a NullPointerException. You can set your compiler warning levels to notify you of these little mistakes.

codebooka at 2007-7-15 14:19:12 > top of Java-index,Desktop,Core GUI APIs...
# 2

> this.dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

> this.dialog.setLocationRelativeTo(null);

> this.dialog.pack();

> this.dialog.setVisible(true);

> this.dialog.dispose();

Another little thing (that I don't think is related), did you know you can simply use WindowConstants.DISPOSE_ON_CLOSE

instead of DO_NOTHING_ON_CLOSE

followed by a call to dialog.dispose()

?

codebooka at 2007-7-15 14:19:12 > top of Java-index,Desktop,Core GUI APIs...
# 3
Yes, You are rigth, I must have made the mistake when I rearranged the code before pasting it here.But nevertheless the bug appears either I set parent of JDialog to frame or to null.
mikocha at 2007-7-15 14:19:12 > top of Java-index,Desktop,Core GUI APIs...
# 4
The problem described above is now accepted by the sun as bug.For details see: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6518198
mikocha at 2007-7-15 14:19:12 > top of Java-index,Desktop,Core GUI APIs...