2009-08-27 13 views

Respuesta

47

cerrar una ventana (con dispose()) y esconderlo (con setVisible(false)) son diferentes operaciones, y producir diferentes eventos - y cerrarla desde el sistema operativo es otro diferente operación que produce un evento diferente.

Los tres producirá windowDeactivated para informarle enfoque perdida de la ventana, pero dispose() entonces producirá windowClosed, mientras que el cierre de la primera OS producir windowClosing. Si desea manejar ambos de la misma manera, se puede establecer la ventana para ser eliminados cuando se cierra:

window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 

En general, setVisible(false) implica que es posible que desee utilizar la ventana de nuevo, por lo que no hace publicar cualquier evento de ventana (aparte de windowDeactivated). Si desea detectar el ocultamiento de una ventana, necesita usar un ComponentListener;

window.addComponentListener(new ComponentAdapter() { 
    @Override 
    public void componentHidden(ComponentEvent e) { 
    System.out.println("componentHidden()"); 
    } 
}) 

en cuenta sin embargo que esta prácticamente sólo funcionará para explícitos setVisible() llamadas. Si necesita detectar el ocultamiento de manera más general, puede usar un HierarchyListener, pero probablemente sea más problemático de lo que vale.

window.addHierarchyListener(new HierarchyListener() { 
    @Override 
     public void hierarchyChanged(HierarchyEvent e) { 
     System.out.println("valid: " + window.isValid()); 
     System.out.println("showing: " + window.isShowing()); 
     } 
    }); 

Tenga en cuenta que cuando se deshaga de una ventana que se abre un par de HierarchyEvent s, en primer lugar para esconderse y después de nulidad, pero cuando se oculta con setVisible() que sigue siendo válida, por lo que no obtendrá el invalidación.

+3

Gracias David. Solo estaba escuchando la opción Cerrar ventana al usar dispose. No me di cuenta de que el único sistema operativo que lo cerraba producía el cierre de la ventana. –

+0

Tuve que descubrirlo por mi cuenta. :) –

+0

Ok, todavía no entiendo la pregunta. Pero el OP dice que quiere que los "oyentes de la bobinadora sigan siendo notificados. Mi sugerencia es NO utilizar el método de eliminación, pero enviar un evento de cierre de ventana a la ventana. Esto actuará como alguien hizo clic en el botón" X ". la ventana se eliminará y el oyente de la ventana será nofificado. Sus 2 líneas de código. Parece que entiende el problema mejor que yo, así que tal vez probará mi sugerencia para ver si tiene sentido. – camickr

0

sugerencia no probado:

¿Usted ha intentado getWindowListeners() y luego la iteración en torno al fuego windowClosed() para cada uno de los WindowListeners?

EDITAR: la sugerencia anterior es incorrecta. Manteniéndolo para la posteridad.

Me temo que llamar a dialog.dispose() funciona bien para mí en mi ejemplo simple.

1

Despachar una ventanaCerrar evento a la ventana. Consulte el ejemplo ExitAction de la entrada Closing an Application.

+3

¿Cómo aprenden las personas algo si no dan una razón para el voto hacia abajo? – camickr

+2

No fui yo quien lo votó negativamente, pero tal vez sea porque parece que no trataste de comprender el problema de Jeff, que acabas de encontrar vinculado a tu publicación de blog más probable relacionada. El hecho de que hayas publicado dos quejas acerca de que a Jeff no le gustaba tu respuesta sin ningún otro intento de averiguar por qué no funciona para él no hace que la respuesta parezca más atractiva. –

+0

Acepto que podría estar afuera en el jardín izquierdo, pero mi comentario acerca de que uno de nosotros no entiende el otro indica que lo he visto varias veces tratando de asegurarme de que entiendo la pregunta. Mis otros comentarios están diseñados para que Jeff eche otro vistazo a mis sugerencias. Sigo manteniendo que tengo una solución de 1 línea para su problema al crear imágenes de un panel no mostrado. – camickr

3

Parece que no tengo su problema. Cuando uso el código a continuación, se llama windowDeactivated(), ya sea para setVisible(false) o dispose() y windowClosed() para deshacerse de ellos().

ClosingDialog.java:

public class ClosingDialog extends JDialog { 
    public ClosingDialog(Frame owner, String title, boolean modal) { 
     super(owner, title, modal); 
     JPanel contentPanel = (JPanel) this.getContentPane(); 

     JButton setVisButton = new JButton("setVisible(false)"); 
     setVisButton.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       ClosingDialog.this.setVisible(false); 
      } 
     }); 

     JButton disposeButton = new JButton("dispose()"); 
     disposeButton.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       ClosingDialog.this.dispose(); 
      } 
     }); 

     contentPanel.setLayout(new FlowLayout()); 

     contentPanel.add(setVisButton); 
     contentPanel.add(disposeButton); 

     this.addWindowListener(new WindowListener() { 
      public void windowActivated(WindowEvent e) { 
       System.out.println("windowActivated"); 
      } 

      public void windowClosed(WindowEvent e) { 
       System.out.println("windowClosed"); 
      } 

      public void windowClosing(WindowEvent e) { 
       System.out.println("windowClosing"); 
      } 

      public void windowDeactivated(WindowEvent e) { 
       System.out.println("windowDeactivated"); 
      } 

      public void windowDeiconified(WindowEvent e) { 
       System.out.println("windowDeiconified"); 
      } 

      public void windowIconified(WindowEvent e) { 
       System.out.println("windowIconified"); 
      } 

      public void windowOpened(WindowEvent e) { 
       System.out.println("windowOpened"); 
      } 
     }); 

     this.setSize(300, 300); 
    } 
} 
+2

Toda la ventana desactivada significa que ha perdido el foco. No se sabe con seguridad si la ventana se está cerrando realmente. En general, los oyentes escucharán el evento de cierre de la ventana para que puedan hacer algún procesamiento especial de una vez. – camickr

+0

Sí, lo intenté con WindowClosing y no recibí ese evento. –

+0

Por eso le di mi solución hace 5 horas. – camickr

0

quería disparar un evento windowClosing a partir del código (como si el usuario hace clic en la X), porque tengo un botón adicional de cerca en el JDialog y quiero lo mismo WindowListener (que he implementado usando un WindowAdapter) para ser ejecutar cuando se hace clic en la X y cuando se hace clic en el botón. Ejecutando dispose() solo dispara windowClosed, no windowClosing, y quiero que aparezca un mensaje antes de la ventana está cerrada, para confirmación.Tampoco pude disparar windowClosing a través del método de JDialog processWindowEvent ya que está protegido.

Así es como lo tengo trabajando sin embargo:

WindowAdapter adapter = (WindowAdapter)jdialog.getWindowListeners()[0]; 
adapter.windowClosing(new WindowEvent((Window)jdialog, WindowEvent.WINDOW_CLOSING)); 

la esperanza de que ayude a alguien.

Cuestiones relacionadas