Looping dentro do Actionperformed

Olá amigos.
Tenho um programinha ( código logo abaixo) que deveria exibir na caixa de texto T1 a contagem progressiva dos números de 1 até 10.
Para tanto, inseri no método Actionperformed, um contador temporizado.
Quando clico no botão B1, ele fica pressionado por exatos 10 segundos, e nesse período nada aparece no mostrador.
Após esse período, o botão B1 é “liberado” e é mostrado apenas o numero 10 em T1. Isso mostra que o contador temporizado funciona, mas o método Actionperformed não consegue atualizar os loops na caixa de texto T1. Como posso resolver o problema ?
Agradeço a atenção !

[code]import java.awt.;
import java.awt.event.
;
import javax.swing.*;
class Inter extends JFrame implements ActionListener{

JTextField T1;
JButton B1;

Inter(){
setSize(150, 150);
T1= new JTextField(10);
B1= new JButton(“b1”);
T1.addActionListener(this);
B1.addActionListener(this);
getContentPane().add(T1);
getContentPane().add(B1);
getContentPane().setLayout(new FlowLayout());
}

public void actionPerformed(ActionEvent e){
if(e.getSource()== B1){
Thread t = new Thread();
t.start();
int i ;
for( i= 1; i<= 10; i ++){
T1.setText(" " +i);
System.out.println(i);
try{
t.sleep(1000);
if(i==100) System.exit (0);}
catch (InterruptedException f ){}
}}}

public static void main(String[] s){
Inter frame = new Inter();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}}[/code]

Se necessariamente não for obrigatório mostrar os números sequencialmente a cada segundo, no lugar de você colocar a Thread com 1 segundo de demora, coloque um JOptionPane a cada mostragem de um número.
Teve um projeto que tive que fazer para faculdade e tenteir utilizar a Thread e deu o mesmo erro que você está tendo agora, e acabei por utilizar o JOptionPane, e ficou muito bom o projeto!

Você deve disparar seu código numa outra thread.

public void actionPerformed(ActionEvent e){ if(e.getSource()== B1){ Thread t = new Thread(new Runnable() { public void run() { try{ for(int i= 1; i<= 10; i ++){ T1.setText(" " +i); System.out.println(i); Thread.sleep(1000); if(i==100) System.exit (0); } } catch (InterruptedException f ){} }}); t.start(); } }

O que você fez em seu código foi criar uma thread vazia. No start(), ela era disparada e morta, já que não tinha nenhuma implementação para rodar em seu interior. Para dizer o que roda na thread, você fornece a classe thread um Runnable, contendo o código que iniciará a execução na thread separada. Foi isso que fiz ali em cima.

Também modifiquei o tratamento da InterruptedException. Geralmente, essa exceção é disparada quando você quiser parar a thread, através do método interrupt(), ou pela própria VM, na hora que o System.exit(0); é chamado. Nesse caso, a thread deveria sair do loop e finalizar graciosamente. Por isso, fiz com que o catch desvie o processamento para fora do for, o que encerrará a thread, assim que ela sair do método run.

Outra coisa, ao invés de fazer seu JFrame estender ActionListener, e depois ficar testando dentro do método actionPerformed que componente fez a invocação, crie um ActionListener diferente por componente. Isso deixa o código mais seguro, mais rápido e mais orientado a objetos.

[quote=WendersonLP]Se necessariamente não for obrigatório mostrar os números sequencialmente a cada segundo, no lugar de você colocar a Thread com 1 segundo de demora, coloque um JOptionPane a cada mostragem de um número.
Teve um projeto que tive que fazer para faculdade e tenteir utilizar a Thread e deu o mesmo erro que você está tendo agora, e acabei por utilizar o JOptionPane, e ficou muito bom o projeto![/quote]

Valeu pela dica amigão! :wink:

[quote=ViniGodoy]Você deve disparar seu código numa outra thread.

public void actionPerformed(ActionEvent e){ if(e.getSource()== B1){ Thread t = new Thread(new Runnable() { public void run() { try{ for(int i= 1; i<= 10; i ++){ T1.setText(" " +i); System.out.println(i); Thread.sleep(1000); if(i==100) System.exit (0); } } catch (InterruptedException f ){} }}); t.start(); } }

O que você fez em seu código foi criar uma thread vazia. No start(), ela era disparada e morta, já que não tinha nenhuma implementação para rodar em seu interior. Para dizer o que roda na thread, você fornece a classe thread um Runnable, contendo o código que iniciará a execução na thread separada. Foi isso que fiz ali em cima.

Também modifiquei o tratamento da InterruptedException. Geralmente, essa exceção é disparada quando você quiser parar a thread, através do método interrupt(), ou pela própria VM, na hora que o System.exit(0); é chamado. Nesse caso, a thread deveria sair do loop e finalizar graciosamente. Por isso, fiz com que o catch desvie o processamento para fora do for, o que encerrará a thread, assim que ela sair do método run.

Outra coisa, ao invés de fazer seu JFrame estender ActionListener, e depois ficar testando dentro do método actionPerformed que componente fez a invocação, crie um ActionListener diferente por componente. Isso deixa o código mais seguro, mais rápido e mais orientado a objetos.[/quote]

Valeu Vini ! Era isso que procurava, caso encerrado !