2009-07-24 15 views
7

Tengo una interfaz de usuario Java Swing que no está actualizando/volviendo a pintar como pensé que debería. La aplicación envía un mensaje XMPP y recibe una respuesta en un hilo diferente. Esa respuesta se procesa y la interfaz de usuario se actualiza para reflejar la información contenida en el mensaje.Swing UI no se actualiza después de usar invokeLater

Cuando se recibe la respuesta, actualizar un componente JPanel usando

javax.swing.SwingUtilities.invokeLater(new Runnable() { 
    public void run() { /* execute logic to update panel */ } 
}); 

Ha sido bastante tiempo desde que he desarrollado en Java, pero basado en mi investigación invokeLater línea pone en cola el ejecutable para la ejecución de la Hilo de GUI. Sin embargo, mi GUI no se actualiza hasta que hago otra cosa en la aplicación que causa un repintado, como cambiar el tamaño de la ventana. ¿Qué me estoy perdiendo? Después de la lógica para actualizar el panel, he intentado varias combinaciones de invalidate() y repintado(), pero el resultado sigue siendo el mismo: la GUI no se actualiza hasta que, por ejemplo, cambie el tamaño de la ventana.

EDITAR: Cuando digo actualizar el panel, específicamente hago un removeAll() y luego agrego un puñado de JLabels.

Respuesta

14

Después de añadir/quitar componentes de un panel que debe utilizar:

días
panel.revalidate(); // this works 99% of the time 
panel.repaint(); // sometimes needed. 

otras cosas como validar(), invalida(), etc, es un remanente de AWT que creo y revalidar() hace una mejor trabajo y fue agregado específicamente para Swing.

+0

Me gustaría actualizar esto, miles de veces. – JCasso

2

Si quiere decir con "actualizar el panel" que está agregando o quitando componentes, entonces será mejor que use invalidate() o revalide() para que el administrador de diseño capte los cambios.

Ver here para un problema similar.

2

Si está agregando o quitando componentes de un panel durante el manejo de eventos de la GUI (como los detectores de acciones), debería llamarse al doLayout() para solucionar su problema. He encontrado que cuando la GUI no se actualiza, las llamadas validate(), doLayout() y repaint() tienden a arreglar cosas.

+1

En realidad, se supone que no debes llamar a doLayout() directamente y debes llamar a revalidate() en su lugar. – Stroboskop

+0

@Stroboskop aunque se supone que no debes hacerlo, la documentación dice "Esto generalmente se llama cuando el componente está validado". y mis experiencias sugieren que al agregar y eliminar componentes de un contenedor durante el manejo de eventos, este método no es invocado por revalidate(). – Peter

+0

Derecha. Dado que todo esto sucede en EventQueue, es muy probable que la bandera de revalidación no se vea hasta que hayas terminado. Pero hubiera adivinado que una llamada a repintado() desencadenaría pintura y diseño más adelante ... – Stroboskop

Cuestiones relacionadas