Atualizando JTextArea Dinamicamente

Pessoal, seguinte, procurei bastante a resolução para o meu problema e não achei resposta.
Eu tenho um textArea em branco, quando preencho alguns dados e clico em um botao chamado “consultar”, essa consulta retorna, por exemplo, 2 mil resultados do banco.

Se eu peço pra dar 1 system.ou.print, ele executa a query, imprime, executa, imprime… ou seja, eu vejo o programa “rodando”…
agora no mesmo lugar onde eu chamo pra imprimir, eu chamo o textArea.append (query), só que não aparece 1 a 1, o textArea só preenche quando todas as querys são executadas, e já aparecem todos os resultados de uma vez… então eu não vejo o programa “rodando”…

Não sei se fui claro… tentei usar revalidate, repaint, mas eu acho q não tem nada haver, neh…
o pior é o seguinte. pensei que o código não passava pelo “append” ou sei lah… ai eu dei 1 Thread.sleep(5000) logo em seguida… e ele para 5 segundos certinho alih… ou seja… ele passa sim por essa parte do código.

Obrigado pela atenção
Alex

Olá.

Os componentes swing não são thread safe, sendo assim a atulização de um componente depende que este processo seja feito em uma thread separada para que você veja o componente sendo modificado.

Pesquise por “thread safe swing” (sem aspas) na busca do fórum que vc vai ter a resposta que precisa. Dê uma pesquisada pelas classes SwingUtilities e SwingWorker tbm ( a qual faz parte do Java SE 6 em diante).

Valew brother!! entendi! naum sabia o que procurar…
Vow dar uma olhada e posto aqui mais tarde,

Obrigado
Alex

Então, olhei os tópicos lá, tentei do jeito de vcs… dei uma olhada na SwingUtilities… e nada
Agora vou ver na SwingWorker… mas tem que dar pela SwingUtilities… alguém porderia me ajudar? além dos jeitos dos tópicos, tentei:

assim

    public void atualizaJTextArea2 ( final String sql , final JTextArea jTextArea2 ) throws InterruptedException {
        final Runnable doAppend = new Runnable () {  
            public void run() {   
                jTextArea2.append(sql);
                jTextArea2.repaint();
                jTextArea2.revalidate();
            }     
        };
        new Thread( new Runnable() {  
            public void run() {  
                try                   { SwingUtilities.invokeAndWait( doAppend ); }
                catch (Exception ex)  { ex.printStackTrace(); }
            };  
        }).start();  
    }

e assim

    public void atualizaJTextArea2 ( final String sql , final JTextArea jTextArea2 ) throws InterruptedException {
        Runnable doAppend = new Runnable () {  
            public void run() {   
                jTextArea2.append(sql);
                jTextArea2.repaint();
                jTextArea2.revalidate();
            }     
        };
        SwingUtilities.invokeLater ( doAppend );

    }

Detalhe: eu chamo esse metodo de uma classe DAO, por exemplo… será que é esse o problema? pq na API tah desse jeito…
Alguém poderia me dar uma luz ai?
enquanto isso, voh vendo na SwingWorker q nem o brother falow.

Valew
Alex

Olha o exemplo.

[code]
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingWorker;

/**
*

  • @author David Buzatto
    */
    public class MeuFrame extends JFrame implements ActionListener {

    private JTextField field;
    private JButton botao;

    public MeuFrame() {

     super( "Teste Thread-Safe" );
     setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
     setSize( 300, 80 );
     setLayout( new FlowLayout() );
    
     field = new JTextField( 10 );
     field.setHorizontalAlignment( JTextField.RIGHT );
     field.setEditable( false );
    
     botao = new JButton( "Contar até 10000" );
     botao.addActionListener( this );
    
     add( field );
     add( botao );
    

    }

    public static void main( String[] args ) {
    new MeuFrame().setVisible( true );
    }

    public void actionPerformed( ActionEvent e ) {
    new Atualizador().execute();
    }

    private class Atualizador extends SwingWorker {

     @Override
     protected Object doInBackground() throws Exception {
    
         botao.setEnabled( false );
    
         for ( int i = 1; i <= 10000; i++ )
             field.setText( String.valueOf( i ) );
    
         botao.setEnabled( true );
    
         return null;
    
     }
    

    }

}[/code]

Não precisa usar os métodos repaint e revalidate do componente como vc fez no seu código.

Brother, brigadão mesmo, ajudoh pra karamba!! testei teu exemplo aqui, massa!
Do validate e repaint eu imaginei q num precisasse, mas antes q alguém desse a sugestão de usar eles, jah joguei eles lah pra num ter duvida…
Sóh q o foda é q eu fiz uma nhaca aki no netbeans e esse exemplo eu voh ter q adaptar… pq eu teoricamente teria q executar esse execute() varias vezes e tipo sincronizado e sendo chamado pela própri classe filha… acho q nem pode fazer isso, tentei fazer no teu exemplo lah, acho q descincronizoh… tipo chamando this.execute(); talvez eu esteja viajando!
mas tava precisando mesmo era de um começo, com esse teu exemplo jah voh conseguir sair do lugar!
toh a 2 dias tentando… o fogo eh q o programa tah rodando de boa, mas queria soh arrumar isso pra num parecer q ele travoh.

Bom, amanha voh tentar lah no trampo… qq coisa grito por socorro por aqui denovo!

Valew mesmo!
Alex

Se te clareou o caminho, que bom!

Até mais!

Galera, toh pastanto nessa joça aqui… tipo, o exemplo que o david me passou, vc executa o execute() só uma vez… ou seja, vc já tem tudo carregado (tipo uma lista já pronta) e só joga 1 a 1 no field… porém no meu caso, eu faço uma consulta no banco, e jogo na tela, faço consulta, jogo na tela… tentei algumas coisas… assim, pra entender melhor o que eu preciso, eu adaptei o exemplo do david… porém num funfoh… as consultas vão sair fora de ordem, mas isso é o de menos. O código abaixo não funciona como deveria…
Pelo que eu andei lendo, depois q instancia uma SwingWorker e dá 1 execute, acaboh… ela é feita pra ser executada uma única vez… então pra cada “consulta” eu crio uma thread e uma SwingWorker…
C vcs puderem me dar uma luz de como eu posso fazer isso…

Detalhe: Ele roda o laço inteiro para só depois começar a atualizar o field…

Valew
Alex

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingWorker;

public class MeuFrame extends JFrame implements ActionListener {

    private CubbyHole c;
    private JTextField field;
    private JButton botao;

    public MeuFrame() {

        super( "Teste Thread-Safe" );
        
        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        setSize( 300, 80 );
        setLayout( new FlowLayout() );

        field = new JTextField( 10 );
        field.setHorizontalAlignment( JTextField.RIGHT );
        field.setEditable( false );

        botao = new JButton( "Contar até 10000" );
        botao.addActionListener( this );

        add( field );
        add( botao );
        
        c = new CubbyHole (field);

    }

    public static void main( String[] args ) {
        MeuFrame m = new MeuFrame();
        m.setLocationRelativeTo(null);
        m.setVisible( true );
    }

    public void actionPerformed( ActionEvent e ) {
        for ( int i = 1; i <= 10000; i++ ) {
            new Tarefa(i,c).start();
        }
    }  
}

class Atualizador extends SwingWorker {
    
    int i;
    JTextField field;

    public Atualizador (int i, JTextField field) {
        this.i = i;
        this.field = field;
    }

    @Override
    protected Object doInBackground() {
        try                 { field.setText(String.valueOf(i)); }
        catch (Exception e) { e.printStackTrace(); }
        
        return null;
    }
    
    @Override
    protected void done() {
        // ?
    }
}

class CubbyHole {
    
    private JTextField field;
    public boolean gravando = false; 
    
    public CubbyHole (JTextField field) {
        this.field = field;
    }
    
    public synchronized void imprime (int i) throws InterruptedException {
        while (gravando)
            wait();
        
        new Atualizador(i, field).execute();    
        
        System.out.println (i);
        Thread.sleep(1000);
        gravando = false;
        notifyAll();
    }
}

class Tarefa extends Thread {
    
    private CubbyHole c;
    private int i;
    
    public Tarefa (int i, CubbyHole c) {
        this.i = i;
        this.c = c;
    }
    
    public void run () {

        try                    { c.imprime(i);        }
        catch (Exception e)    { e.printStackTrace(); }
    }
}