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.
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).
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.
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!
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(); }
}
}