Imprimir resultados em um JTextArea

Opa galera!

Preciso de uma grande ajuda.
Estou desenvolvendo um trabalho de faculdade. O lance é criar um servidor de chat com threads.
O funcionamento do código está aprovado. Porém, preciso que seja impresso os “logs” do servidor em uma interface gráfica.
A pricípio os códigos são esses:

Servidor do Chat:

[code]package trabalhochat;

// ServidorDeChat.java
import java.io.;
import java.net.
;
import java.util.;
import javax.swing.
;
public class ServidorDeChat extends Thread {
public void iniciarThead() {
// instancia o vetor de clientes conectados
clientes = new Vector();
try {
// criando um socket que fica escutando a porta 2222.
ServerSocket s = new ServerSocket(2222);
// Loop principal.
while (true) {
// aguarda algum cliente se conectar. A execu��o do
// servidor fica bloqueada na chamada do m�todo accept da
// classe ServerSocket. Quando algum cliente se conectar
// ao servidor, o m�todo desbloqueia e retorna com um
// objeto da classe Socket, que � porta da comunica��o.

/*PRECISO IMPRIMIR ISSO*/
this.textoenviado="Esperando alguem se conectar...";
visao.setTexto(this.textoenviado);
 /*PRECISO IMPRIMIR ISSO*/

System.out.print("Esperando alguem se conectar...");
Socket conexao = s.accept();
System.out.println(" Conectou!");
// cria uma nova thread para tratar essa conex�o
Thread t = new ServidorDeChat(conexao);
t.start();
// voltando ao loop, esperando mais algu�m se conectar.

}
}
catch (IOException e) {
// caso ocorra alguma excess�o de E/S, mostre qual foi.
System.out.println("IOException: " + e);
}
}

// Parte que controla as conex�es por meio de threads.

String textoenviado = “”;
VisaoServidor visao = new VisaoServidor();
// Note que a instancia��o est� no main.
private static Vector clientes;
// socket deste cliente
private Socket conexao;
// nome deste cliente
private String meuNome;
// construtor que recebe o socket deste cliente
public ServidorDeChat(Socket s) {
conexao = s;
}
public ServidorDeChat() {

}

// execu��o da thread
public void run() {
try {
// objetos que permitem controlar fluxo de comunica��o
BufferedReader entrada = new BufferedReader(new
InputStreamReader(conexao.getInputStream()));
PrintStream saida = new
PrintStream(conexao.getOutputStream());
// primeiramente, espera-se pelo nome do cliente
meuNome = entrada.readLine();
// agora, verifica se string recebida � valida, pois
// sem a conex�o foi interrompida, a string � null.
// Se isso ocorrer, deve-se terminar a execu��o.
if (meuNome == null) {return;}
// Uma vez que se tem um cliente conectado e conhecido,
// coloca-se fluxo de sa�da para esse cliente no vetor de
// clientes conectados.
clientes.add(saida);
// clientes � objeto compartilhado por v�rias threads!
// De acordo com o manual da API, os m�todos s�o
// sincronizados. Portanto, n�o h� problemas de acessos
// simult�neos.

// Loop principal: esperando por alguma string do cliente.
// Quando recebe, envia a todos os conectados at� que o
// cliente envie linha em branco.
// Verificar se linha � null (conex�o interrompida)
// Se n�o for nula, pode-se compar�-la com m�todos string
String linha = entrada.readLine();
while (linha != null && !(linha.trim().equals(""))) {
// reenvia a linha para todos os clientes conectados
sendToAll(saida, " disse: ", linha);
// espera por uma nova linha.
linha = entrada.readLine();
}
// Uma vez que o cliente enviou linha em branco, retira-se
// fluxo de sa�da do vetor de clientes e fecha-se conex�o.
sendToAll(saida, " saiu ", “do chat!”);
clientes.remove(saida);
conexao.close();
}
catch (IOException e) {
// Caso ocorra alguma excess�o de E/S, mostre qual foi.
System.out.println("IOException: " + e);
}
}

// enviar uma mensagem para todos, menos para o pr�prio
public void sendToAll(PrintStream saida, String acao,
String linha) throws IOException {
Enumeration e = clientes.elements();
while (e.hasMoreElements()) {
// obt�m o fluxo de sa�da de um dos clientes
PrintStream chat = (PrintStream) e.nextElement();
// envia para todos, menos para o pr�prio usu�rio
if (chat != saida) {chat.println(meuNome + acao + linha);}
}
}
}[/code]

Interface Gráfica:

[code]package trabalhochat;

public class VisaoServidor extends javax.swing.JFrame {
public VisaoServidor() {
initComponents();
}
public VisaoServidor(int I)
{
this.texto="";
}

@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    jTextArea1 = new javax.swing.JTextArea();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jTextArea1.setColumns(20);
    jTextArea1.setRows(5);
    jScrollPane1.setViewportView(jTextArea1);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 179, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 390, Short.MAX_VALUE)
    );

    java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
    setBounds((screenSize.width-187)/2, (screenSize.height-424)/2, 187, 424);
}// </editor-fold>

public static void main(String args[]) {
    ServidorDeChat servidor = new ServidorDeChat();
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new VisaoServidor().setVisible(true);
        }
    });
    servidor.iniciarThead();

}

// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextArea jTextArea1;
// End of variables declaration
private String texto ="";


/**
 * @param texto the texto to set
 */
public void setTexto(String tex) {
    this.texto = tex;
    this.jTextArea1.setText(tex); //Acho que isto é o correto...
}

}
[/code]

O que comentado como PRECISO IMPRIMIR ISSO na parte “Servidor de Chat” é o que eu preciso imprimir no JTextArea da Visão.
No final da 2ª classe, está o método que eu achava que funcionaria… E não funcionou.

Pergunta:
Como farei para imprimir a mensagem do Servidor de Chat?
O que eu fiz não funciona nem por decreto…

OBS: Será que precisa de um action para alterar o jTextArea?
E se for isso, qual action?

Obrigado.

P.S: Se alguém perguntar, eu respondo: “Sim, usei o NetBeans pra gerar a parte gráfica…”

Foi você mesmo quem fez esse código? Porque você está usando o estilo de programação do Java 1.2, e dá a impressão que você copiou o código de algum lugar beeem antigo.

Se você quer se adequar ao estilo normal, comece eliminando o Vector e substituindo por um ArrayList. Não se faz mais iteração através de um Enumerator há muito tempo, no lugar, use o for each ou o iterator. É mais seguro e mais fácil também.

Preferencialmente, atribua um tipo de dado ao conteúdo do seu ArrayList usando Generics:
http://www.guj.com.br/posts/list/74068.java#389435

Para imprimir em um JTextArea, é melhor usar o comando append. Ele irá adicionar mais texto ao JTextArea, ao invés de substituir o texto existente pela String passada. No caso de chat, você pode ter um fluxo de textos maior, e o append se tornar desinteressante. Nesse caso, você pode usar uma dessas classes aqui:
http://www.guj.com.br/posts/list/83462.java#445238

Ela permite usar o JTextArea como se fosse um System.out. E já tem uma threadzinha para não deixar um fluxo muito grande travar a aplicação.

Bem, mas no caso, eu só quero imprimir na tela os logs de quem conectou…
Não será as mensagens nesta tela.

Aqui, só usar jTextArea1.append(“qualquer coisa”); ?
Pq num deu muito certo não…

Mudei esta parte para o append e não deu certo…

public void setTexto(String tex) { this.texto = tex; this.jTextArea1.append("Testando..."); }

Está no final do 2º código passado acima.

Acho que terei que montar outra estratégia…

OBS: O código foi passado pelo professor…
Como preciso entregar isso meio que correndo, vou arriscar mudar muita coisa não…
Qdo estiver mais tranquilo, faço isso. Será mais por questões de aprendizagem mesmo.

Por que não deu certo? O que o Java fez?

Absolutamente nada.

O JFrame fica absolutamente vazio.
O JFrame roda, o servidor funciona (pq eu testo o Cliente e funciona), mas o JFrame fica vazio…

Nota: Será que não é meu construtor? Pq pra criar o objeto da classe visual, eu inicio por ele (não anta. Vc inicia do destructor…).
Não sei pq, estou com esta desconfiança…

Pode ser isso aqui:

public VisaoServidor(int I) { this.texto=""; }

Mude para:

public VisaoServidor(int I) { this(); this.texto=""; }

Esquece, achei o problema. Você cria no main uma visão, e no servidor outra.
Ou seja, seu main exibe uma coisa, mas seu servidor atualiza outra.

O seu código só poderá ter um único “new VisaoServidor()”, que será o do main.

Isso não seria a mesma coisa que só chamar o construtor inicial?

Pq no código, eu não uso a variável this.texto.
E já criei o objeto com os dois contrutores e o JFrame continua vazio.

Se eu mudar o JTextArea para JTextPane? Não seria mais fácil trabalhar?

Ah tá!
Entendi. Então quer dizer que é como se o código fosse impresso em uma nova “tela invisível”.

Então como eu criaria um objeto da classe visão para pegar o método que está na classe da visão?
Ou, como eu jogaria este valor para a visão?

Faça o seguinte, altere o construtor da classe ServidorDeChat para:

public ServidorDeChat(Socket s, VisaoServidor vs) { conexao = s; visao = vs; }

e

public ServidorDeChat(VisaoServidor vs) { visao = vs; }

Depois, altere a inicialização da variável visao, da mesma classe para:

Depois, na hora de criar, faça:

public static void main(String args[]) { final VisaoServidor visao = new VisaoServidor(); ServidorDeChat servidor = new ServidorDeChat(visao); java.awt.EventQueue.invokeLater(new Runnable() { public void run() { visao.setVisible(true); } }); servidor.iniciarThead(); }

E

Ou, vc é o cara…

Só que não imprimiu nada ainda.

Se vc qser, te mando o pacote do projeto que estou fazendo. Ele só está no NetBeans.

AFF!

Não funcionou de novo.
Vou perder a paciência com isso e montar uma nova visão.
Só não sei como vou embutir a visão (que extende a JFRAME) com o servidor (que extende a Threads).
Se não fosse as extensõs, colocava tudo na mesma classe e resolvia meu problema.