Olá pessoal.
Cá estou eu, com o trabalho final de POO2 da faculdade, precisando de ajuda.
Abaixo a tela principal. Inclui uma nova ação normalmente.:
A aba novidades tem um JTextArea, onde a cada inclusão, exclusão ou alteração, dou um append com a informação sobre a operação realizada. Porém ao clicar na aba para ler as novidades, parece que o append não funcionou:
Mas se após o append, eu exibir uma mensagem com todo o conteúdo do JTextArea, está tudo lá. Vejam a imagem abaixo, após incluir duas ações no sistema:
Alguém sabe porque isso acontece?
Tenho um JPanel, com um JScrollPane e dentro deste o JTextArea. Já tentei dar repaint() nos três componentes, sem êxito.
Segue o código da aba Novidades:
[code]public class Novidades extends JPanel implements Observer {
private Acao acao;
private JTextArea areaTexto;
private JScrollPane scrollPane;
public Novidades() {
setLayout(new BorderLayout(0, 0));
areaTexto = new JTextArea();
areaTexto.setEditable(false);
scrollPane = new JScrollPane(areaTexto);
add(scrollPane);
areaTexto.append(".::NOVIDADES NA BOLSA DE VALORES::.\n\n\n");
}
@Override
public void update(DadosAcoes o) {
this.acao = o.getAcao();
if (o.isEhNova()) {
this.informaNova();
} else {
if (o.isEhExclusao()) {
this.informaExclusao();
} else {
this.informaAlteracao();
}
}
}
private void informaNova() {
areaTexto.append("- Ação "+acao.getCodigo()+" negociada por "+acao.getDescricao()+" por R$ "+acao.getValor()+".\n\n");
JOptionPane.showMessageDialog(null, areaTexto.getText());
}[/code]
Ajuudem!
Não sei se entendi direito. Você quer exibir apenas a última mensagem inserida?
Está aparecendo todas as mensagens, por que vc está exibindo todo conteúdo do seu TextArea.
Pra exibir somente a última, teria que fazer algo assim:
[code]
private void informaNova() {
String ultimaNovidade = “- Ação “+acao.getCodigo()+” negociada por “+acao.getDescricao()+” por R$ “+acao.getValor()+”.\n\n”;
areaTexto.append(ultimaNovidade);
JOptionPane.showMessageDialog(null, ultimaNovidade);
} [/code]
[quote=igor_ks]Não sei se entendi direito. Você quer exibir apenas a última mensagem inserida?
Está aparecendo todas as mensagens, por que vc está exibindo todo conteúdo do seu TextArea.
Pra exibir somente a última, teria que fazer algo assim:
[code]
private void informaNova() {
String ultimaNovidade = “- Ação “+acao.getCodigo()+” negociada por “+acao.getDescricao()+” por R$ “+acao.getValor()+”.\n\n”;
areaTexto.append(ultimaNovidade);
JOptionPane.showMessageDialog(null, ultimaNovidade);
} [/code][/quote]
Eu preciso exibir tudo.
Ao instanciar o JTextArea, eu faço o append do título.
Durante a execução do programa, conforme operações ocorrem, é preciso reportá-las nessa área de texto. Tudo o que acontece durante a execução do programa deve ser reportado ali, serve como um “journal” das operações efetuadas. E por isso mesmo que coloquei essa área de texto com scroll, pra justamente quando encher continuar escrevendo e habilitar o scroll.
Só que todo append que eu faço nesse textArea simplesmente não é exibido no componente. Mas se eu pegar todo o conteúdo já escrito nesse textArea e mandar exibir numa JOptionPane por exemplo, está tudo lá.
O problema não está em inserir as informações, está na exibição mesmo. O componente está recebendo e armazenando as informações corretamente, porém não as exibe.
Coloca um breakpoint no seu construtor e veja se não está sendo chamado duas vezes.
Olá Vini!
Creio que não seja isso, pois se na linha abaixo da qual eu fizer o append, criar um JOptionPane pra exibir o getText() desta JTextArea, todo o conteúdo é exibido. Mas na bendita área de texto ele não aparece.
Outro fato importante é que implementei o padrão de projeto Observer, e este TextArea está numa classe Observadora. Eu instancio todos os Observadores no início da aplicação e registro-os no Subject. É um dos primeiros passos na inicialização do programa. Portanto já descartei essa possibilidade de o construtor estar sendo chamado mais vezes, pois só é possível atualizar o objeto Observer a partir de um notifyObservers() vindo do Subject, e como este objeto tem uma lista dos seus observadores, e em nenhum momento tal lista é alterada, já me certifiquei que não existe mais de uma instância desta classe Novidades rodando no meu sistema.
Enfim, já entreguei este trabalho e expliquei a situação para o professor. No fim das contas o objetivo não era avaliar interface gráfica, mas sim conceitos de POO e Design Patterns(que funcionou!).
Mas eu fiquei boladão que essa porcaria não funcionou! Odeio trabalhar com Swing!
Deveria funcionar. Mas faça o que eu falei. O que as vezes acontece é ter duas instâncias, uma delas criada por acidente. Uma que está na tela, e outra que vc está atualizando.
Estou com o mesmo problema. Como você conseguiu resolver?
Não consegui resolver não cara.
No fim das contas eu fiz exibir o conteúdo do TextArea em um JOptionPane mesmo e expliquei a situação para o meu professor. Nem ele conseguiu encontrar o problema.
Cara, eu consegui resolver colocando pra mostrar dentro de uma Thread. Pode fazer o teste que vai funcionar. Eu tava notando que ele só não escreve no Jtext quando entra em algum loop. Eu fiz disparar uma Thread e resolveu o problema, mostrava certinho dentro. Faz um teste e diga se deu certo.
Eu sei que você já entregou o seu trabalho para o professor, mas aqui neste link está a resposta para seu problema:
http://pt.stackoverflow.com/questions/25169/jtextarea-recebe-o-append-mas-n%C3%A3o-exibe-o-texto/25267#25267
[quote=bomba544]Eu sei que você já entregou o seu trabalho para o professor, mas aqui neste link está a resposta para seu problema:
http://pt.stackoverflow.com/questions/25169/jtextarea-recebe-o-append-mas-n%C3%A3o-exibe-o-texto/25267#25267[/quote]
Interessante isto.
Não consegui ler tudo, li meio por cima aqui, mas vou guardar o link pra ler com mais atenção qualquer dia desses.
Eu não sabia da existência deste SwingUtilities.
Quem disparava mensagens para o observer não era uma thread separada? Eu sempre parti do pressuposto que fosse.
O método append, do contrário do contrário do setText (que o StackOverflow fala) é um dos poucos que são thread-safe.
Desculpa Vini, não sabíamos o que realmente era o problema. Eu não sabia que o frame só atualizava depois que saisse dela .-.
Saisse da Event Dispatcher Thread…
Estava falando ali da arquitetura do Ruttman. No seu código eu não saberia dizer. É que no código dele o código que chamada o JTextArea implementa observer, então, parti do pressuposto (talvez errado de minha parte) que esse observer era alimentado por outra thread.
Eu tava pensando aqui…
Então o método repaint() só vai funcionar dentro Thread Separada?
[quote=bomba544]Eu tava pensando aqui…
Então o método repaint() só vai funcionar dentro Thread Separada?[/quote]
A thread do Swing funciona assim:
while (true) {
while (temMensagensNaFila()) {
processaAProximaMensagem();
}
if (houvePedidoDeRepaint) {
repintaTela();
}
yield();
}
O comando EventQueue.invokeLater coloca uma mensagem na fila do Swing.
O comando repaint, coloca outra mensagem, solicitando a repintura.
Um evento, também ocorre como resposta a uma mensagem da fila do Swing, portanto, é uma das atividades do método “processaMensagensDaFila()”. Por isso, ele trava a repintura, impedindo a tela de se redesenhar.
Isso responde a sua pergunta? Se você der um repaint num método evento de botão, só estará colocando uma mensagem a mais na fila, que não será processada até que esse evento termine e o Swing um dia chegue no pedido de repintura.
Respondida sim. Muito obrigado, de verdade.