[RESOLVIDO] Swing - Tela de Loading durante cálculos

Qual seria a melhor forma de implementar uma tela de Loading quando executando consultas no banco e cálculos demorados em Swing? Sendo uma tela com uma ProgressBar no modo Indeterminate mesmo. Não teria uma forma elegante e concisa, sem a necessidade de muito código repetitivo pra fazer isso?
A idéia seria uma tela que tivesse um comportamento como de um JDialog modal que impedisse o usuário de ficar pressionando várias vezes o botão de cálculo ou abrindo outras telas e processos, más que mostrasse a barra indo e vindo pra indicar que o programa está calculando.
Implementei uma forma mas foi meio que POG, então gostaria de saber como vocês fazem isso, ou fariam. Achei que isso fosse algo muito comum nos programas, porém pesquisei e não achei nada consistente quanto à isso.

Para executar processamentos pesados que “travam” a interface, um meio indicado no caso do Swing é suar SwingWorker, que faz o processamento de forma paralela (evitando travar a tela) e pode trocar informações de status com a thread do Swing (o que permite atualizar uma ProgressBar, por exemplo).

Referências:

Abraço.

Olá,
Então, eu utilizei SwingWorker e coloquei o setVisible() da ViewLoading (Tela com a msg carregando e um ProgressBar indeterminate mesmo só pra mostrar que ta carregando. E no done() dei o dispode() na ViewLoading. Porém não consigo deixá-la Modal porque ela travaria a EDT e ficaria só a tela de Loading aparecendo pra sempre sem chamar o done(). E se utilizar um setEnabled(false) na View que chamou a ViewLoading, eu não consigo colocar pelo menos um Cursor.WAITING_CURSOR na View que está com setEnabled(false). Não sei se esta forma de implementar a tela de Loading seria meio “gambiarra”. Você já implementou uma tela de Loading durante processos em Swing?

Isso é parte do requisito?
Se não é, é total e plenamente dispensável.
Se for, então você precisa identificar um meio de fazer.

Talvez seja o caso de usar algum pattern como o observable, não?

Sim, foi passado como requisito, já que tem aplicações que dependendo da quantidade de dados podem demorar vários segundos.

Desculpe, nunca trabalhei com ou estudei o padrão Observer, vou pesquisar sobre o assunto! Mas não entendi como ele solucionaria o problema de deixar o JDialog da ViewLoading como modal, ou seria outra abordagem pra atingir esse resultado?

A abordagem é a mesma, a questão é que, no padrão observer, você teria a tela que está em enable false como o observable e a modal como observer, ou seja, a modal seria avisada que a outra terminou o processamento e poderia ser fechada.

Por que precisa ser uma tela separada de loading? E por que ela precisa ser modal?

Eu colocaria um ProgressBar na própria tela de cálculo, e usaria o SwingWorker pra atualizá-la. Se seu medo é que o usuário clique no botão de calcular novamente (iniciando um novo cálculo), basta adicionar uma verificação no botão, e não fazer nada caso um processamento já esteja ativo. Algo como:

botao.addActionListener(new ActionListener{
  void actionPerformed(){
  if (!processamentoRodando){
   iniciarProcessamentoNoSwingWorker();
   processamentoRodando = true;
  }
  }
});

processamentoRodando é uma variável boolean do próprio Form. Quando o processamento finaliza (done() do SwingWorker), mude para false.

Abraço.

1 curtida

Desculpem, ela está funcionando sim, mas mesmo colocando o setVisible(true) da ViewLoading no SwingWorker ainda travava e não executava o código doInBackgroung(), mas mesmo chamando dentro do SwingWorker coloquei a chamada do setVisible(true) no EventQueue.invokeLater (Criei uma classe utilitária com método static que tem instanciada e deixa visível a ViewLoading pra ser invocada à qualquer hora no código) e aparentemente está funcionando ok. Obrigado pela atenção!