Aparecer Mensagens em Tempo Real na JtextArea

Bom dia pessoal,

Aki estou eu outra vez :slight_smile:

O meu problema é o seguinte:

Eu tenho um projecto em netbeans “Java Application”.

Estou a usar uma parte grafica com uma JTextArea.

Ao logo do código estou a por mensagens para aparecer na JTextArea.

Mas as mensagens só aparecem quando acaba de correr o código.

Como é que posso por aparecer na JTextArea as mensagens em tempo real?

Abraço

Estou com esse problema tb, acho que é necessário o uso de multiplas Threads! Alguém sabe como faz isso, tipo a cada linha que andar no evento executar imediatamente? :?

a ideia das threads eh interessante…mas acho que a sincronizacao delas poderia gerar inconsistencia em alguns casos…

qdo mais precisamente vc precisa alterar o conteudo da jTextArea???

nao poderia fazer por um metodo generico para atualizacao???

eu tenho um simulador que eu atualizo diversos campos na tela em tempo real…dai fiz um metodo tipo o repaint (da applet)…que pode reexibir apenas um campo atualizado…ou varrer os outros para saber se possui modificacoes…

nao sei se encaixa na sua necessidade…mas qquer coisa fala mais sobre oq vc precisa que mando novas ideias!!

faloouuu!!

O numero de mensagens a aparecer na JTextArea não é calculado, ou seja, pode aparecer 4 mensagens como pode aparecer 30 mensagens.

A minha ideia é fazer um género de consola, onde aparecerá mesagens de sucesso ou de erro.

Para o utilizador saber o que o programa está a fazer.

Abraço

Alguem podia explicar a mim e ao guisantogui como é que podemos fazer isto?

Abraço

Tente usar o timerbean
com ela pode se fazer mutiplas threads.
http://informaticon.com.br/site/file.php/1/TimerBean.jar
Se estiver usando o netbeans sera mais facil para adicionar ele…

Obrigado gergon. :slight_smile:

Tem alguma tutorial a explicar como funciona o TimerBean?

Abraço

Que IDE vc esta usando?

Desculpa, estou a usar o Netbeans 6.9

Abraço

Oi snow!

Normalmente os objetos visuais sofrem acões de threads não previstas pelo programador para causar o refresh, ou seja, as vezes simplesmente não precisa fazer nada. Resumindo…depende da situação em que vc se encontra.

Se o seu código não for muito grande, coloque em um post para podermos ajuda-lo melhor.

flws

Para adicionar este jar a seu projeto faca o seguinte
No netbeans navegue em>> ferramentas>>paleta>>Componentes swing/awt

Na janela que ira abrir va em>> adicionar do jar

Agora nesta janela procure pelo arquivo jar TimerBean que voce baixou e seleciona ele>>depois de next>selecione timer e de next>>selecione beans e depois concluir…

Assim eh so adicionar o componente Timer do bean e adicionar ele em seu projeto

Aqui esta a API do TimerBean http://www.easybeans.org/javadoc/org/ow2/easybeans/examples/timerservice/TimerBean.html

Peço desculpa mas o meu código é um bocado grande, mas vou vos dar um exemplo:

[code]private void txtDateFocusLost(java.awt.event.FocusEvent evt) {
//Configuração das mensagens na Consola
JTextArea output = getTxtConsole();
//output.setText("");
output.getText();

    // Now create a new TextAreaOutputStream to write to our JTextArea control and wrap a
    // PrintStream around it to support the println/printf methods.
    PrintStream out = new PrintStream( new TextAreaOutputStream( output ) );
    
    // redirect standard output stream to the TextAreaOutputStream
    System.setOut( out );
    
    // redirect standard error stream to the TextAreaOutputStream
    System.setErr( out );

    String data = this.txtDate.getText();

    DateFormat formatter = new SimpleDateFormat("yyyyMMdd");

    //Validar o Campo Data
    if(data.equals("")){
        
        //Apresenta mensagem de erro na Consola
        System.out.println("Defina uma data");
        //E não deixa carregar no botão de ok
        this.bttOk.setEnabled(false);
    }else{
        
        try {
            if(data.length() != 8){
                throw new ParseException("", 0);
            }
            Date date = (Date) formatter.parse(data);
            
            System.out.println("date - "+date);
            
            this.bttOk.setEnabled(true);

        } catch (ParseException ex) {
            System.out.println("Data incorrecta");
            this.bttOk.setEnabled(false);
        return;
        }

    }
}       [/code]

O meu problema é que só no final de correr a função é que aparecem as mensagens.

O que eu queria era ao logo da função quando aparece-se um System.out.println() apresenta-se logo na JTextArea.

Precebem ou tá confuso?

Abraço

La vai como vc pode fazer para resolver a sua duvida…

Depois de fazer o que eu te disse

adiciona o componente bean no projeto…

configure o delay dele na janela de propriedades, o delay é o tempo em milisegundo. la vai estar 1000 ou seja a cada segundo ele fara algo…

depois adicione o evento OnTime[Timer1OnTime]

O que colocar neste evento(que no momento metodo) sera o que ele fara a cada tempo
E declare o metodo Timer1.start() no metodo da classe

exemplo do evento:

public minhaClasse(){
//declaracoes de init componentes e outros metodos
//E a declaracao do metodo Timer.start():
Timer.start():
}

private void Timer1OnTime(algo que nao me lembro){
//aqui dentro vai oque ele vai fazer a cada segundo,se delay for 1000
//por exemplo
system.out.println("Ola sou o segundo");//vai aparecer esta mensagen a cada segundo
}

Oi Snow!

Ao ler o seu código notei que (minha opinião):

  1. As mensagens não aparecem de imediato porque a thread da “função” é prioritária; por isso que elas só aparecem quando a “função” termina, a outra thread (a que faz o refresh) processa logo em seguida.

  2. Tem muito código dentro do seu método.

Talvez para resolver isto você tenha que colocar o TextArea em uma outra thread ou simplesmente desacoplar esta parte do código do código do método.

flws

Boas fantomas!

Como é que eu posso por as mensagens prioritárias?

Abraço

Oi Snow!

Escrevi um código para tentar lhe ajudar, leia e tire suas conclusões.

[code]public class Main {

public static void main(String[] args) {

    Console console = new Console();

    console.setVisible(true);

    Teste teste = new Teste(console);
}

}
[/code]

[code]public class Console extends JFrame {

private JTextArea txtArea = new JTextArea();

public Console() {
    this.initialize();
}

public void println(final String value ) {
    this.txtArea.append(value);
    this.txtArea.append("\n");
}

private void initialize() {
    super.setTitle("Console");
    super.getContentPane().add(this.txtArea, BorderLayout.CENTER);
    super.setSize(500, 200);
    super.setLocationRelativeTo(null);
}

}
[/code]

[code]public class Teste extends JFrame {

private Console console = null;

public Teste(final Console console) {
    this.console = console;
    this.initialize();
}

private void initialize() {

    super.setTitle("TESTE");

    super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    super.setLayout(new GridLayout(2, 3));

    JTextField firstName = new JTextField(40);
    JTextField lastName = new JTextField(40);

    firstName.addFocusListener(new FocusListener() {

        public void focusGained(FocusEvent e) {
            Teste.this.console.println("Entrei no campo first name!");
        }

        public void focusLost(FocusEvent e) {
            Teste.this.lostFocusProcess();
        }
    });

    super.getContentPane().add(new JLabel("First Name :"));
    super.getContentPane().add(firstName);
    super.getContentPane().add(new JLabel("Last Name :"));
    super.getContentPane().add(lastName);

    super.setLocationRelativeTo(null);
    super.pack();
    super.setVisible(true);
}

private void lostFocusProcess() {

    // ESTA THREAD É EXECUTADA "PARALELAMENTE" COM A THREAD DO MÉTODO

    Thread thread = new Thread(new Runnable() {

        public void run() {
            Teste.this.console.println("Sai do campo first name!");
            Teste.this.console.println("Vou aguardar 3 segundos!");
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Teste.this.console.println("3 segundos expirados!");
            Teste.this.console.println("Fim do método lostFocusProcess!");
        }
    });

    thread.start();

}

}
[/code]

O ponto de interesse é o método lostFocusProcess, execute para ver se a idéia serve como solução.

flws

Já implementei o exemplo que me indicas-te mas não funciona.

Eu penso que seja por causa do método: java.awt.EventQueue.invokeLater

Este método bloqueia a parte gráfica toda por isso é que as mensagens não vão aparecendo ao logo do código.

Existem algum método que não bloqueie a parte gráfica?

Abraço

Faça um teste sem utilizar o invokeLater para ver o que acontece.

Se não me falha a memória o invokeLater coloca sua thread em uma especie de fila de execução, ou seja, será executado tardiamente (later). Sem o invokeLater a VM tera que compartilhar o tempo de execução no mesmo momento.

flws

Já experimentei, não funciona na mesma.

Abraço

Se o código que coloque no post como exemplo estiver executando conforme o esperado, siguinifica que o problema pode estar em outro lugar do seu código.

Se isto se confirmar será dificil lhe ajudar sem o ver o teu código completo.

Você consegue isolar o problema em algumas classes pequenas que possam ser executadas para que a gente possa analisar?

flws