Alterar text de JButton de outra classe

Olá,

Em um aplicativo desktop, tenho a classe inicial com o jButton de nome btnSincronizar. Após clicar nele, é chamada outra classe que implementa runnable de nome SincronizarDados. Preciso que assim que finalize o processo desta classe chamada, o botão volte a ficar ativo e o text volte ao que era: “Sincronizar”.

[code]public class Principal extends javax.swing.JFrame {
public Principal() {
setExtendedState(MAXIMIZED_BOTH);
initComponents();
}

private void initComponents() {

    jFrame1 = new javax.swing.JFrame();


btnSincronizar = new javax.swing.JButton();

public JButton getBtnSincronizar() {
return btnSincronizar;
}

public void setBtnSincronizar(JButton btnSincronizar) {
    this.btnSincronizar = btnSincronizar;
}


private void btnSincronizarActionPerformed(java.awt.event.ActionEvent evt) {
SincronizarDados sincronizarDados = new SincronizarDados();
Thread threadSincronizarDados = new Thread(sincronizarDados);
threadSincronizarDados.start();
this.btnSincronizar.setText(“Sincronizando”);
this.btnSincronizar.setEnabled(false);
}
[/code]

[code]public class SincronizarDados implements Runnable {


@Override
public void run() {
atualizaTabelaClientes();
}

public void atualizaTabelaClientes() {
try {

        ProgressMonitor pm = new ProgressMonitor(null, "Iniciando...", "Inicializando sincronização dos dados...", 0, 0);

        ARRAYOFSTRUCTCLI resultClientes = listaclientes(Acesso.getInstance().getCodigo(), "", "", "", "", "");


[/code]

Como fazer para voltar o JButton ao que era antes? Não funcionou quando fiz da forma abaixo, por se tratar de thread acredito apareceu rapidamente “Soncronizando” e antes da rotina chamada terminar já voltou para “Sincronizar” e a habilitação do botão:

        private void btnSincronizarActionPerformed(java.awt.event.ActionEvent evt) {                                            
        this.btnSincronizar.setText("Sincronizando");
        this.btnSincronizar.setEnabled(false);
        SincronizarDados sincronizarDados = new SincronizarDados();
        Thread threadSincronizarDados = new Thread(sincronizarDados);
        threadSincronizarDados.start();
        this.btnSincronizar.setText("Sincronizar");
        this.btnSincronizar.setEnabled(true);
    }                                           

vicentedepaula,

Antes de tudo:

  1. o swing trabalha na EDT( Event Dispatch Thread), qualquer operacao com os componentes do swing devem ser feitas dentro dessa thread
public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setSize(200, 200);
        frame.setVisible(true);
    }

na linha 2 o JFrame é instanciado, nesse momento já são criado as threads utilizadas pelo swing para eventos, atualizacoes de telas.
o codigo funciona, mas seguindo a regra que disse acima está errado. qual a forma correta?

Utilize

SwingUtilities.invokeAndWait( seu Runnable ); 
ou
SwingUtilities.invokeLater(seu Runnable); 

verifica o javadoc pra ver qual te atende melhor sempre que precisar executar uma thread na EDT

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                   JFrame frame = new JFrame();
        frame.setSize(200, 200);
        frame.setVisible(true);
            }
        });
  1. o swing só atualiza a tela no final do evento
        //mandei o swing pintar sincronizando no swing button
        this.btnSincronizar.setText("Sincronizando");
        this.btnSincronizar.setEnabled(false);
        SincronizarDados sincronizarDados = new SincronizarDados();
        Thread threadSincronizarDados = new Thread(sincronizarDados);
        threadSincronizarDados.start();
        //mandei ele pintar "sincronizar" no swing button <- perceba que aqui ainda o swingo não mandou pintar seu botao com o texto "sincronizando"        
        this.btnSincronizar.setText("Sincronizar");
        this.btnSincronizar.setEnabled(true);
        //fim evento
        ...
        //swing manda pintar componentes

entao, como fazer atualizar tela, fazer processamento demorado e atualizar apos termina o processamento?
pensando nisso… foi criado o SwingWorker
ele executa o seu processamento fora da EDT, e apos terminar o processamento executa outro metodo dentro da EDT

private void btnSincronizarActionPerformed(java.awt.event.ActionEvent evt) {  
  this.btnSincronizar.setText("Sincronizando");
  this.btnSincronizar.setEnabled(false);
   SwingWorker sw =  SwingWorker<String, Object> {

       //É executado fora da EDT, aqui fica o seu processamento demorado
       //Só deve realizar atualizacao de tela  nesse metodo utilizando process (não entrarei em detalhes nesse topico)
       @Override
       public String doInBackground() {
              SincronizarDados sincronizarDados = new SincronizarDados();
             sincronizarDados.atualizaTabelaClientes();

             String saida = "ok";
             return saida;
       }


       //Aqui é executado dentro da EDT apos terminar o processamento
       //Voce pode atualizar tela nesse metodo
       @Override
       protected void done() {
           try { 
                /*metodo get recebe o retorno de doInBackground(), é importante sempre chamar ele, mesmo que nao haja retorno ou não precise, voce pode perder alguma "exception" que ocorreu no doBackGround */
               String saida =  get();
                
                this.btnSincronizar.setText("Sincronizar");
                this.btnSincronizar.setEnabled(true);
                this.btnSincronizar.setSelected(true);

           } catch (Exception ex) {
                  ex.getCause() // exception que ocorreu
           }
       }
   }
 
   sw.execute();

o primeiro tipo na declaração em SwingWorker<String, Object>, será o tipo de retorno do metodo doInBackground()

de uma olhada em http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html pra entender melhor

qualquer duvida…

abraços