Atualizar conteúdo de um JTextPane conforme adiciono texto a um StringBuffer?

Eu sei… Essa pergunta é muito doida…mas lá vai:

Eu consigo atualizar o texto de um JTextPane (ou JTextArea, JEditorPane…) conforme vou adicionando Strings a um StringBuffer. Ou seja, atrelar todas as modificações de valores de um StringBuffer para que seu valor seja exibido em um JTextPane?

Qual a minha idéia? Enviar esse StringBuffer como parâmetro para diversos objetos de processamente de operações longas. Esse processamento longo deverá registrar no StringBuffer as tarefas que executou. Ao mesmo tempo que isso é registrado no StringBuffer, essas mudanças repercutam automaticamente no JTextPane e este exibe o conteúdo atualizado do StringBuffer em tempo real.

Têm como ou viajei na maionese?? kkk
:smiley:

Só fazendo um método que atualize os dois.

E… vc não quis dizer StringBuilder no lugar de StringBuffer?

Não…é StringBuffer mesmo…

A idéia era o StringBuffer servir como fonte de conteúdo para o JTextPane. Assim ao adicionar textos nele, não teria que me preocupar em atualizar o segundo.

Eu vou te contar o que eu fiz, quando precisei fazer o que você quer…

  1. Criei um Writer chamado MultipleWriter, que redirecionava a saída dele para vários writers (uma implementação direta do padrão Composite);
  2. Usei um StringWriter no lugar do StringBuffer;
  3. Criei uma classe que é um writer para o TextComponent: http://www.guj.com.br/posts/list/83462.java#445238

O StringBuffer é adequado para ambientes multi-threads a um custo de perda de desempenho. Quase sempre você deve usar StringBuilder.

A solução do ViniGodoy deve servir, mas eu acredito que seja mais simples usar um append no StringBuilder e no JTextArea.

O StringBuffer é adequado para ambientes multi-threads a um custo de perda de desempenho. Quase sempre você deve usar StringBuilder.

A solução do ViniGodoy deve servir, mas eu acredito que seja mais simples usar um append no StringBuilder e no JTextArea.[/quote]

E… detalhe… normalmente, mesmo em ambiente multi-thread, seus métodos sincronizarão o acesso ao StringBuilder. Você só precisa do StringBuffer se as threads irão escrever diretamente sobre ele, isto é, se ele for a variável compartilhada entre multiplas threads, o que raríssimamente é o que ocorre.

A solução do PrintWriter que dei é interessante quando você pode ter multiplas saídas, configuráveis. No nosso caso, era opcional jogar a saída para a tela. O usuário também poderia incluir um arquivo nas saídas possíveis, ou mesmo enviar os dados via socket (ou tudo isso ao mesmo tempo). Para cada opção, havia um writer que simplesmente precisaria ser incluído no multiple-writer. As classes que geravam os dados só precisam conhecer o PrintWriter que escrevia nesse cara.

E aí Marcos, blz?

Ok

É o que venho fazendo… mas estou fazendo o log em html. E o JTextArea, que não suporta esse formato, é o único que têm o append. Assim, gostaria de saber uma forma mais simples de portar este writer entre as classes que irão registrar suas operações (sem ter que ficar portando dois objetos).
Na verdade, já consegui fazer assim, enviando os dois objetos para atualizar. Mas queria saber se não há uma forma que possa empregar como padrão nestas situações, utilizando conteúdo texto, html, rtf ou componentes JtextArea, JEditorPane… para todos eles, sendo uma forma simples e intuitiva de fazer isso.

ViniGodoy, funcionou.

Rodei um pequeno teste para verificar se conseguia. Mas quando registro as operações em html no writer, está aparecendo o código html em si e não a página formatada:

<html><body><p style="color: red;">Primeira tarefa executada</p><p>Segunda tarefa executada</p><p>Terceira tarefa executando</p><ul><li>Processamento dos dados;</li><li>Armazenamento;</li><li>Limpeza de cache.</li></ul><p><b>Quarta tarefa</b> executada</p><h2>Última tarefa executada</h2></body></html>

Fora esse detalhe, ficou muito legal. Eu já configurei o JTextPane para exibir html e o JEditorPane também. Com ambos, aconteceu o mesmo.

Nem tudo é perfeito… :frowning:

Você pode fazer um append diretamente a qualquer Document (isso quer dizer que pode se aplicar a qualquer JTextComponent). O JTextArea é o único componente que traz um método utilitário para isso. Aqui segue o código que fica no método append do JTextArea:

Document doc = getDocument();                        
if (doc != null) {                                   
    try {                                            
        doc.insertString(doc.getLength(), str, null);
    } catch (BadLocationException e) {               
    }                                                
}                                                    

Funcionou também.

Mas está apresentando o mesmo problema que postei, explicando ao Viny. O código aparece em html puro ao invés de ficar formatado.