Bienvenido al maravilloso mundo del hilo de despacho de eventos bloqueados (y la violación del hilo inicial)
Básicamente, Swing es un entorno de enhebrado único, se espera que todas las actualizaciones y modificaciones a la interfaz de usuario se ejecuten dentro del contexto del hilo de despacho de eventos (también conocido como EDT).
El EDT es responsable de, entre otras cosas, procesar solicitudes de repintado. Si, por alguna razón, bloquea este hilo (por ejemplo, utilizando un bucle de ejecución largo o bloqueando IO), evitará que el EDT procese nuevas solicitudes de pintura, lo que hace que su programa haya colgado ... porque esencialmente él esencialmente. posee.
La razón por la que puede ver una diferencia entre correr Timer
Directamente y usarlo en su GUI es porque cuando se inicia la aplicación, se ejecutará dentro, lo que comúnmente se conoce como, el hilo "principal".
Cuando crea por primera vez un contenedor de swing de nivel superior, se inicia el EDT (que es un hilo separado), lo que significa que la interfaz de usuario aparecerá en su propio hilo, pero la aplicación continuará ejecutándose en el hilo "principal", lo que permite que su iterate
Método para ejecutarse independientemente del EDT.
Sin embargo, cuando intenta ejecutarlo desde su GUI, todo se ejecuta dentro del contexto del EDT, lo que hace que se bloquee.
Empiece por echar un vistazo a
Para solucionar el problema, según su código de ejemplo, sugeriría usar un SwingWorker
. Esto le permitirá ejecutar su "tarea de larga duración" en un hilo de fondo, pero proporciona una serie de métodos que le permiten volver a sincronizar sus actualizaciones al EDT. Esto es muy importante, ya que nunca debe intentar actualizar la interfaz de usuario o cambiar su estado desde cualquier hilo que el EDT.
Echa un vistazo a Hilos de trabajadores y swingworker para más detalles
Y si es necesario, algunos ejemplos ...