Frame "congelando"

7 respostas
J

Boa dia a todos!
Tenho um frame que é chamado antes de exibir um relatório .doc. Este frame exibe uma mensagem para o usuário aguardar e um botão desabilitado a princípio.
Então, este frame é exibido e em seguida ele gera o .pdf, que demora uns segundos para ficar pronto.
O problema é: dou um setVisible(true) no frame, ele aparece mas os componentes dentro dele(label, button) não aparecem. É tão rápido que o .pdf já começa a ser gerado, e o frame fica “congelado”. Só quando termina a geração do pdf que os campos do frame “descongelam” e aparecem com a mensagem “Relatório gerado com sucesso”.
Tem como eu exibir este frame todo e depois começar a gerar o .pdf?

Obrigado.

João

7 Respostas

M

O correto no caso é usar uma Thread separada para realizar a tarefa demorada. Isso evita que a Thread que controla a GUI trave, deixando a tela congelada como ocorreu. Procure por Threads, como implementar a interface Runnable e pode dar uma olhada também em SwingWorker.

Lavieri

exatamente isso que o marco falou…

se vc usa NetBeans, existe uma opção la ao criar Actions de fazer Rodar em backgroud… usando uma classe chamada Task, é bem facinho de usar

J

Implementei Threads como falaram, ficou assim:
No programa principal:

exportarDOC exportDOC = new exportarDOC(caminho);
			Thread thA = new Thread(exportDOC);
			thA.start();

E dentro do principal, tem a seguinte classe:

public class exportarDOC implements Runnable{
		private String caminho = "";
		public exportarDOC(String _caminho){
			this.caminho = _caminho;
		}
		public void run() {
			DOCRTF.geraDOC(this.caminho, rtf);
		}
		
	}

Como eu faço para que somente quando essa thread "thA" terminar, eu faça outra coisa?

KWill

JoAuM:
Implementei Threads como falaram, ficou assim:
No programa principal:

Como eu faço para que somente quando essa thread “thA” terminar, eu faça outra coisa?

Se tudo o que tu precisa fazer é esperar essa thread “thA” terminar, basta usar o método “join()”, que vai bloquear até a thread finalizar.

Inté.

J

No meu caso eu tenho um frame para mostrar ao usuário para aguardar, quando termino de executar a thread da qual falei, o label do frame muda para “Relatório gerado com sucesso!”.

Ficaria assim??

thA.start();
thA.join();
formAguardando.getLabel1().setText("Relatório gerado com sucesso!");
formAguardando.getOkButton().setEnabled(true);

Desse jeito não deu certo! O programa mudou o nome do label e habilitou o botão antes de terminar de gerar o relatório! :\

fabiofalci

O mais fácil é seguir o link que o marcobiscaro2112 colocou.
Exatament aqui
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/simple.html

Ou seja, no método doInBackground tu faz o processo do PDF e no método done
atualize a tela!

J

Resolvi criando um Timer que de 1 em 1 segundo verifica se o arquivo está escrito no H.D.
Estando escrito, ele faz outra tarefa!

public class ExportarDOC implements Runnable {
		private String caminho = "";
		private File file = null;
		private final int TEMPO = 1000;
		private Timer timer = null;
		
		public ExportarDOC(String _caminho) {
			this.caminho = _caminho;
			file = new File(this.caminho);
		}
		
		public void run() {
			DOCRTF.geraDOC(this.caminho, rtf);
			if (timer == null) {
				timer = new Timer();
				TimerTask tarefa = new TimerTask() {
					public void run() {
						try {
							if (file.exists()) {
								formAguardando.getLabel1().setText(
										"Relatório gerado com sucesso!");
								formAguardando.getOkButton().setEnabled(true);
								timer.cancel();
							} else {

							}
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				};
				timer.scheduleAtFixedRate(tarefa, TEMPO, TEMPO);
			}

		}
	}

Obrigado a todos!!

Criado 19 de fevereiro de 2009
Ultima resposta 27 de fev. de 2009
Respostas 7
Participantes 5