tutorial interfaz grafica example español ejemplos java swing

interfaz - java swing pdf



SwingUtilities.invokeLater() ¿por qué es necesario? (7)

Los objetos Swing no son seguros para subprocesos . SwingUtilities.invokeLater() permite que una tarea se ejecute en algún momento posterior, como su nombre lo sugiere; pero lo más importante, la tarea se ejecutará en el hilo de despacho del evento AWT. Cuando se usa invokeLater , la tarea se ejecuta de forma asíncrona; también hay invokeAndWait , que no volverá hasta que la tarea haya terminado de ejecutarse.

Parte de la información sobre la decisión de no hacer que Swing sea seguro para los hilos se puede encontrar aquí: Conjuntos de herramientas multiproceso: ¿un sueño fallido?

¿Por qué es necesario poner el código de actualización de GUI en SwingUtilities.invokeLater() ?

¿Por qué no puede ser atendido internamente por Swing? ¿Por qué la persona que llama debe preocuparse por cómo maneja las actualizaciones de UI?


Porque las actualizaciones de la GUI deben realizarse en el hilo de envío del evento. Si estás operando en un hilo diferente, al hacer la actualización en invokeLater lo invokeLater de tu hilo y lo invokeLater al hilo del evento.

Más explicación aquí: http://www.oracle.com/technetwork/java/painting-140037.html

Lo inteligente de las grandes actualizaciones (como la repoblación de una tabla JTable desde la base de datos) en Swing es obtener el modelo subyacente, hacer las actualizaciones del modelo en el hilo y luego invokeLater una notificación usando invokeLater . Eso mantiene tu GUI respondiendo a eventos y redibujando. Si la actualización va a ser muy extensa, incluso puede iniciar estas notificaciones con invokeLater a intervalos regulares mientras actualiza, como cada segundo o segundo.


Swing es de un solo hilo. Cada actualización de la interfaz de usuario debe realizarse a partir de la llamada EDT, el hilo de evento-dispater que es el hilo principal de la GUI que usa Swing (y creo que AWT). Si no haces esto, entonces cosas extrañas pueden suceder o sucederán (aunque me gusta Windows FOrms mejor aquí que arroja una excepción si lo haces mal).

Una vez dicho esto, no es necesario que envuelva todas las operaciones de UI en SwingUtilities.invokeLater() : si el código que está escribiendo ya ha sido ejecutado por EDT, no es necesario. Entonces el ActionListener para un clic de botón no necesita esto. Pero un oyente en un objeto externo, ejecutando en otro hilo, que actualiza un JLabel alguna parte, allí lo necesita.


Swing no fue escrito para ser un juego de herramientas GUI seguro para subprocesos, por lo que todas las actualizaciones de la GUI deberían realizarse a partir de un único hilo para evitar cualquier punto muerto. En Swing, este es el subproceso Distribuidor de eventos (EDT).

Vea Concurrent in Swing del tutorial de Java para más detalles. También hace referencia a esta entrada de blog sobre por qué es difícil escribir un conjunto de herramientas GUI multiproceso.


Toda la pintura de los componentes debe realizarse en un solo hilo, por lo tanto, se representan correctamente. De esa forma, el componente sabrá qué parte ya se ha pintado y qué parte no.

Si invoca un método relacionado con la "pintura" (pintura, actualización, paintComponent, show, setVisible, pack, etc.) fuera del EDT, intentará pintar en dos subprocesos diferentes, y eso puede ocasionar problemas.

Cuando necesite usar otro hilo para actualizar la UI, debe invocarlo con la función invokeLater, que a su vez lo colocará en el EDT, por lo que aún pintará en el mismo hilo.

No necesita usarlo, si está codificando en un método que ya se ejecuta en el EDT (por ejemplo, actionPerformed o paint o uno de esos) o si está ejecutando código no relacionado con la interfaz de usuario (por ejemplo, archivos de procesamiento) en el fondo, etc.)

Para comprender mejor todos estos conceptos, lea: La regla del hilo único


SwingUtilities.invokeLater()

Hace que doRun.run () se ejecute de forma asincrónica en el hilo de despacho del evento AWT. Esto sucederá después de que se hayan procesado todos los eventos pendientes de AWT. Este método se debe usar cuando un subproceso de aplicación necesita actualizar la GUI.
...


Repetir otros: Swing no es seguro para subprocesos, por lo que un subproceso debe hacer todas las actualizaciones para evitar problemas de concurrencia. invokeLater es un método de utilidad para ejecutar algo dentro del subproceso de procesamiento de eventos.

¿Por qué Swing no lo hace internamente? Esta es mi impresión ... Creo que sería excesivo: controlar todos los lugares donde se lleva a cabo una actualización. Inflaría el código de Swing, dificultando la revisión y mantenibilidad del código.

Por otro lado, no es tan difícil para una aplicación saber si no se está ejecutando dentro del hilo de la GUI y llamar a invokeLater. Será cuando la propia aplicación lanzó algún hilo antes.