Benvenuto nel meraviglioso mondo del thread di spedizione di eventi bloccato (e violazione del thread iniziale)
Fondamentalmente, Swing è un singolo ambiente thread, tutti gli aggiornamenti e le modifiche all'interfaccia utente dovrebbero essere eseguiti nel contesto del thread di eventi (aka EDT).
L'EDT è responsabile, tra le altre cose, di elaborare richieste di riduzione. Se, per qualche motivo, blocchi questo thread (ad esempio, usando un ciclo di lunga durata o bloccando IO), impedirà all'EDT di elaborare nuove richieste di verniciatura, facendo sembrare che il tuo programma fosse appeso ... perché essenzialmente lo ha.
Il motivo per cui potresti vedere una differenza tra la corsa Timer
Direttamente e usarlo nella tua GUI è perché quando l'applicazione sarà avviata, sarà in esecuzione all'interno, ciò che è comunemente noto come il thread "principale".
Quando si crea per la prima volta un contenitore di altalena di alto livello, l'EDT viene avviato (che è un thread separato), il che significa che l'interfaccia utente apparirà nel proprio thread, ma l'applicazione continuerà a funzionare nel thread "principale", permettendo il tuo iterate
Metodo da eseguire indipendentemente dall'EDT.
Tuttavia, quando provi a eseguirlo dalla tua GUI, è tutto in esecuzione nel contesto dell'EDT, causando il blocco.
Inizia dando un'occhiata
Per risolvere il problema, in base al tuo codice di esempio, suggerirei di usare un SwingWorker
. Ciò ti consentirà di eseguire la tua "attività di lunga durata" in un thread di fondo, ma fornisce una serie di metodi che ti consentono di risincronizzare gli aggiornamenti all'EDT. Questo è molto importante, poiché non dovresti mai tentare di aggiornare l'interfaccia utente o modificare il suo stato da qualsiasi thread oltre all'EDT.
Date un'occhiata al Discussioni del lavoratore e swelayer per ulteriori dettagli
E se necessario, alcuni esempi ...