I have an application with an abstract class that extends JDialog
. The class as an abstract void onClose()
, and, in the class's constructor, the following code is added:
addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
onClose();
}
}
The event is fired when expected, but then a strange thing happens. When a concrete extension of this class has code to create a new JDialog
in the onClose()
method, and this JDialog
's defaultCloseOperation
is JDialog.DISPOSE_ON_CLOSE
, the event is fired continuously, until I force quit the operation.
I have isolated the code to the following SSCCE:
// package removed
// imports removed
public class SSCCE extends JDialog {
public static void main(String[] args) {
SSCCE s = new SSCCE();
s.pack();
s.setVisible(true);
}
public SSCCE() {
setLayout(new GridLayout(1, 0, 0, 0));
JButton btn = new JButton("click me");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
dispose();
}
});
addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
System.out
.println("SSCCE.SSCCE().new WindowAdapter() {...}.windowClosed()");
onClose();
}
});
add(btn);
}
public void onClose() {
JDialog dialog = new JDialog();
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
}
}
Upon clicking the "click me" button, the blank JDialog
appears and SSCCE.SSCCE().new WindowAdapter() {...}.windowClosed()
appears in the console window. When I close the blank dialog, it reappears again and the text appears again.
Another really interesting thing is that when I change the initialization line from
JDialog dialog = new JDialog();
to
JDialog dialog = new JDialog() {
@Override
public synchronized void addWindowListener(WindowListener l) {
super.addWindowListener(l);
System.out
.println("SSCCE.onClose().new JDialog() {...}.addWindowListener()");
}
};
I get the following output in the console:
When clicking the "click me" button:
SSCCE.SSCCE().new WindowAdapter() {...}.windowClosed()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
At the first closing of the dialog:
SSCCE.SSCCE().new WindowAdapter() {...}.windowClosed()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
At the second closing of the dialog:
SSCCE.SSCCE().new WindowAdapter() {...}.windowClosed()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
Each time I close the dialog, addWindowListener(WindowListener l)
is called an additional time, even though it I am not intentionally calling it.
I don't really want any WindowListener
s to be registered on the dialog, but I think that simply overriding the addWindowListener(...)
method and not calling super.addWindowListener(...)
would be too sloppy.
I'm running Java 1.6.0_31 on Mac OS X 10.6.8, using Eclipse Indigo (with WindowBuilder, if it matters).
Does anyone have any ideas?
Thanks!