Actualizar JTextArea desde otra clase

Iniciado por ChicoTolerante, 27 Febrero 2013, 02:05 AM

0 Miembros y 1 Visitante están viendo este tema.

ChicoTolerante

Hola!

Estoy INTENTANDO hacer un chat. El problema lo tengo para actualizar los mensajes enviados y el texto que debe aparecer en el JTextArea. Entonces, tengo lo siguiente, esencialmente:

Código (java) [Seleccionar]

Fichero 1: clase InterfazDelChat
public class InterfazDelChat extends JFrame implement ActionListener
{
public static JTextArea areaChat = new JTextArea("Titulo del JTextArea del chat\n\n", 50, 50);
public static JButton conec = new JButton("Conectar");
public InterfazDelChat()
{
super("Titulillo");
getContentPane().add(areaChat);
getContentPane().add(conec);
areaChat.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent ev)
{
new ServidorDelChat;
}
public static void main(String[]args)
{
new InterfazDelChat();
}
}


Fichero 2: clase ServidorDelChat
Código (java) [Seleccionar]

public static class ServidorDelChat
{
public ServidorDelChat()
{
//Codigo del socket hasta el punto de DataInputStream tenerlo en el String mensajeRecibido)
while (desconectado != true)
{
//Lo que yo creia que tenia que poner:
InterfazDelChat.areaChat.append("\nCliente dice:\n" + mensajeRecibido + "\n");
}
/*Lo que ocurre, cuando pongo esto, es que el texto no llega a la interfaz, al JTextArea
del programa, hasta que no ha completado el bucle
(cuando pongo un numero de opciones finito,
no como el que esta puesto aqui,
si pongo 3, envia 3 mensajes diferentes...),
porque si quiero que esto se pueda repetir, ¿tendre que meterlo en un bucle, no?
El caso es que me lo imprime, y me lo imprime bien, pero tarde.
No me lo imprime en la pantalla, en el caso de poner 3 como fin del bucle,
hasta que no ha superado el bucle, no carga el texto
(no carga el texto de linea en linea, carga solo al final del bucle todos los mensajes acumulados...*/
}
}


He imaginado que la clase InterfazDelChat no se vuelve a cargar hasta que acaba con el bucle, que termina el objeto, y así vuelve a cargar los demás objetos. Entonces... mi pregunta sería:
  - ¿Cómo puedo cargar el JTextArea de la clase InterfazDelChat desde la otra clase ServidorSocket? ¿O cómo puedo cargar de nuevo un objeto, o actualizarlo, estando este en una, y queriendo cargarlo desde otra?

Gracias por todo!!!

Kenkox

#1
Pues respondiendo a tu pregunta...
1ª Clase Cliente ( con JTextArea )
2ª Clase Servidor ( con quien quiero modificar el JTextArea )

Lo que podrias hacer es tener tu JTextArea como miembro estatico privado  de tu clase cliente, y con su respectivo metodo get..... en la clase Servidor pues llamas a tu clase cliente, y el metodo get que te regresa el textArea.... el problema de esto es que solo podrias tener un cliente ya que el jtextArea seria miembro de la clase y no de un objeto cliente.... por lo cual te recomiendo que tu crees una clase llamada "Lector"

Clase Servidor ----->

Código (java) [Seleccionar]

// En esta clase, al momento de crear el hilo de "Lector" tambien le deberas de pasar la referencia de tu jtextarea....
// asi, tu hilo se encargara de escribir el contenido que reciba al jtextarea

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;


public class Servidor {
public static void main(String[] args) throws IOException {
// variables
String  auxiliar;
int puertoServicio = 0;
       ServerSocket miServicio = null;
Socket miCliente = null;


// Creando objeto para escribrir flujo de entrada
       BufferedReader  teclado = new BufferedReader(new InputStreamReader(System.in));

// pidiendo datos para la conexion
System.out.println("Inserta el numero de puerto");
try{
puertoServicio=Integer.parseInt(teclado.readLine());
System.out.println("Puerto establecido.\nEsperando peticiones");
}
catch(NumberFormatException e){
System.out.println("Error de datos del teclado");
System.exit(1);
}

// Creando socket, asignando puerto y aceptando solicitud de cliente.
       try {
           miServicio = new ServerSocket(puertoServicio);
   miCliente = miServicio.accept();
       } catch (Exception e) {
           System.err.println("No se establecio el puerto "+puertoServicio);
           System.exit(1);
       }

//Creando objeto para leer flujo de entrada desde el socket.
BufferedReader entrada = new BufferedReader(new InputStreamReader(miCliente.getInputStream()));
//DataInputStream entrada = new DataInputStream(miCliente.getInputStream());

// Creando objeto para escribir flujo de salida hacia el socket.
//DataOutputStream salida = new DataOutputStream(miCliente.getOutputStream());
       PrintWriter salida = new PrintWriter(miCliente.getOutputStream(), true);
      System.out.println("-----SERVIDOR-----\n\nCliente conectado. Iniciando comunicación...\n");

      // Creando un subproceso que se encargará de leer datos  de entrada del socket.(Hilo)
     Thread t = new Thread(new Lector(entrada));
            t.start();

// Ciclo interativo de escritura sobre el socket(enviando lineas de texto).
       while (!((auxiliar=teclado.readLine()).equals("salir"))) {
           salida.println(auxiliar);
       }

// Cerrando conexiones y flujos.
teclado.close();
       salida.close();
       entrada.close();
       miCliente.close();
       miServicio.close();
   }
}



Clase Lector ---->


Código (java) [Seleccionar]

// en esta clase, en el contructor tienes que recibir aparte del buffer, recibir un jtextarea...
// y en el metodo run, adjuntar el contenido que el buffer tenga

import java.io.BufferedReader;
import java.io.DataInputStream;

public final class Lector implements Runnable {

   DataInputStream entrada1;
   BufferedReader entrada;
   String cadena;

   public Lector(BufferedReader entrada){ /// AQUI TAMBIEN RECIBIR UNA REFERENCIA A UN TEXTAREA
       this.entrada=entrada;
   }

@Override
   public void run() {
       try {

           while (!((cadena = entrada.readLine()).equals("salir"))) {
               System.out.println("Recibido: " + cadena); // EN LUGAR DE ESTO, SERIA AJDUNTAR CADENA AL JTEXTAREA
           }

       } catch (Exception ex) {
           System.out.println("CONEXIÓN FINALIZADA");
  System.exit(0);
       }
   }
}



Clase Cliente  ----->

Código (java) [Seleccionar]


// En esta clase, al crear tu hilo "lector" de igual manera deberas enviar el jtextarea
// de esta clase, para que tu hilo "lector" se encarge de escribir los mensajes que reciba en tu jtextarea
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class Cliente {
   public static void main(String[] args) throws IOException {
// declaracion de variables
       Socket miCliente = null;
       String ipServidor;
String auxiliar;
       int puertoServidor = 0;

// Creando objeto para  flujo de entrada de datos desde el teclado.
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));

// pidiendo datos desde el teclado
System.out.println("Inserta la IP del servidor o nombre del servidor");
ipServidor=teclado.readLine();

System.out.println("Insetra numero de puerto");
try{
puertoServidor = Integer.parseInt(teclado.readLine());
}
catch(NumberFormatException e){
System.out.println("Error de datos de entrada");
System.exit(1);
}

// Inicializando socket
try {
           miCliente = new Socket(ipServidor,puertoServidor);
       } catch (IOException e) {
           System.err.println("No se pudo establecer la conexión");
           System.exit(1);
       }
//Creando objeto para leer flujo de entrada desde el socket.
       BufferedReader entrada = new BufferedReader(new InputStreamReader(miCliente.getInputStream()));
PrintWriter salida = new PrintWriter(miCliente.getOutputStream(), true);

System.out.println("-----CLIENTE-----\n");
       System.out.println("Conexión establecida. Comenzando comunicación...\n");

// Creando un subproceso que se encargará de leer datos de entrada del socket.
       Thread t=new Thread(new Lector(entrada));
t.start();

// Ciclo interactivo de escritura sobre el socket(enviando lineas de texto).
while (!((auxiliar=teclado.readLine()).equals("salir"))) {
            salida.println(auxiliar);
       }

// Cerrando todas las conexiones y flujos.
salida.close();
entrada.close();
teclado.close();
miCliente.close();
   }
}



Como te habras fijado, las anteriores clases son unicamente para un chat en linea de comandos... si lo quieres hacer con java swing... lo que podrias hacer es modificar la clase lector para que reciba una referencia a un textArea en el cual procedentemente Adjuntara el contenido que ha recibido... obviamente tendrias que modificar la clase Servidor y cliente para mandar la referencia de su respectivo JtextArea.... Fijate en los comentarios en mayuscula que estan en la clase lector.... con las 3 clases que te pase es muy sencillo pasarlo a interfaz grafica... tambien tendrias que modificar unas cuantas lineas de Cliente y servidor para saber cuando terminar la comunicacion, en las clases que te pase, se termina cuando alguno de los dos escribe "salir"


Suerte