Aparecer Mensagens em Tempo Real na JtextArea

20 respostas
snow

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

20 Respostas

guisantogui

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? :?

ffc4852

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!!

snow

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

snow

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

Abraço

gergon

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…

snow

Obrigado gergon. :slight_smile:

Tem alguma tutorial a explicar como funciona o TimerBean?

Abraço

gergon

Que IDE vc esta usando?

snow

Desculpa, estou a usar o Netbeans 6.9

Abraço

fantomas

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

gergon

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

snow

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

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;
            }

        }
    }

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

gergon

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
}
fantomas

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

snow

Boas fantomas!

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

Abraço

fantomas

Oi Snow!

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

public class Main {

    public static void main(String[] args) {

        Console console = new Console();

        console.setVisible(true);

        Teste teste = new Teste(console);
    }
}
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);
    }
}
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();

    }
}

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

flws

snow

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

fantomas

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

snow

Já experimentei, não funciona na mesma.

Abraço

fantomas

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

snow

Olá!!

Já consegui :smiley:

O que fiz foi retirar o java.awt.EventQueue.invokeLater.

E de pois criei uma Thread que contem a invocação da class que eu pretendo.

Resolvido :smiley:

oi guisantogui vê se funciona no teu código como fiz.

Abraço

Criado 21 de julho de 2010
Ultima resposta 23 de jul. de 2010
Respostas 20
Participantes 5