JButton + Thread

Então neste caso eu voltaria a usar o método sleep() da classe Thread, já que não usa mais a Timertask…

Isso aí roda o que tem no Runnable, uma única vez, daí a thread morre…

E sim, se vc quiser dar uma pausinha, é só usar o Thread.sleep. :slight_smile:

class ProcessTask implements Runnable { @Override public void run() { //Aqui chamamos o metodo através da EventQueue da AWT. //Conforme dito, isso garante Thread safety para o Swing. tc.IniciaProcesso(); EventQueue.invokeLater(new Runnable() { public void run() { //Atualize o swing com os resultados aqui. } }); } }Tá dando erro na linha da declaração do método run da ProcessTask (quote abaixo), na linha 3, se eu comento o ‘@Override’ aí ele para de dar erro, mas não faz sentido, o método a ser sobrescrito não é justamente o run()?

Segue abaixo a sua sugestão, Vini:[code] private void initComponents() throws InterruptedException
{
setTitle(“WebService Consulta”);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	jButton1 = new javax.swing.JButton();
	jButton1.setText("Start");	
	jButton1.addActionListener(new ActionListener(){		    
			public void actionPerformed(ActionEvent e){
				new Thread(new ProcessTask()).start();										
			}
		}
	);	[/code]Como faço pra dar o sleep na Thread, quando ela é declarada desta maneira com 'new'? Tentei da seguinte maneira, mas nao funcionou...  :/ [code]	private void initComponents() throws InterruptedException
{	
	setTitle("WebService Consulta");		
	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	jButton1 = new javax.swing.JButton();
	jButton1.setText("Start");	
	jButton1.addActionListener(new ActionListener(){		    
			public void actionPerformed(ActionEvent e){
				Thread t = new Thread(new ProcessTask()).start();										
                                     t.sleep(3600000);
			}
		}
	);	[/code]A Thread em questão vai saber que só é para ela dormir durante o tempo especificado depois que a tarefa no método chamado em Runnable for concluída? Ou vai dormir logo depois de realizar a chamada?

Declarar a Thread desta maneira está dando o seguinte erro:[quote]Type mismatch: cannot convert from void to Thread…[/quote]
Creio q assim não seja a melhor maneira…rs…mais uma vez obrigado.

O sleep faz a thread atual dormir.

Quem é a thread atual?

No método actionPerformed é a thread do Swing.
E no método run() é a nova thread, que você acabou de criar com o new.

Para fazer sua segunda thread dormir (e não a do botão), você deve mover o sleep para dentro do run, ou de qualquer método chamado pelo run.

Blz kra, it worked… 8) [code]class ProcessTask implements Runnable {
//@Override
public void run() {
//Aqui chamamos o metodo através da EventQueue da AWT.
//Conforme dito, isso garante Thread safety para o Swing.
tc.IniciaProcesso();
/*EventQueue.invokeLater(new Runnable() {
public void run() {
//Atualize o swing com os resultados aqui.
}
}); */
}
}

private void initComponents() throws InterruptedException
{	
	setTitle("WebService Consulta Indivíduos");		
	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	jButton1 = new javax.swing.JButton();
	jButton1.setText("Start");	
	jButton1.addActionListener(new ActionListener(){		    
			public void actionPerformed(ActionEvent e){
				new Thread(new ProcessTask()).start();
			}
		}
	);	 

…[/code]Reparou q eu comentei a EventQueue.invokeLater? E ainda assim funcionou…
O que exatamente eu teria necessidade de ‘invocar tardiamente’ ali?E o sleep eu coloquei dentro do método da outra classe:[code]public void IniciaProcesso()
{
try
{
ExportaConsultax ecx = new ExportaConsultax();
SimpleDateFormat sdf = new SimpleDateFormat(“dd/MM/yyyy - hh:mm:ss”);
SimpleDateFormat sdfLog = new SimpleDateFormat(“dd_MM_yyyy-hh.mm.ss”);

		Thread t = new Thread();
		t.start();			
			
			ecx.VerificaIndividuos(CICLO, CONTADOR);
			
			Date d3 = new Date();				
			fc.createFile("C:\\", "ClienteInterfaceIndividuo_"+ sdfLog.format(d3) +".log", log.getLog());
			log.setLog(null);
			
			CICLO++;
			CONTADOR = 1;	
		
		t.sleep(INTERVALO); //milisegundos			
		IniciaProcesso();
	}
	catch(Exception e)
	{			
		e.printStackTrace();
	}
}	[/code]

Voltei um pouco á lógica inicial…o problema agora é q a JTextArea não está descendo com o scroll conforme vai acrescentando texto, mas aí já é outra história!!!
Preciso também criar um método para pausar esta thread, vou olhar nakele seu outro tópico.
VALEU Vini!

Você precisa chamar o invokeLater sempre que for atualizar um componente do Swing que não seja thread-safe. Não é o caso do JTextArea, mas é o caso da maioria: do JButton, JLabel, JTextField, e vários outros.

Geralmente, você só coloca os sets desses componentes dentro do InvokeLater, raramente um processamento.

Para movimentar o cursor do JTextArea é uma xunxeira desgraçada, por conta de uns bugs do próprio JTextPane.

Há uns tempos atrás postei aqui o código de um PrintWriter que escreve num JTextArea ou JTextPane, e já faz esse lance do cursor. Talvez você possa usa-lo. Ele também é thread-safe. O bom é que daí vc pode escrever no JTextArea com todos os métodos que vc teria usando o System.out, inclusive o printf. :slight_smile:

Aqui está o link:
http://www.guj.com.br/posts/list/83462.java#445238

Eu geralmente uso com JTextPane para poder definir cores e formatação. Desenvolvemos um componente aqui baseado no Antlr que faz colorização automática dos nossos logs. :smiley:

Brother não li as respostas pois estou com pressa, so li seu primeiro post…

Quanto a ficar travado, isso acontece pq o Swing tem prioridade diferentes em relação a seus componentes, por isso seu botão fica travado enquanto um Thread que foi chamada a partir da interface gráfica está rodando!
Faça o seguinte:

Thread threadProgress = new Thread(new Runnable() {
				public void run() {
					Controlador.diGrafu.getJProgressBar().setString("Executando...");
					Controlador.diGrafu.getJProgressBar().setIndeterminate(true);
				}
			});
			threadProgress.setDaemon(true);
			threadProgress.start();

			Thread threadDiGrafu = new Thread(new Runnable() {
				public void run() {
					ControlaExecucao.executaDiGrafu();
					Controlador.diGrafu.getJProgressBar().setVisible(false);
				}
			});
			threadDiGrafu .start();

Essas 2 Threads (threadProgress e threadDiGrafu ) uma controla um progressBar e a outra algumas execuções que eu faço.

Vc pode controlar seus botões na Thread threadProgress e as outras execuções que vc quer fazer na Thread threadDiGrafu

Se o seu problema é o que eu estou pensando com certeza vai dar certo…

flw

Foi mal people, andei enrolado com outras coisas (do mesmo sistema) e a interface acabou ficando por último…(prioridade é prioridade)
Mas não tem problema, o pesadelo voltou! rs…
Bom, como eu postei acima, consegui fazer a chamada do método que possui uma thread controladora de intervalos pelo JButton.
Eu clico no JButton e ele chama o método, esse método por sua vez inicia uma thread e esta thread controla intervalos de tempo neste método.

Agora criei um botão para pausar o funcionamento da thread, e adivinha: ele está ficando travado :roll:

[quote=Vini Godoy]Você precisa chamar o invokeLater sempre que for atualizar um componente do Swing que não seja thread-safe. Não é o caso do JTextArea, mas é o caso da maioria: do JButton, JLabel, JTextField, e vários outros.
Geralmente, você só coloca os sets desses componentes dentro do InvokeLater, raramente um processamento.
Para movimentar o cursor do JTextArea é uma xunxeira desgraçada, por conta de uns bugs do próprio JTextPane.
[/quote]

Creio que eu tenha que usar o InvokeLater neste JButton que invoca o Pause, concorda?
Eu fiz, mas nao adiantou…Vini, você disse atualizar…porém, creio que nao seria bem atualizar o JButton neste caso.

[code]Thread t = new Thread();

public void Pause() throws InterruptedException{
log.setPAUSE(true);
t.wait();
}

public void Resume() throws InterruptedException{
log.setPAUSE(false);
t.notify();
}

public void IniciaProcesso()
{
try
{
t.start();
ecx.VerificaIndividuos(CICLO, CONTADOR);
t.sleep(INTERVALO); //milisegundos
IniciaProcesso();
}
catch(Exception e)
{
e.printStackTrace();
}
}[/code]

Objetivo: se a pessoa clica no JButton ‘Start’ e deixa, o sistema executa a tarefa e depois de uma hora executa novamente, e assim fica eternamente.
Se alguém clicar no JButton ‘Pause’, ela tem que ficar parada até clicarem no Start novamente.
Acontece que quando invoco o método Pause pelo JButton ele trava o botão Pause, fica travado e a thread não pausa. :roll:

Resolvi colocar a Thread dentro da classe que usa o Swing, pois ficou mais simples e organizado.
(trecho):

private Thread t = new Thread();
public MainGui() {
        initComponents();
    }   
            
    class ProcessTask implements Runnable {   
        //@Override   
        public void run() {   		
            //Aqui chamamos o metodo através da EventQueue da AWT.   
            //Conforme dito, isso garante Thread safety para o Swing.
        	new TarefaContinuax();
            /*EventQueue.invokeLater(new Runnable() {   
                public void run() {   
                     //Atualize o swing com os resultados aqui.
                }   
            });   */
        }   
    }   
	
	public ActionListener ActionStart = new ActionListener() {		    
		public void actionPerformed(ActionEvent e) {
			new Thread(new ProcessTask()).start();				
		}
	};	
	
	ActionListener ActionPause = new ActionListener() {		    
		public void actionPerformed(ActionEvent e) {           	
			jTextArea1.append("\nProcesso interrompido...");           	
           	try{
           		t.wait();
           	}catch(InterruptedException ie){
           		jTextArea1.append("\nErro: "+ie.getMessage());
           	}
        }           							
	};
	
	ActionListener ActionResume = new ActionListener() {		    
		public void actionPerformed(ActionEvent e) {           	
			jTextArea1.append("\nProcesso interrompido...");
      		t.notify();           	
        }           							
	};	

A dúvida agora é como controlar a chamada de new TarefaContinua(); para acontecer de uma em uma hora, e os métodos para pausar e resumir a thread…
Agradeço qualquer ajuda pessoal.
[]´s