Problema Cruel em Treads (3 dias no pau)

Tou com um problema maldito que não consigo resolver há 3 dias, já tentei em uns 10 foruns (inclusive no da Sun), mas até agora nada.

Problema:
Tenho um método que faz uso de Runtime.getRuntime().exec(command) para acessar o GBAK (arquivo que faz cópia/restauração do banco de dados Firebird), esse processo leva alguns minutos para terminar.

O que preciso é que durante esse tempo uma saída seja impressa em um componente Swing.

Isso poderia ser um cronômetro em um JLabel ou até mesmo uma barra intermitente com JProgressBar.

Porém nada disso foi possível até agora. O componente Swing simplesmente não atualiza o texto ou valor.

Já tentei com e sem:

int exitVal = process.waitFor();

Todos sabem que com esse linha o JVM faz todo o resto esperar esse processo terminar.

O código que vou informar abaixo está tentando ativar uma barra intermitente antes do início desse processo com uma mensagem e depois do processo terminando tentando desativar a barra e mudar a mensagem.

    private void setBackup(){
        campoMens.setText("");
        String gbak = getBinFolder()+"gbak.exe";
        String command = gbak+" -v -t " +
                "-user "+Lib.USUARIO+" " +
                "-password "+Lib.SENHA+" " +
                "localhost:"+Lib.CAMINHO_BD+" "+backupFile+" -y "+logFile;
        Process process;
        boolean exist = new File(gbak).exists();
        if(exist){
            barra.setString("Aguarde... Isso pode demorar...");
            barra.setIndeterminate(true);
            
            if(new File(backupFile).exists()){
                boolean deleted = new File(backupFile).delete();
            }
            if(new File(logFile).exists()){
                boolean deleted = new File(logFile).delete();
            }
            if(new File(zipFile).exists()){
                boolean deleted = new File(zipFile).delete();
            }
            
            try {
                process = Runtime.getRuntime().exec(command);
                int exitVal = process.waitFor();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            
            String str, mess = "";
            try {
                BufferedReader in = new BufferedReader(new FileReader(logFile));
                while ((str = in.readLine()) != null) {
                    mess += str+"\n";
                }
                in.close();
            } catch (IOException e) {}
            campoMens.setText(mess);
            campoMens.setCaretPosition(0);
            
            barra.setString("Processo de backup terminado.");
            barra.setIndeterminate(false);
        } else {
            campoMens.setText("O arquivo que executa o backup não está nessa máquina." +
                    "\nFavor executar esse procedimento na máquina onde o banco de dados está instalado.");
        }
    }

Alguma luz no fim do tunel???

Obrigado

Cara, assim.
Estuda bem o comportamento de
‘AWT event dispatching thread’
SwingUtilities.invokeLater
SwingWorker

E assim, nunca faça um processo dentro da ‘event dispatching thread’, como tu esta fazendo no teu
exemplo, coloque numa thread separada.

Peguei o teu exemplo e meio que usei o SwingUtilities.invokeLater, a unica coisa que
falta seria usar o SwingWorker para trancar a tela e o usuario nao ficar clicando novamente
no botão. Mas isto tu pode dar um olhada e incluir.

Ah, eh soh pra te dar a ideia, tem que dar um ajeitada no codigo.

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class UndeterminedProgressBar extends JPanel {

	JProgressBar barra;

	JTextArea campoMens;

	JButton button;

	public UndeterminedProgressBar() {
		this.barra = new JProgressBar();
		this.barra.setPreferredSize(new Dimension(100, 25));

		this.campoMens = new JTextArea();
		this.campoMens.setPreferredSize(new Dimension(100, 50));

		this.button = new JButton("Start");
		this.button.setPreferredSize(new Dimension(100, 25));
		this.button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setBackup();
			}
		});

		this.add(barra);
		this.add(new JScrollPane(campoMens));
		this.add(button);

	}

	private void setBackup() {
		this.barra.setIndeterminate(true);
		this.campoMens.setText("Inicio..\n");
		this.barra.setString("Aguarde... Isso pode demorar...");
		this.barra.setIndeterminate(true);

		new Thread(new Runnable() {
			public void run() {
				try {
					// process = Runtime.getRuntime().exec(command);
					// int exitVal = process.waitFor();
					// o teu processo aqui
					Thread.sleep(4000);
				} catch (InterruptedException ex) {
					ex.printStackTrace();
				}

				// atualiza a tela na EDT
				SwingUtilities.invokeLater(new Runnable() {
					@SuppressWarnings("unqualified-field-access")
					public void run() {
						String mess = "Tudo Certo!!!";

						campoMens.append(mess);
						campoMens.setCaretPosition(0);
						barra.setIndeterminate(false);
						barra.setString("Processo de backup terminado.");
					}
				});
			}
		}).start();
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		UndeterminedProgressBar panel = new UndeterminedProgressBar();
		frame.setSize(new Dimension(500, 300));
		frame.setContentPane(panel);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}