Bonjour à tous,
Je poste ici le code d'un tchat en java que j'ai implémenté.
Partie cliente :
package graphic;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class ConnectionPanel extends JPanel {
private static final long serialVersionUID = 1L;
private JButton mButtonTchatter;
public ConnectionPanel() {
setLayout(new BorderLayout());
JPanel vEmptyPanel = new JPanel();
vEmptyPanel.setPreferredSize(new Dimension(200, 220));
mButtonTchatter = new JButton("Tchatter");
add(vEmptyPanel, BorderLayout.PAGE_START);
add(mButtonTchatter, BorderLayout.CENTER);
}
public void addListenerToButtonTchatter(ActionListener pListener) {
mButtonTchatter.addActionListener(pListener);
}
}
package graphic;
import graphic.ConnectionPanel;
import graphic.TchatPanel;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import bean.TchatMessage;
import net.TchatClient;
import net.TchatClient.StatusClient;
public class TchatMainWindow extends JFrame {
private static final long serialVersionUID = 1L;
private TchatPanel mTchatPanel;
private ConnectionPanel mConnectionPanel;
private Map<String,TchatWindow> mPrivatesTchatsWindows;
private TchatClient mTchatClient;
private String mClientNom;
public TchatMainWindow() {
setTitle("Connexion au Tchat");
setSize(550, 550);
initConnectionPanel();
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent pEvent) {
mTchatClient.setStatusClient(StatusClient.stopped);
for (TchatWindow vPrivateTchatWindowTmp : mPrivatesTchatsWindows.values()) {
vPrivateTchatWindowTmp.dispose();
}
}
});
mTchatClient = new TchatClient();
mPrivatesTchatsWindows = new HashMap<String, TchatWindow>();
setVisible(true);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
private void initConnectionPanel() {
setLayout(new FlowLayout());
mConnectionPanel = new ConnectionPanel();
mConnectionPanel.addListenerToButtonTchatter(new ActionListener() {
public void actionPerformed(ActionEvent e) {
mClientNom = JOptionPane.showInputDialog(TchatMainWindow.this, "Veuillez entrer un pseudo pour tchatter :");
mTchatClient.launchTchatClient(mClientNom);
checkAuthentificationClientStatus();
}
});
add(mConnectionPanel);
}
private void initTchatPanel() {
setTitle("Bienvenue " + mClientNom);
remove(mConnectionPanel);
setLayout(new BorderLayout(5, 5));
mTchatPanel = new TchatPanel();
mTchatPanel.addListenerToSendMessageButton(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
TchatMessage vTchatMessage = new TchatMessage();
vTchatMessage.setEmetteur(mClientNom);
vTchatMessage.setMessage(mTchatPanel.getMessageTextArea().getText());
mTchatClient.getMessagesToSend().add(vTchatMessage);
mTchatPanel.displayTchatMessageInTchatArea(vTchatMessage);
mTchatPanel.getMessageTextArea().setText("");
}
});
mTchatPanel.addListenerToClientsConnected(new MouseAdapter() {
public void mouseClicked(MouseEvent pEvent) {
if (pEvent.getClickCount() > 1) {
final String vSelectedDestinataire = new String((String) mTchatPanel.getClientsConnected().getSelectedValue());
if (vSelectedDestinataire != null
&& !mClientNom.equals(vSelectedDestinataire)
&& !mPrivatesTchatsWindows.containsKey(vSelectedDestinataire)) {
createPrivateTchatWindow(vSelectedDestinataire);
}
}
}
});
add(mTchatPanel, BorderLayout.CENTER);
mTchatPanel.updateUI();
checkTchatClientStatus();
}
private void createPrivateTchatWindow(final String pDestinataire) {
TchatWindow vTchatWindow = new TchatWindow();
vTchatWindow.setTchatClient(mTchatClient);
vTchatWindow.setClientNom(mClientNom);
vTchatWindow.setPrivateDestinataire(pDestinataire);
vTchatWindow.changeTitle();
vTchatWindow.displayClientsConnected();
vTchatWindow.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent pEvent) {
mPrivatesTchatsWindows.remove(pDestinataire);
}
});
mPrivatesTchatsWindows.put(pDestinataire, vTchatWindow);
}
private void displayMessagesReceived() {
Map<String, List<TchatMessage>> vMessagesReceived = mTchatClient.sortMessagesReceivedByEmetteur();
mTchatPanel.displayTchatsMessagesInTchatArea(vMessagesReceived.get("all"));
vMessagesReceived.remove("all");
for (String vDestinataireTmp : vMessagesReceived.keySet()) {
if (!mPrivatesTchatsWindows.containsKey(vDestinataireTmp)) {
createPrivateTchatWindow(new String(vDestinataireTmp));
}
mPrivatesTchatsWindows.get(vDestinataireTmp).getTchatPanel().displayTchatsMessagesInTchatArea(vMessagesReceived.get(vDestinataireTmp));
}
mTchatClient.getMessagesReceived().clear();
}
private void displayClientsConnected() {
List<String> vClientsConnected = new ArrayList<String>(mTchatClient.getClientsConnected());
mTchatPanel.displayClientsConnected(vClientsConnected);
for (String vDestinataireTmp : mPrivatesTchatsWindows.keySet()) {
if (!vClientsConnected.contains(vDestinataireTmp)) {
mPrivatesTchatsWindows.get(vDestinataireTmp).removePrivateDestinataire();
mPrivatesTchatsWindows.get(vDestinataireTmp).getTchatPanel().getButtonSendMessage().setEnabled(false);
}
}
}
private void checkAuthentificationClientStatus() {
Thread vThread = new Thread() {
public void run() {
while (true) {
if (mTchatClient.getStatusClient() == StatusClient.success) {
initTchatPanel();
return;
} else if (mTchatClient.getStatusClient() == StatusClient.connectionFailed) {
JOptionPane.showMessageDialog(TchatMainWindow.this, "Connection au serveur impossible !", "Erreur", JOptionPane.ERROR_MESSAGE);
return;
} else if (mTchatClient.getStatusClient() == StatusClient.authentificationFailed) {
JOptionPane.showMessageDialog(TchatMainWindow.this, "Ce nom existe deja ou est incorrect !", "Warning", JOptionPane.WARNING_MESSAGE);
return;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
vThread.start();
}
private void checkTchatClientStatus() {
Thread vThread = new Thread() {
public void run() {
while (mTchatClient.getStatusClient() == StatusClient.success) {
displayMessagesReceived();
displayClientsConnected();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (mTchatClient.getStatusClient() == StatusClient.connectionFailed) {
JOptionPane.showMessageDialog(TchatMainWindow.this, "Connection au serveur interrompue !", "Erreur", JOptionPane.ERROR_MESSAGE);
}
}
};
vThread.start();
}
}
package graphic;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import bean.TchatMessage;
public class TchatPanel extends JPanel {
private static final long serialVersionUID = 1L;
private JTextArea mTchatTextArea;
private JTextArea mMessageTextArea;
private JList mClientsConnected;
private JButton mButtonSendMessage;
public TchatPanel() {
setPreferredSize(new Dimension(500, 500));
setLayout(new BorderLayout(5, 5));
JPanel vPanelVerticalSeparation = new JPanel();
vPanelVerticalSeparation.setPreferredSize(new Dimension(5, 500));
/**/
JPanel vPanelLeft = new JPanel();
vPanelLeft.setPreferredSize(new Dimension(350, 450));
vPanelLeft.setLayout(new BorderLayout());
mTchatTextArea = new JTextArea();
mTchatTextArea.setEditable(false);
JScrollPane vScrollPaneTchatTextArea = new JScrollPane(mTchatTextArea);
vScrollPaneTchatTextArea.setPreferredSize(new Dimension(350, 350));
mMessageTextArea = new JTextArea();
JScrollPane vScrollPaneMessageTextArea = new JScrollPane(mMessageTextArea);
vScrollPaneMessageTextArea.setPreferredSize(new Dimension(350, 100));
vPanelLeft.add(vScrollPaneTchatTextArea, BorderLayout.CENTER);
vPanelLeft.add(vScrollPaneMessageTextArea, BorderLayout.PAGE_END);
/**/
JPanel vPanelRight = new JPanel();
vPanelRight.setPreferredSize(new Dimension(150, 450));
vPanelRight.setLayout(new BorderLayout());
mClientsConnected = new JList();
mClientsConnected.setPreferredSize(new Dimension(150, 350));
mButtonSendMessage = new JButton("Envoyer");
vPanelRight.add(mClientsConnected, BorderLayout.CENTER);
vPanelRight.add(mButtonSendMessage, BorderLayout.PAGE_END);
add(vPanelLeft, BorderLayout.CENTER);
add(vPanelRight, BorderLayout.LINE_END);
}
public void addListenerToClientsConnected(MouseListener pListener) {
mClientsConnected.addMouseListener(pListener);
}
public void displayTchatsMessagesInTchatArea(List<TchatMessage> pMessages) {
for (TchatMessage vMessageTmp : pMessages) {
displayTchatMessageInTchatArea(vMessageTmp);
}
}
public void displayTchatMessageInTchatArea(TchatMessage pMessage) {
mTchatTextArea.append(pMessage.getEmetteur() + " : " + pMessage.getMessage());
mTchatTextArea.append(System.getProperty("line.separator"));
mTchatTextArea.append(System.getProperty("line.separator"));
}
public void displayClientsConnected(List<String> pClientsConnected) {
DefaultListModel vModel = new DefaultListModel();
for (String vClientConnectedTmp : pClientsConnected) {
vModel.addElement(vClientConnectedTmp);
}
mClientsConnected.setModel(vModel);
}
public void addListenerToSendMessageButton(ActionListener pListener) {
mButtonSendMessage.addActionListener(pListener);
}
public JTextArea getMessageTextArea() {
return mMessageTextArea;
}
public JList getClientsConnected() {
return mClientsConnected;
}
public JButton getButtonSendMessage() {
return mButtonSendMessage;
}
}
package graphic;
import graphic.TchatPanel;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import bean.TchatMessage;
import net.TchatClient;
public class TchatWindow extends JFrame {
private static final long serialVersionUID = 1L;
private TchatPanel mTchatPanel;
private TchatClient mTchatClient;
private String mPrivateDestinataire;
private String mClientNom;
public TchatWindow() {
setSize(350, 350);
setLayout(new BorderLayout(5, 5));
mTchatPanel = new TchatPanel();
mTchatPanel.addListenerToSendMessageButton(new ActionListener() {
public void actionPerformed(ActionEvent e) {
TchatMessage vTchatMessage = new TchatMessage();
vTchatMessage.setEmetteur(mClientNom);
vTchatMessage.setDestinataire(mPrivateDestinataire);
vTchatMessage.setMessage(mTchatPanel.getMessageTextArea().getText());
mTchatClient.getMessagesToSend().add(vTchatMessage);
mTchatPanel.displayTchatMessageInTchatArea(vTchatMessage);
mTchatPanel.getMessageTextArea().setText("");
}
});
add(mTchatPanel, BorderLayout.CENTER);
setVisible(true);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public TchatPanel getTchatPanel() {
return mTchatPanel;
}
public void setTchatClient(TchatClient tchatClient) {
mTchatClient = tchatClient;
}
public void setClientNom(String clientNom) {
mClientNom = clientNom;
}
public void setPrivateDestinataire(String privateDestinataire) {
mPrivateDestinataire = privateDestinataire;
}
public void changeTitle() {
setTitle("Conversation avec " + mPrivateDestinataire);
}
public void displayClientsConnected() {
ArrayList<String> vClientsConnected = new ArrayList<String>();
vClientsConnected.add(mClientNom);
vClientsConnected.add(mPrivateDestinataire);
mTchatPanel.displayClientsConnected(vClientsConnected);
}
public void removePrivateDestinataire() {
ArrayList<String> vClientsConnected = new ArrayList<String>();
vClientsConnected.add(mClientNom);
mTchatPanel.displayClientsConnected(vClientsConnected);
}
}
package net;
import io.ConfigReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import bean.TchatMessage;
public class TchatClient {
private Socket mClientSocket;
private List<TchatMessage> mMessagesToSend;
private List<TchatMessage> mMessagesReceived;
private List<String> mClientsConnected;
private StatusClient mStatusClient;
public TchatClient() {
mClientsConnected = new ArrayList<String>();
mMessagesToSend = Collections.synchronizedList(new ArrayList<TchatMessage>());
mMessagesReceived = Collections.synchronizedList(new ArrayList<TchatMessage>());
}
private void connectToServer() throws Exception {
mStatusClient = StatusClient.none;
int vPortServeur = Integer.parseInt(ConfigReader.getInstance("client.properties").getProperty("serveur.port"));
String vIpServeur = ConfigReader.getInstance("client.properties").getProperty("serveur.ip");
mClientSocket = new Socket(vIpServeur, vPortServeur);
}
private boolean authentificateClientNameToServer(String pClientName) throws Exception {
ObjectOutputStream vObjectOutputStream = new ObjectOutputStream(mClientSocket.getOutputStream());
vObjectOutputStream.writeObject(pClientName);
vObjectOutputStream.flush();
ObjectInputStream vObjectInputStream = new ObjectInputStream(mClientSocket.getInputStream());
if ("OK".equals((String) vObjectInputStream.readObject())) {
return true;
}
return false;
}
private boolean checkClientName(String pClientName) {
if (pClientName == null || pClientName.equals("") || pClientName.equals("all")) {
return false;
}
return true;
}
private void echangeMessagesWithServeur() throws Exception {
ObjectOutputStream vObjectOutputStream = new ObjectOutputStream(mClientSocket.getOutputStream());
vObjectOutputStream.writeObject(mMessagesToSend);
vObjectOutputStream.flush();
mMessagesToSend.clear();
// On recupère les messages du serveur
ObjectInputStream vObjectInputStream = new ObjectInputStream(mClientSocket.getInputStream());
mMessagesReceived.addAll((List<TchatMessage>) vObjectInputStream.readObject());
// On recupère la liste des connectés dpuis le serveur
mClientsConnected = (List<String>) vObjectInputStream.readObject();
}
public Map<String, List<TchatMessage>> sortMessagesReceivedByEmetteur() {
HashMap<String, List<TchatMessage>> vResult = new HashMap<String, List<TchatMessage>>();
vResult.put("all", new ArrayList<TchatMessage>());
for (TchatMessage vTchatMessage : mMessagesReceived) {
if (vTchatMessage.getDestinataire() == null) {
vResult.get("all").add(vTchatMessage);
} else {
if (!vResult.containsKey(vTchatMessage.getEmetteur())) {
vResult.put(vTchatMessage.getEmetteur(), new ArrayList<TchatMessage>());
}
vResult.get(vTchatMessage.getEmetteur()).add(vTchatMessage);
}
}
return vResult;
}
public void launchTchatClient(final String pClientName) {
if (!checkClientName(pClientName)) {
mStatusClient = StatusClient.authentificationFailed;
return;
}
Thread vThread = new Thread() {
public void run() {
try {
connectToServer();
if (authentificateClientNameToServer(pClientName) ){
mStatusClient = StatusClient.success;
while (mStatusClient != StatusClient.stopped) {
echangeMessagesWithServeur();
Thread.sleep(1000);
}
} else {
mStatusClient = StatusClient.authentificationFailed;
}
} catch (Exception e) {
mStatusClient = StatusClient.connectionFailed;
e.printStackTrace();
} finally {
try {
if (mClientSocket != null) {
mClientSocket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
vThread.start();
}
public StatusClient getStatusClient() {
return mStatusClient;
}
public void setStatusClient(StatusClient pStatusClient) {
mStatusClient = pStatusClient;
}
public List<TchatMessage> getMessagesToSend() {
return mMessagesToSend;
}
public List<TchatMessage> getMessagesReceived() {
return mMessagesReceived;
}
public List<String> getClientsConnected() {
return mClientsConnected;
}
public enum StatusClient {
none, connectionFailed, success, authentificationFailed, stopped
}
}
Lanceur de la partie client :
import graphic.TchatMainWindow;
public class TchatWindowLauncher {
public static void main(String[] args) {
new TchatMainWindow();
}
}
Partie serveur :
package net;
import io.ConfigReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import bean.TchatMessage;
public class TchatServer {
public Map<String, List<TchatMessage>> mClientsTchatsMessages;
public void launchServer() {
mClientsTchatsMessages = Collections.synchronizedMap(new HashMap<String, List<TchatMessage>>());
try {
int vPortServeur = Integer.parseInt(ConfigReader.getInstance("serveur.properties").getProperty("serveur.port"));
ServerSocket vServerSocket = new ServerSocket(vPortServeur);
while(true) {
final Socket vSocket = vServerSocket.accept();
Thread vThread = new Thread() {
String vCurrentThreadClientNom = null;
public void run() {
try {
if ((vCurrentThreadClientNom = authentificateClient(vSocket)) != null) {
while (true) {
echangeMessagesWithClient(vSocket, vCurrentThreadClientNom);
}
}
} catch (Exception e) {
mClientsTchatsMessages.remove(vCurrentThreadClientNom);
e.printStackTrace();
} finally {
try {
vSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
vThread.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private String authentificateClient(Socket pSocket) throws Exception {
ObjectInputStream vObjectInputStream = new ObjectInputStream(pSocket.getInputStream());
String vClientName = (String) vObjectInputStream.readObject();
String vReponse = null;
if (mClientsTchatsMessages.containsKey(vClientName)) {
vReponse = "KO";
vClientName = null;
} else {
vReponse = "OK";
mClientsTchatsMessages.put(vClientName, new ArrayList<TchatMessage>());
}
ObjectOutputStream vObjectOutputStream = new ObjectOutputStream(pSocket.getOutputStream());
vObjectOutputStream.writeObject(vReponse);
vObjectOutputStream.flush();
return vClientName;
}
private void echangeMessagesWithClient(Socket pSocket, String vCurrentThreadClientNom) throws Exception {
ObjectInputStream vObjectInputStream = new ObjectInputStream(pSocket.getInputStream());
List<TchatMessage> vTchatMessagesReceived = (List<TchatMessage>) vObjectInputStream.readObject();
addMessageToClientsMessages(vTchatMessagesReceived);
ObjectOutputStream vObjectOutputStream = new ObjectOutputStream(pSocket.getOutputStream());
vObjectOutputStream.writeObject(mClientsTchatsMessages.get(vCurrentThreadClientNom));
vObjectOutputStream.flush();
vObjectOutputStream.writeObject(new ArrayList<String>(mClientsTchatsMessages.keySet()));
vObjectOutputStream.flush();
mClientsTchatsMessages.get(vCurrentThreadClientNom).clear();
}
private void addMessageToClientsMessages(List<TchatMessage> pTchatsMessages) {
for (TchatMessage vTchatMessageTmp : pTchatsMessages) {
try {
// Cas message prive
if (vTchatMessageTmp.getDestinataire() != null) {
mClientsTchatsMessages.get(vTchatMessageTmp.getDestinataire()).add(vTchatMessageTmp);
// Cas message general
} else {
for (String vClientConnectedTmp : mClientsTchatsMessages.keySet()) {
if (!vClientConnectedTmp.equals(vTchatMessageTmp.getEmetteur())) {
mClientsTchatsMessages.get(vClientConnectedTmp).add(vTchatMessageTmp);
}
}
}
} catch (NullPointerException e) {
// NOBREAK
e.printStackTrace();
}
}
}
}
Lanceur de la partie serveur :
import net.TchatServer;
public class TchatServerLauncher {
public static void main(String[] args) {
new TchatServer().launchServer();
}
}
Partie "communes" :
package bean;
import java.io.Serializable;
public class TchatMessage implements Serializable {
private static final long serialVersionUID = 1L;
private String mMessage;
private String mEmetteur;
private String mDestinataire;
public String getMessage() {
return mMessage;
}
public void setMessage(String pMessage) {
mMessage = pMessage;
}
public String getEmetteur() {
return mEmetteur;
}
public void setEmetteur(String pEmetteur) {
mEmetteur = pEmetteur;
}
public String getDestinataire() {
return mDestinataire;
}
public void setDestinataire(String pDestinataire) {
mDestinataire = pDestinataire;
}
}
package io;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class ConfigReader {
private Properties mProperties;
private static ConfigReader sInstance;
private ConfigReader(String pFilePropertiesName) throws IOException {
readConfig(pFilePropertiesName);
}
public static ConfigReader getInstance(String pFilePropertiesName) {
if (sInstance == null) {
try {
sInstance = new ConfigReader(pFilePropertiesName);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Impossible de lire le fichier " + pFilePropertiesName);
}
}
return sInstance;
}
private void readConfig(String pFilePropertiesName) throws IOException {
mProperties = new Properties();
FileInputStream vFileInputStream = new FileInputStream(pFilePropertiesName);
mProperties.load(vFileInputStream);
vFileInputStream.close();
}
public String getProperty(String pKey) {
return mProperties.getProperty(pKey);
}
public Properties getProperties() {
return mProperties;
}
public static String getClasspathResource(String pResourcePath) {
String vPath = pResourcePath;
if (vPath.startsWith("/")) {
vPath = vPath.substring(1);
}
try {
return Thread.currentThread().getContextClassLoader().getResource(vPath).getPath().replaceAll("%20", " ");
} catch (Exception pException) {
throw new RuntimeException("La ressource " + pResourcePath + " n est pas dans le classpath !");
}
}
}
Pour fonctionner le client a besoin d un fichier "client.properties" "dans le répertoire d execution" avec les proprietes suivantes
serveur.port=3500 serveur.ip=localhost
Pour fonctionner le serveur a besoin d un fichier "serveur.properties" "dans le répertoire d execution" avec les proprietes suivantes
serveur.port=3500
J'espère que je n'ai rien oublié, n'oubliez pas de mettre les classes dans les bons packages :)
Bonne chance,
Niroken

