Boa Tarde Pessoal.
Vejo as vezes o pessoal pedindo auxilio para criação de um chat com interface gráfica.
Estou postando este para contribuir com quem tem dificuldades.
A Base de tudo peguei daqui http://mballem.wordpress.com/2011/02/04/chat-multiusuario-com-socket/ e implementei a parte gráfica.
É multi-usuário.
Não cheguei a mexer muito no código, e também meu forte não é swing e sim web.
Mas acho que mesmo assim será útil para o pessoal que está aprendendo.
Classe Servidor:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
public class ServidorSocket extends Thread {
private static Map<String, PrintStream> MAP_CLIENTES;
private Socket conexao;
private String nomeCliente;
private static List<String> LISTA_DE_NOMES = new ArrayList<String>();
public ServidorSocket(Socket socket) {
this.conexao = socket;
}
public boolean armazena(String newName) {
for (int i = 0; i < LISTA_DE_NOMES.size(); i++) {
if (LISTA_DE_NOMES.get(i).equals(newName))
return true;
}
LISTA_DE_NOMES.add(newName);
return false;
}
public void remove(String oldName) {
for (int i = 0; i < LISTA_DE_NOMES.size(); i++) {
if (LISTA_DE_NOMES.get(i).equals(oldName))
LISTA_DE_NOMES.remove(oldName);
}
}
public static void main(String args[]) {
MAP_CLIENTES = new HashMap<String, PrintStream>();
try {
ServerSocket server = new ServerSocket(5555);
System.out.println("ServidorSocket rodando na porta 5555");
while (true) {
Socket conexao = server.accept();
Thread t = new ServidorSocket(conexao);
t.start();
}
} catch (IOException e) {
System.out.println("IOException: " + e);
}
}
public void run() {
try {
BufferedReader entrada = new BufferedReader(new InputStreamReader(this.conexao.getInputStream()));
PrintStream saida = new PrintStream(this.conexao.getOutputStream());
this.nomeCliente = entrada.readLine();
if (armazena(this.nomeCliente)) {
saida.println("Este nome ja existe! Conecte novamente com outro Nome.");
this.conexao.close();
return;
} else {
//mostra o nome do cliente conectado ao servidor
System.out.println(this.nomeCliente + " : Conectado ao Servidor!");
//Quando o cliente se conectar recebe todos que estão conectados
saida.println("Conectados: " + LISTA_DE_NOMES.toString());
}
if (this.nomeCliente == null) {
return;
}
//adiciona os dados de saida do cliente no objeto MAP_CLIENTES
//A chave será o nome e valor o printstream
MAP_CLIENTES.put(this.nomeCliente, saida);
String[] msg = entrada.readLine().split(":");
while (msg != null && !(msg[0].trim().equals(""))) {
send(saida, " escreveu: ", msg);
msg = entrada.readLine().split(":");
}
System.out.println(this.nomeCliente + " saiu do bate-papo!");
String[] out = {" do bate-papo!"};
send(saida, " saiu", out);
remove(this.nomeCliente);
MAP_CLIENTES.remove(this.nomeCliente);
this.conexao.close();
} catch (IOException e) {
System.out.println("Falha na Conexao... .. ." + " IOException: " + e);
}
}
/**
* Se o array da msg tiver tamanho igual a 1, então envia para todos
* Se o tamanho for 2, envia apenas para o cliente escolhido
*/
public void send(PrintStream saida, String acao, String[] msg) {
out:
for (Map.Entry<String, PrintStream> cliente : MAP_CLIENTES.entrySet()) {
PrintStream chat = cliente.getValue();
if (chat != saida) {
if (msg.length == 1) {
chat.println(this.nomeCliente + acao + msg[0]);
} else {
if (msg[1].equalsIgnoreCase(cliente.getKey())) {
chat.println(this.nomeCliente + acao + msg[0]);
break out;
}
}
}
}
}
}
Classe Cliente:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ClienteSocket extends JFrame implements ActionListener {
// parte que controla a recepção de mensagens do cliente
private Socket conexao;
Socket socket ;
JTextArea areaTexto;
JTextField msg;
JButton btn;
JLabel rotulo;
PrintStream saida;
BufferedReader entrada;
public ClienteSocket() {
super("Chat");
Container tela = getContentPane();
BorderLayout layout = new BorderLayout();
tela.setLayout(layout);
rotulo = new JLabel("");
btn = new JButton("Enviar");
btn.addActionListener(this);
msg = new JTextField(20);
areaTexto = new JTextArea(15, 30);
JScrollPane painelRolagem = new JScrollPane(areaTexto);
painelRolagem.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
painelRolagem.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JPanel pSuperior = new JPanel();
pSuperior.setLayout(new FlowLayout(FlowLayout.LEFT));
pSuperior.add(rotulo);
JPanel pCentro = new JPanel();
pCentro.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 0));
pCentro.add(painelRolagem);
JPanel pInferior = new JPanel();
pInferior.setLayout(new FlowLayout(FlowLayout.RIGHT));
pInferior.add(msg);
pInferior.add(btn);
tela.add(BorderLayout.NORTH, pSuperior);
tela.add(BorderLayout.CENTER, pCentro);
tela.add(BorderLayout.SOUTH, pInferior);
pack();
setVisible(true);
}
void executa()
{
try {
socket = new Socket("127.0.0.1", 5555);
//Instancia do atributo saida, obtem os objetos que permitem controlar o fluxo de comunicação
saida = new PrintStream(socket.getOutputStream());
String meuNome = JOptionPane.showInputDialog("Digite seu nome ");
rotulo.setText("Bem Vindo " + meuNome);
//envia o nome digitado para o servidor
saida.println(meuNome.toUpperCase());
//instancia a thread para ip e porta conectados e depois inicia ela
Recebedor r = new Recebedor(socket.getInputStream());
new Thread(r).start();
} catch (IOException e) {
System.out.println("Falha na Conexao... .. ." + " IOException: " + e);
}
}
public static void main(String[] args) {
ClienteSocket cliente = new ClienteSocket();
WindowListener ls = new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
};
cliente.addWindowListener(ls);
cliente.executa();
}
// execução da thread
public void run()
{
try {
//recebe mensagens de outro cliente através do servidor
BufferedReader entrada = new BufferedReader(new InputStreamReader(this.conexao.getInputStream()));
//cria variavel de mensagem
String msg;
while (true)
{
// pega o que o servidor enviou
msg = entrada.readLine();
//se a mensagem contiver dados, passa pelo if, caso contrario cai no break e encerra a conexao
if (msg == null) {
System.out.println("Conexão encerrada!");
System.exit(0);
}
areaTexto.append(msg + "\n");
}
} catch (IOException e) {
// caso ocorra alguma exceção de E/S, mostra qual foi.
System.out.println("Ocorreu uma Falha... .. ." + " IOException: " + e);
}
}
class Recebedor implements Runnable {
private InputStream servidor;
public Recebedor(InputStream servidor) {
this.servidor = servidor;
}
@Override
public void run() {
try {
//recebe mensagens de outro cliente através do servidor
entrada = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//cria variavel de mensagem
String msg;
while (true)
{
// pega o que o servidor enviou
msg = entrada.readLine();
//se a mensagem contiver dados, passa pelo if, caso contrario cai no break e encerra a conexao
if (msg == null) {
System.out.println("Conexão encerrada!");
System.exit(0);
}
areaTexto.append(msg + "\n");
}
} catch (IOException e) {
// caso ocorra alguma exceção de E/S, mostra qual foi.
System.out.println("Ocorreu uma Falha... .. ." + " IOException: " + e);
}
}
}
@Override
public void actionPerformed(ActionEvent event) {
Object fonte = event.getSource();
if (fonte == btn) //Envia informacao pelo socket
{
String text = msg.getText();
saida.println(text);
msg.setText(new String("")); //recebe do servidor
}
}
}
Bom é isso.
Até mais !