Bem -vindo ao maravilhoso mundo do tópico de despacho de eventos bloqueados (e violação do tópico inicial)
Basicamente, espera -se que o Swing seja um ambiente de rosca, todas as atualizações e modificações na interface do usuário devem ser executadas no contexto do encadeamento de despacho de eventos (também conhecido como EDT).
O EDT é responsável, entre outras coisas, processando solicitações de repetição. Se, por algum motivo, você bloqueia esse tópico (por exemplo, usando um loop de longa duração ou bloqueando o IO), isso impedirá que o EDT processe novas solicitações de tinta, fazendo com que pareça como se o seu programa tenha pendurado ... porque essencialmente ele tem.
A razão pela qual você pode ver a diferença entre correr Timer
Diretamente e usá -lo na sua GUI é porque, quando o aplicativo é iniciado, ele estará em execução, o que é comumente conhecido como o thread "principal".
Quando você cria um recipiente de balanço de nível superior, o EDT é iniciado (que é um fio separado), o que significa que a interface do usuário aparecerá em seu próprio tópico, mas o aplicativo continuará sendo executado no tópico "principal", permitindo que o seu seu iterate
Método para executar independentemente do EDT.
No entanto, quando você tenta executá -lo de dentro da sua GUI, tudo está em execução no contexto do EDT, fazendo com que ele seja bloqueado.
Comece dando uma olhada em
Para corrigir o problema, com base no seu código de exemplo, sugiro usar um SwingWorker
. Isso permitirá que você execute sua "tarefa de longa execução" em um encadeamento de segundo plano, mas fornece vários métodos que permitem ressincronizar suas atualizações de volta ao EDT. Isso é muito importante, pois você nunca deve tentar atualizar a interface do usuário ou alterar seu estado de qualquer tópico que não seja o EDT.
Dar uma olhada em Tópicos de trabalhador e swingworker para mais detalhes
E se necessário, alguns exemplos ...