Tengo una aplicación con una clase abstracta que se extiende JDialog
. La clase como un abstract void onClose()
, y, en el constructor de la clase, se añade el siguiente código:`WindowListener` actuando, despido perpetuo
addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
onClose();
}
}
El evento se activa cuando se esperaba, pero luego sucede algo extraño. Cuando una extensión concreta de esta clase tiene código para crear un nuevo JDialog
en el método onClose()
, y JDialog
defaultCloseOperation
es JDialog.DISPOSE_ON_CLOSE
, el evento se dispara continuamente, hasta que fuerzo salir de la operación.
He aislado el código para la siguiente 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);
}
}
Al hacer clic en el botón "Me clic", la pieza en bruto JDialog
aparece y SSCCE.SSCCE().new WindowAdapter() {...}.windowClosed()
aparece en la ventana de la consola. Cuando cierro el cuadro de diálogo en blanco, vuelve a aparecer y el texto aparece de nuevo.
Otra cosa muy interesante es que cuando cambio la línea de inicialización de
JDialog dialog = new JDialog();
a
JDialog dialog = new JDialog() {
@Override
public synchronized void addWindowListener(WindowListener l) {
super.addWindowListener(l);
System.out
.println("SSCCE.onClose().new JDialog() {...}.addWindowListener()");
}
};
Me da la siguiente salida en la consola:
Al hacer clic en el "clic yo "botón:
SSCCE.SSCCE().new WindowAdapter() {...}.windowClosed()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
SSCCE.onClose().new JDialog() {...}.addWindowListener()
En el primer cierre de la ventana de diálogo:
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()
En el segundo cierre del diálogo:
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()
Cada vez que cierro la ventana de diálogo, addWindowListener(WindowListener l)
se llama un adicional tiempo, aunque no lo estoy llamando intencionalmente.
que realmente no quieren ningún WindowListener
s para ser registrados en el diálogo, pero creo que simplemente reemplazando el método addWindowListener(...)
y no llamar super.addWindowListener(...)
sería demasiado descuidado.
Estoy ejecutando Java 1.6.0_31 en Mac OS X 10.6.8, utilizando Eclipse Indigo (con WindowBuilder, si es importante).
¿Alguien tiene alguna idea?
Gracias!
Gracias! Eso tiene perfecto sentido. – wchargin