Documentos de Académico
Documentos de Profesional
Documentos de Cultura
ELECTRÓNICA
Escuela de Ingeniería de Sistemas e Informática
1
Junior Arturo Barboza Vidarte 1614216
2
Junior Arturo Barboza Vidarte 1614216
3
Junior Arturo Barboza Vidarte 1614216
Luego de que los clientes envíen y reciban múltiples mensajes se tiene algo
como lo siguiente.
4
Junior Arturo Barboza Vidarte 1614216
5
Junior Arturo Barboza Vidarte 1614216
6
Junior Arturo Barboza Vidarte 1614216
7
Junior Arturo Barboza Vidarte 1614216
Programa Servidor
1. HiloCliente.java:
/*
* Practica Calificada 2
* Junior Barboza Vidarte
* Mayo 2019
*/
package chatservidor;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.LinkedList;
/**
* Los objetos de esta clase son hilos que al correr escuchan
* permanentemente lo que los clientes puedan decir, hay un hilo para
* cada cliente que se conecta al servidor y dicho hilo tiene como
* función escuchar solamente a ese cliente.
* @author JuniorBarboza
*/
public class HiloCliente extends Thread{
/**
* Socket que se utiliza para comunicarse con el cliente.
*/
private final Socket socket;
/**
* Stream con el que se envían objetos al servidor.
*/
private ObjectOutputStream objectOutputStream;
/**
* Stream con el que se reciben objetos del servidor.
*/
private ObjectInputStream objectInputStream;
/**
* Servidor al que pertenece este hilo.
*/
private final Servidor server;
/**
* Identificador único del cliente con el que este hilo se
*comunica.
*/
private String identificador;
/**
* Variable booleana que almacena verdadero cuando este hilo está
* escuchando lo que el cliente que atiende está diciendo.
*/
private boolean escuchando;
/**
* Método constructor de la clase hilo cliente.
* @param socket
* @param server
*/
8
Junior Arturo Barboza Vidarte 1614216
this.server=server;
this.socket = socket;
try {
objectOutputStream = new
objectOutputStream(socket.getOutputStream());
objectInputStream =
new ObjectInputStream(socket.getInputStream());
} catch (IOException ex) {
System.err.println("Error en la inicialización del
ObjectOutputStream y el ObjectInputStream");
}
}
/**
* Método encargado de cerrar el socket con el que se esta
* comunicando.
*/
public void desconnectar() {
try {
socket.close();
escuchando=false;
} catch (IOException ex) {
System.err.println("Error al cerrar el socket de
comunicación con el cliente.");
}
}
/**
* Sobreescritura del método de Thread, es acá en donde se monta
* el ciclo infinito.
*/
public void run() {
try{
escuchar();
} catch (Exception ex) {
System.err.println("Error al llamar al método readLine del
hilo del cliente.");
}
desconnectar();
}
/**
* Método que constantemente está escuchando todo lo que es
* enviado por el cliente que se comunica con él.
*/
public void escuchar(){
escuchando=true;
while(escuchando){
try {
Object aux=objectInputStream.readObject();
if(aux instanceof LinkedList){
ejecutar((LinkedList<String>)aux);
}
} catch (Exception e) {
System.err.println("Error al leer lo enviado por el
cliente.");
}
}
}
/**
* Método que realiza determinadas acciones dependiendo de lo que
* el socket haya recibido y lo que este le envie el método, en
* él se manejan una serie de códigos.
9
Junior Arturo Barboza Vidarte 1614216
* @param lista
*/
public void ejecutar(LinkedList<String> lista){
// 0 - El primer elemento de la lista es siempre el tipo
String tipo=lista.get(0);
switch (tipo) {
case "SOLICITUD_CONEXION":
// 1 - Identificador propio del nuevo usuario
confirmarConexion(lista.get(1));
break;
case "SOLICITUD_DESCONEXION":
// 1 - Identificador propio del nuevo usuario
confirmarDesConexion();
break;
case "MENSAJE":
// 1 - Cliente emisor
// 2 - Cliente receptor
// 3 - Mensaje
String destinatario=lista.get(2);
server.clientes
.stream()
.filter(h ->
(destinatario.equals(h.getIdentificador())))
.forEach((h) -> h.enviarMensaje(lista));
break;
default:
break;
}
}
/**
* Método para enviar un mensaje al cliente atraves del socket.
* @param lista
*/
private void enviarMensaje(LinkedList<String> lista){
try {
objectOutputStream.writeObject(lista);
} catch (Exception e) {
System.err.println("Error al enviar el objeto al
cliente.");
}
}
/**
* Una vez conectado un nuevo cliente, este método notifica a
* todos los clientes conectados que hay un nuevo cliente para que
* lo agreguen a sus contactos.
* @param identificador
*/
private void confirmarConexion(String identificador) {
Servidor.correlativo++;
this.identificador=Servidor.correlativo+" - "+identificador;
LinkedList<String> lista=new LinkedList<>();
lista.add("CONEXION_ACEPTADA");
lista.add(this.identificador);
lista.addAll(server.getUsuariosConectados());
enviarMensaje(lista);
server.agregarLog("\nNuevo cliente: "+this.identificador);
// enviar a todos los clientes el nombre del nuevo usuario
// conectado excepto a él mismo
LinkedList<String> auxLista=new LinkedList<>();
auxLista.add("NUEVO_USUARIO_CONECTADO");
auxLista.add(this.identificador);
10
Junior Arturo Barboza Vidarte 1614216
server.clientes
.stream()
.forEach(cliente -> cliente.enviarMensaje(auxLista));
server.clientes.add(this);
}
/**
* Método que retorna el identificador único del cliente dentro
* del chat.
* @return
*/
public String getIdentificador() {
return identificador;
}
/**
* Método que se invoca cuando el usuario al que atiende este
* hilo decide desconectarse, si eso pasa, se tiene que informar
* al resto de los usuarios que ya no pueden enviarle mensajes y
* que deben quitarlo de su lista de contactos.
*/
private void confirmarDesConexion() {
LinkedList<String> auxLista=new LinkedList<>();
auxLista.add("USUARIO_DESCONECTADO");
auxLista.add(this.identificador);
server.agregarLog("\nEl cliente \""+this.identificador+"\" se
ha desconectado.");
this.desconnectar();
for(int i=0;i<server.clientes.size();i++){
if(server.clientes.get(i).equals(this)){
server.clientes.remove(i);
break;
}
}
server.clientes
.stream()
.forEach(h -> h.enviarMensaje(auxLista));
}
}
11
Junior Arturo Barboza Vidarte 1614216
2. Servidor.java:
/*
* Practica Calificada 2
* Junior Barboza Vidarte
* Mayo 2019
*/
package chatservidor;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import javax.swing.JOptionPane;
/**
* Clase en la que se maneja la comunicación del lado del servidor.
* @author JuniorBarboza
*/
public class Servidor extends Thread{
/**
* Socket servidor que tiene como principal función escuchar
* cuando los clientes se conectan para incluirlos en el chat.
*/
private ServerSocket serverSocket;
/**
* Lista de todos los hilos de comunicación, para cada cliente se
* instancia uno de estos hilos ya que cada hilo está escuchando
* permanentemente lo que dicho cliente envía al servidor.
*/
LinkedList<HiloCliente> clientes;
/**
* Variable que almacena la ventana que gestiona la interfaz
* gráfica del servidor.
*/
private final VentanaS ventana;
/**
* Variable que almacena el puerto que el servidor usará para
* escuchar.
*/
private final String puerto;
/**
* Correlativo para diferenciar a los múltiples clientes que se
* conectan, si se conectaran, por ejemplo, dos usuarios con el
* mismo nombre, se podrían diferenciar por este correlativo.
*/
static int correlativo;
/**
* Constructor del servidor.
* @param puerto
* @param ventana
*/
public Servidor(String puerto, VentanaS ventana) {
correlativo=0;
this.puerto=puerto;
this.ventana=ventana;
clientes=new LinkedList<>();
this.start();
}
12
Junior Arturo Barboza Vidarte 1614216
/**
* Método sobre el que corre el bucle infinito que tiene como
* función escuchar permenentemente en espera de conexiones de
* nuevos clientes.
*/
public void run() {
try {
serverSocket = new ServerSocket(Integer.valueOf(puerto));
ventana.addServidorIniciado();
while (true) {
HiloCliente h;
Socket socket;
socket = serverSocket.accept();
System.out.println("Nueva conexion entrante:"+socket);
h=new HiloCliente(socket, this);
h.start();
}
} catch (Exception e) {
JOptionPane.showMessageDialog(ventana,
"El servidor no se ha podido
iniciar, \n"
+ "puede que haya ingresado
un puerto
incorrecto.\n"
+ "Esta aplicación se
cerrará.");
System.exit(0);
}
}
/**
* Ciclo que devuelve una lista con los identificadores de todos
* los clientes conectados.
* @return
*/
LinkedList<String> getUsuariosConectados() {
LinkedList<String>usuariosConectados=new LinkedList<>();
clientes.stream().forEach(c ->
usuariosConectados.add(c.getIdentificador()));
return usuariosConectados;
}
/**
* Método que agrega una linea al log de la interfaz gráfica del
* servidor.
* @param texto
*/
void agregarLog(String texto) {
ventana.agregarLog(texto);
}
}
13
Junior Arturo Barboza Vidarte 1614216
3. VentanaS.java
/*
* Practica Calificada 2
* Junior Barboza Vidarte
* Mayo 2019
*/
package chatservidor;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* Clase que gestiona la interfaz gráfica del servidor, que muestra un
* log de las conexiones y desconexiones de los diferentes clientes,
* así como un mensaje de confirmación de que el servidor está
* corriendo correctamente.
* @author JuniorBarboza
*/
public class VentanaS extends javax.swing.JFrame {
private final String DEFAULT_PORT="10101";
private final Servidor servidor;
/**
* Creates new form VentanaS
*/
public VentanaS() {
initComponents();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String puerto=getPuerto();
servidor=new Servidor(puerto, this);
}
/**
* This method is called from within the constructor to initialize
* the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants
.EXIT_ON_CLOSE);
setTitle("Servidor");
txtClientes.setColumns(20);
txtClientes.setRows(5);
txtClientes.setBorder(javax.swing.BorderFactory
.createTitledBorder("Log del servidor"));
txtClientes.setCursor(newjava.awt.Cursor
(java.awt.Cursor.TEXT_CURSOR));
14
Junior Arturo Barboza Vidarte 1614216
jScrollPane1.setViewportView(txtClientes);
pack();
setLocationRelativeTo(null);
}// </editor-fold>
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel
//setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay
* with the default look and feel.
* For details see
* http://download.oracle.com/javase/tutorial/uiswing/
* lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info :
javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(
info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(VentanaS
.class.getName()).log(java.util.logging.Level.SEVERE,
null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(VentanaS
.class.getName()).log(java.util.logging.Level.SEVERE,
null, ex);
15
Junior Arturo Barboza Vidarte 1614216
/**
* Método que agrega una línea de texto al log.
* @param texto
*/
void agregarLog(String texto) {
txtClientes.append(texto);
}
/**
* Método que abre una ventana para que el usuario ingrese el
* puerto que desea utilizar para que el servidor escuche.
* @return
*/
private String getPuerto() {
String p=DEFAULT_PORT;
JTextField puerto = new JTextField(20);
puerto.setText(p);
JPanel myPanel = new JPanel();
myPanel.setLayout(new GridLayout(2, 1));
myPanel.add(new JLabel("Puerto de la conexión:"));
myPanel.add(puerto);
int result = JOptionPane.showConfirmDialog(null, myPanel,
"Configuraciones de la comunicación",
JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
p=puerto.getText();
}else{
System.exit(0);
}
return p;
}
/**
* Método que agrega un mensaje de confirmación al log cuando el
* servidor está corriendo correctamente.
*/
void addServidorIniciado() {
txtClientes.setText("Inicializando el servidor... [Ok].");
}
}
16
Junior Arturo Barboza Vidarte 1614216
Programa Cliente
1. Cliente.java:
/*
* Practica Calificada 2
* Junior Barboza Vidarte
* Mayo 2019
*/
package chatcliente;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.LinkedList;
import javax.swing.JOptionPane;
/**
* Clase en la que se maneja la comunicación del lado del cliente.
* @author JuniorBarboza
*/
public class Cliente extends Thread {
/**
* Socket utilizado para comunicarse con el servidor.
*/
private Socket socket;
/**
* Stream utilizado para el envío de objetos al servidor.
*/
private ObjectOutputStream objectOutputStream;
/**
* Stream utilizado para el envío de objetos al servidor.
*/
private ObjectInputStream objectInputStream;
/**
* Ventana utilizada para la interfaz gráfica del cliente.
*/
private final VentanaC ventana;
/**
* Identificador único del cliente dentro del chat.
*/
private String identificador;
/**
* Variable que determina si el cliente escucha o no al servidor,
* una vez que se arranca el hilo de comunicación del cliente.
*/
private boolean escuchando;
/**
* Variable que almacena la IP del host en el que se ejecuta el
* servidor.
*/
private final String host;
/**
* Varable que almacena el puerto por el cual el servidor escucha
* las conexiones de los diversos clientes.
*/
private final int puerto;
/**
* Constructor de la clase cliente.
* @param ventana
17
Junior Arturo Barboza Vidarte 1614216
* @param host
* @param puerto
* @param nombre
*/
Cliente(VentanaC ventana, String host, Integer puerto, String
nombre) {
this.ventana=ventana;
this.host=host;
this.puerto=puerto;
this.identificador=nombre;
escuchando=true;
this.start();
}
/**
* Método run del hilo de comunicación del lado del cliente.
*/
public void run (){
try {
socket=new Socket(host, puerto);
objectOutputStream=new ObjectOutputStream(socket
.getOutputStream());
objectInputStream=new ObjectInputStream(socket
.getInputStream());
System.out.println("Conexion exitosa!!!!");
this.enviarSolicitudConexion(identificador);
this.escuchar();
} catch (UnknownHostException ex) {
JOptionPane.showMessageDialog(ventana, "Conexión rehusada,
servidor desconocido, \n"
+ "puede que haya ingresado
una ip incorrecta\n"
+ "o que el servidor no este
corriendo.\n"
+ "Esta aplicación se
cerrará.");
System.exit(0);
} catch (IOException ex) {
JOptionPane.showMessageDialog(ventana, "Conexión rehusada,
error de Entrada/Salida,\n"
+ "puede que haya ingresado
una ip o un puerto\n"
+ "incorrecto, o que el
servidor no este
corriendo.\n"
+ "Esta aplicación se
cerrará.");
System.exit(0);
}
/**
* Método que cierra el socket y los streams de comunicación.
*/
public void desconectar(){
try {
objectOutputStream.close();
objectInputStream.close();
socket.close();
escuchando=false;
} catch (Exception e) {
18
Junior Arturo Barboza Vidarte 1614216
/*
* Método que escucha constantemente lo que el servidor dice.
*/
public void escuchar() {
try {
while (escuchando) {
Object aux = objectInputStream.readObject();
if (aux != null) {
if (aux instanceof LinkedList) {
//Si se recibe una LinkedList entonces se
//procesa
ejecutar((LinkedList<String>)aux);
} else {
System.err.println("Se recibió un Objeto
desconocido a través del
socket");
}
} else {
System.err.println("Se recibió un null a través
del socket");
}
}
} catch (Exception e) {
JOptionPane.showMessageDialog(ventana, "La comunicación
con el servidor se ha\n"
+ "perdido, este chat
tendrá que finalizar.\n"
+ "Esta aplicación se
cerrará.");
System.exit(0);
}
}
19
Junior Arturo Barboza Vidarte 1614216
/**
* Método que ejecuta una serie de instrucciones dependiendo del
* mensaje que el cliente reciba del servidor
* @param lista
*/
public void ejecutar(LinkedList<String> lista){
// 0 - El primer elemento de la lista es siempre el tipo
String tipo=lista.get(0);
switch (tipo) {
case "CONEXION_ACEPTADA":
// 1 - Identificador propio del nuevo usuario
// 2 .. n - Identificadores de los clientes conectados
// actualmente
identificador=lista.get(1);
ventana.sesionIniciada(identificador);
for(int i=2;i<lista.size();i++){
ventana.addContacto(lista.get(i));
}
break;
case "NUEVO_USUARIO_CONECTADO":
// 1 - Identificador propio del cliente que se
// acaba de conectar
ventana.addContacto(lista.get(1));
break;
case "USUARIO_DESCONECTADO":
// 1 - Identificador propio del cliente que se
// acaba de conectar
ventana.eliminarContacto(lista.get(1));
break;
case "MENSAJE":
// 1 - Cliente emisor
// 2 - Cliente receptor
// 3 - Mensaje
ventana.addMensaje(lista.get(1), lista.get(3));
break;
default:
break;
}
}
/**
* Al conectarse el cliente debe solicitar al servidor que lo
* agregue a la lista de clientes, para ello se ejecuta este
* método.
* @param identificador
*/
private void enviarSolicitudConexion(String identificador) {
LinkedList<String> lista=new LinkedList<>();
//tipo
lista.add("SOLICITUD_CONEXION");
//cliente solicitante
lista.add(identificador);
try {
objectOutputStream.writeObject(lista);
} catch (IOException ex) {
System.out.println("Error de lectura y escritura al enviar
mensaje al servidor.");
}
}
/**
* Cuando se cierra una ventana cliente, se debe notificar al
* servidor que el cliente se ha desconectado para que lo elimine
20
Junior Arturo Barboza Vidarte 1614216
21
Junior Arturo Barboza Vidarte 1614216
2. VentanaC.java:
/*
* Practica Calificada 2
* Junior Barboza Vidarte
* Mayo 2019
*/
package chatcliente;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* Clase que maneja la interfaz gráfica del cliente.
* @author JuniorBarboza
*/
public class VentanaC extends javax.swing.JFrame {
/**
* Constructor de la ventana.
*/
public VentanaC() {
initComponents();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String ip_puerto_nombre[]=getIP_Puerto_Nombre();
String ip=ip_puerto_nombre[0];
String puerto=ip_puerto_nombre[1];
String nombre=ip_puerto_nombre[2];
cliente=new Cliente(this, ip, Integer.valueOf(puerto),nombre);
}
/**
* This method is called from within the constructor to initialize
* the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants
.EXIT_ON_CLOSE)
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt){
formWindowClosing(evt);
}
});
22
Junior Arturo Barboza Vidarte 1614216
txtHistorial.setColumns(20);
txtHistorial.setRows(5);
jScrollPane2.setViewportView(txtHistorial);
btnEnviar.setText("Enviar");
btnEnviar.addActionListener(new java.awt.event.
ActionListener() {
public void actionPerformed(java.awt.event.
ActionEvent evt) {
btnEnviarActionPerformed(evt);
}
});
jLabel1.setText("Destinatario");
23
Junior Arturo Barboza Vidarte 1614216
.addGroup(layout.createParallelGroup(javax.swing
.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(cmbContactos, javax.swing
.GroupLayout.PREFERRED_SIZE, javax
.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout
.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing
.GroupLayout.Alignment.BASELINE)
.addComponent(btnEnviar)
.addComponent(txtMensaje, javax.swing.GroupLayout
.PREFERRED_SIZE, javax.swing
.GroupLayout.DEFAULT_SIZE, javax
.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(47, Short.MAX_VALUE))
);
pack();
setLocationRelativeTo(null);
}// </editor-fold>
/**
* Cuando la ventana se este cerrando se notifica al servidor que
* el cliente se ha desconectado, por lo que los demás clientes
* del chat no podrán enviarle más mensajes.
* @param evt
*/
private void formWindowClosing(java.awt.event.WindowEvent evt) {
cliente.confirmarDesconexion();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel
24
Junior Arturo Barboza Vidarte 1614216
/**
* Constante que almacena el puerto por defecto para la aplicación.
*/
private final String DEFAULT_PORT="10101";
/**
* Constante que almacena la IP por defecto (localhost) para el
* servidor.
*/
private final String DEFAULT_IP="127.0.0.1";
25
Junior Arturo Barboza Vidarte 1614216
/**
* Constante que almacena el cliente, con el cual se gestiona la
* comunicación con el servidor.
*/
private final Cliente cliente;
/**
* Agrega un contacto al JComboBox de contactos.
* @param contacto
*/
void addContacto(String contacto) {
cmbContactos.addItem(contacto);
}
/**
* Agrega un nuevo mensaje al historial de la conversación.
* @param emisor
* @param mensaje
*/
void addMensaje(String emisor, String mensaje) {
txtHistorial.append("##### "+emisor + " ##### : \n" +
mensaje+"\n");
}
/**
* Se configura el título de la ventana para una nueva sesión.
* @param identificador
*/
void sesionIniciada(String identificador) {
this.setTitle(" --- "+identificador+" --- ");
}
/**
* Método que abre una ventana para que el usuario ingrese la IP
* del host en el que corre el servidor, el puerto con el que
* escucha y el nombre con el que quiere participar en el chat.
* @return
*/
private String[] getIP_Puerto_Nombre() {
String s[]=new String[3];
s[0]=DEFAULT_IP;
s[1]=DEFAULT_PORT;
JTextField ip = new JTextField(20);
JTextField puerto = new JTextField(20);
JTextField usuario = new JTextField(20);
ip.setText(DEFAULT_IP);
puerto.setText(DEFAULT_PORT);
usuario.setText("Usuario");
JPanel myPanel = new JPanel();
myPanel.setLayout(new GridLayout(3, 2));
myPanel.add(new JLabel("IP del Servidor:"));
myPanel.add(ip);
myPanel.add(new JLabel("Puerto de la conexión:"));
myPanel.add(puerto);
myPanel.add(new JLabel("Escriba su nombre:"));
myPanel.add(usuario);
int result = JOptionPane.showConfirmDialog(null, myPanel,
"Configuraciones de la comunicación",
JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
s[0]=ip.getText();
s[1]=puerto.getText();
s[2]=usuario.getText();
}else{
System.exit(0);
26
Junior Arturo Barboza Vidarte 1614216
}
return s;
}
/**
* Método que elimina cierto cliente de la lista de contactos,
* este se llama cuando cierto usuario cierra sesión.
* @param identificador
*/
void eliminarContacto(String identificador) {
for (int i = 0; i < cmbContactos.getItemCount(); i++) {
if(cmbContactos.getItemAt(i).toString().equals(identificador)){
cmbContactos.removeItemAt(i);
return;
}
}
}
}
27