diff --git a/README.md b/README.md index cd5d004..ec3acf2 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -devoir-java +## Chat Application - 2017/03 +This is my first Java project basing on Client-Server structure (with sockets), realised with 3 of my University colleagues. diff --git a/bin/client/Client.class b/bin/client/Client.class index 266b8fc..c05f89f 100644 Binary files a/bin/client/Client.class and b/bin/client/Client.class differ diff --git a/src/View/ClientUI.java b/src/View/ClientUI.java index 5603b15..1eac9d0 100644 --- a/src/View/ClientUI.java +++ b/src/View/ClientUI.java @@ -1,5 +1,6 @@ package View; +import java.util.ArrayList; import java.util.Observable; import java.util.Observer; @@ -9,16 +10,13 @@ import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.awt.image.BufferedImage; import java.io.IOException; -import javax.imageio.ImageIO; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; -import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; @@ -28,8 +26,8 @@ import utils.ImagePanel; /** - * ClientUI - * @author Corentin + * ClientUI is the user interface. Each ClientUI create and observe a new Client. + * @author Corentin, Raphael */ public class ClientUI extends JFrame implements Observer{ @@ -41,6 +39,7 @@ public class ClientUI extends JFrame implements Observer{ public ClientUI(Client client) throws IOException { this.client = client; + // Client is observed by ClientUI client.addObserver(this); createUI(); } @@ -49,7 +48,6 @@ public ClientUI(Client client) throws IOException { * @throws IOException */ private void createUI() throws IOException { - // TODO :: supprimer la mapView de la Frame à part et l'intégrer à ClientUI JFrame map = new MapView(this.client); ImagePanel mapPanel = (ImagePanel) map.getContentPane(); mapPanel.setBorder(BorderFactory.createLineBorder(Color.black)); @@ -66,11 +64,6 @@ private void createUI() throws IOException { add(box, BorderLayout.SOUTH); add(new JScrollPane(boxUsers), BorderLayout.EAST); inputTextField = new JTextField(); - for(int i=0; i<5;i++){ - JLabel userName = new JLabel("user"+i); - boxUsers.add(userName); - } - //JTextArea usersList = new JTextArea("users List"); sendButton = new JButton("Send"); sendButton.setBackground(new Color(59,89,182)); sendButton.setForeground(Color.WHITE); @@ -79,9 +72,8 @@ private void createUI() throws IOException { inputTextField.setForeground(Color.BLACK); box.add(inputTextField); box.add(sendButton); - //boxUsers.add(usersList); - // Action for the inputTextField and the goButton + // Send text line message to client ActionListener sendListener = new ActionListener() { public void actionPerformed(ActionEvent e) { String str = inputTextField.getText(); @@ -110,6 +102,17 @@ public void update(Observable o, Object arg) { public void run() { textArea.append(arg.toString()); textArea.append("\n"); + boxUsers.removeAll(); + JLabel titre = new JLabel("Liste des utilisateurs connectés : "); + boxUsers.add(titre); + ArrayList clientsList = client.getClientsData(); + for (Client c : clientsList) { + if(c != null){ + JLabel userName = new JLabel(c.getName()); + boxUsers.add(userName); + } + } + System.out.println("ClientUI update : " + clientsList); } }); } diff --git a/src/View/GridView.java b/src/View/GridView.java index dab0ba0..9f903db 100644 --- a/src/View/GridView.java +++ b/src/View/GridView.java @@ -31,20 +31,19 @@ public class GridView extends JPanel { private MapManager mapManager; /** Draw borders for the client scope */ + /* public void paintComponent(Graphics g){ super.paintComponent(g); g.drawOval(-200, -200, 400, 400); - //g.drawRect(0, -200, 400, 400); + //g.drawRect(-200, -200, 400, 400); //g.drawRoundRect(000, -200, 400, 400,100,100); // TODO :: La portée est affichée en brut ici, à changer dynamiquement ! - } + }*/ public GridView(MapManager mapManager, Client currentClient) { super(); this.mapManager = mapManager; - - // Image du marqueur ImageIcon pinIcon = new ImageIcon(getClass().getResource("/res/pin.png")); // load the image to a imageIcon @@ -54,7 +53,7 @@ public GridView(MapManager mapManager, Client currentClient) { // Listener permettant de gérer le drag n drop MouseListener ml = new MouseListener() { - + @Override public void mouseClicked(MouseEvent e) {} @@ -63,6 +62,8 @@ public void mousePressed(MouseEvent e) { GridCase jc = (GridCase)e.getSource(); TransferHandler th = jc.getTransferHandler(); + + currentClient.sendPosition(); // Permet d'éviter de pouvoir déplacer une case vide if(jc.getIcon() != null) diff --git a/src/client/Client.java b/src/client/Client.java index 9b629b0..abcea9f 100644 --- a/src/client/Client.java +++ b/src/client/Client.java @@ -12,19 +12,19 @@ /** - * Client allows a user to send messages to the server. + * Client allows a user to send messages to the server. This class communicates with ClientUI (Obs) and ClientThread with ObjectStream + * This is a serializable class that allow it to be send in ObjectStream (only with position and name) * @author Corentin - * */ public class Client extends Observable implements Serializable { - private String name = "test"; + // Serializabled attributes + private String name; private int position_x; private int position_y; + private ArrayList clientsData = new ArrayList<>(); // Client knows its Client's pair. - - private ArrayList clientsData = new ArrayList<>(); - + // Sockets and streams attributes private Socket socket = null; private OutputStream outputStream; private ObjectOutputStream objectOutputStream; @@ -33,6 +33,7 @@ public Client(){ super(); } + /** This constructor is used to send this into socket **/ public Client(String name, int position_x, int position_y){ this.name = name; this.position_x = position_x; @@ -49,29 +50,28 @@ public void InitSocket(String server, int port) throws IOException { receivingThread.start(); } + /** ClientUI is updating with arg by this method **/ public void notifyObservers(Object arg) { super.setChanged(); super.notifyObservers(arg); } - /** Send a line of text */ + /** Send a text Message to ClientThread */ public void send(String text) { try { Message message = new Message(Message._TEXT_, text, this.name, this.position_x, this.position_y, null); objectOutputStream.writeObject(message); - //objectOutputStream.flush(); } catch (IOException e) { notifyObservers(e); } } - /** Send a line of text */ + /** Send a position Message to ClientThread */ public void sendPosition() { try { Message message = new Message(Message._POSITION_, "", this.name, this.position_x, this.position_y, null); System.out.println("Client.SendPosition :" +message); objectOutputStream.writeObject(message); - //objectOutputStream.flush(); } catch (IOException e) { notifyObservers(e); } @@ -117,10 +117,9 @@ public int getY() { public void setY(int position_y) { this.position_y = position_y; } - + public void setClientsData(ArrayList clients){ this.clientsData = clients; - //System.out.println(clients); } public ArrayList getClientsData(){ @@ -129,9 +128,8 @@ public ArrayList getClientsData(){ @Override public String toString() { - return "Client [name=" + name + ", position_x=" + position_x + ", position_y=" + position_y + "]"; + return "Client [name=" + name + ", position_x=" + position_x + ", position_y=" + position_y + ", clientsData=" + + clientsData + ", socket=" + socket + ", outputStream=" + outputStream + ", objectOutputStream=" + + objectOutputStream + "]"; } - - - } diff --git a/src/client/ClientThread.java b/src/client/ClientThread.java index 4126da1..3a7b29b 100644 --- a/src/client/ClientThread.java +++ b/src/client/ClientThread.java @@ -11,12 +11,11 @@ import model.MessageValidator; /** - * ClientThread + * ClientThread is the thread that communicates with Server and Client. It receives Message from Client and sends Message to Client. * @author Corentin */ - public class ClientThread extends Thread{ - // Client Data (Name, posX, posY) saved in thread, not real Client instanced in ClientUI + // Client Data (Name, posX, posY) saved in thread, not real Client instanced in ClientUI. private Client clientData; private ObjectInputStream streamIn = null; private ObjectOutputStream streamOut = null; @@ -30,6 +29,7 @@ public ClientThread(Socket clientSocket, ArrayList threads) { } public synchronized void run() { + // Each ClientThread knows its ClientThread's pair. ArrayList threads = this.threads; try { @@ -37,20 +37,20 @@ public synchronized void run() { ObjectInputStream streamIn = new ObjectInputStream(is); streamOut = new ObjectOutputStream(clientSocket.getOutputStream()); - streamOut.writeObject(new Message(Message._TEXT_,"Quel est votre nom ?", "", 0, 0, null)); - streamOut.flush(); + // Ask to Client it's username and save him into clientData + streamOut.writeObject(new Message(Message._TEXT_,"Quel est votre nom ?", "BOT", 0, 0, getClients())); Message msgName = (Message)streamIn.readObject(); String clientName = msgName.text; this.clientData = new Client(clientName, 0, 0); - + for(ClientThread thread : threads){ if(thread != this){ - streamOut.writeObject(new Message(Message._TEXT_," s'est connecté !", clientName, 0, 0, null)); + streamOut.writeObject(new Message(Message._TEXT_," s'est connecté !", clientName, 0, 0, getClients())); } else { - streamOut.writeObject(new Message( Message._NAME_, "Bonjour " + clientName + " et bienvenue dans le chat. Pour communiquer avec les utilisateurs, il est nécessaire de se positionner à leur portée", clientName, 0, 0, null)); + streamOut.writeObject(new Message( Message._NAME_, "Bonjour " + clientName + " et bienvenue dans le chat. Pour communiquer et voir les utilisateurs connectés, il est nécessaire de se positionner à leur portée à l'aide d'un drag and drop", clientName, 0, 0, getClients())); } - //streamOut.flush(); + ArrayList clients = getClients(); } /* Start the conversation. */ @@ -61,8 +61,6 @@ public synchronized void run() { if(msg != null){ switch(msg.type){ case Message._TEXT_: - /*Message clientsMsg = new Message(Message._CLIENTS_, "", "", 0, 0, getClients()); - messages.add(clientsMsg);*/ sendMessages(messages); break; @@ -85,17 +83,22 @@ public synchronized void run() { } } + /** This method allows threads to send Messages to every Client **/ public synchronized void sendMessages(ArrayList messages){ + ArrayList clients = getClients(); for(ClientThread thread : threads){ for(Message message : messages){ try { + // All clients connected to server are saved into Message to allow Client to know them each other. + message.clients = clients; /*MessageValidator val = new MessageValidator(this.clientData, thread.clientData); if(this == thread || val.isClientsNear() == true) thread.streamOut.writeObject(message); else System.out.println("Hors de portée");*/ - thread.streamOut.writeObject(message); + thread.streamOut.writeObject(message); + System.out.println("ClientThread.sendMessages :" + message); } catch (IOException e) { e.printStackTrace(); } @@ -107,39 +110,35 @@ public synchronized void sendMessage(Message message){ ArrayList messages = new ArrayList<>(); messages.add(message); sendMessages(messages); - - //TODO : Le message est sensé contenir la listes des clients lq cette méthode est appelée par refreshClientData - System.out.println("ClientThread.sendMessage :" + messages); } + /** Save Client new position **/ public synchronized void refreshClientData(String name, int posX, int posY){ this.clientData.setName(name); this.clientData.setX(posX); this.clientData.setY(posY); - System.out.println("ClientThread.refreshClientData :"+this.clientData); - System.out.println(name+" position has been updated"); - + System.out.println(name+" position updated" + clientData); + } + + public synchronized Message createClientsMessage(){ ArrayList clients = getClients(); - - System.out.println("ClientThread.refreshClientData getClients() :"+ clients); - - sendMessage(new Message(Message._CLIENTS_, "", "", 0, 0, clients)); + return (new Message(Message._CLIENTS_, clients)); } + /** Return the list of Thread's Clients **/ public ArrayList getClients(){ ArrayList clients = new ArrayList<>(); for(ClientThread thread : threads){ clients.add(thread.clientData); } - System.out.println("ClientThread.getClients :"+clients); return clients; } public synchronized void disconnect(){ try{ for(ClientThread thread : threads){ - thread.streamOut.writeObject(new Message(Message._TEXT_, clientData.getName() + "s'est déconnecté !", "", 0, 0, null)); + thread.streamOut.writeObject(new Message(Message._TEXT_, clientData.getName() + "s'est déconnecté !", "", 0, 0, getClients())); if(thread == this) thread = null; } diff --git a/src/client/ReceivingThread.java b/src/client/ReceivingThread.java index 18ff0a8..f5797eb 100644 --- a/src/client/ReceivingThread.java +++ b/src/client/ReceivingThread.java @@ -8,7 +8,7 @@ import model.Message; /** - * ReceivingThread + * ReceivingThread allows Client to listen ClientThread * @author Corentin */ public class ReceivingThread implements Runnable{ @@ -26,18 +26,19 @@ public void run() try { InputStream is = socket.getInputStream(); ObjectInputStream streamIn = new ObjectInputStream(is); + Message msg = null; while(true){ msg = (Message)streamIn.readObject(); if(msg.type == Message._NAME_){ this.client.setName(msg.clientName); + msg.clientName = "BOT"; } - if(msg.type == Message._CLIENTS_){ - this.client.setClientsData(msg.clients); - continue; - } + // Set Clients array to Client + this.client.setClientsData(msg.clients); + // Notify all observers that ClientThread just send a Message this.client.notifyObservers("<"+msg.clientName+">"+msg.text); - System.out.println("ReceivingThread.run thisClients : "+this.client.getClientsData()); + System.out.println("ReceivingThread.run Message :" + msg); } } catch (IOException | ClassNotFoundException e) { diff --git a/src/model/Message.java b/src/model/Message.java index f935cf7..2d875bb 100644 --- a/src/model/Message.java +++ b/src/model/Message.java @@ -15,6 +15,7 @@ public class Message implements Serializable { public final static int _CLIENTS_ = 2; public final static int _DISCONNECT_ = 3; public final static int _POSITION_ = 4; + public final static int _CONNECT_ = 5; public int type; public String text; @@ -33,6 +34,11 @@ public Message(int type, String text, String clientName, int posX, int posY, Arr this.posY = posY; this.clients = clients; } + + public Message(int type, ArrayList clients){ + this.type = type; + this.clients = clients; + } @Override public String toString() { diff --git a/src/server/Server.java b/src/server/Server.java index 039d537..47c2220 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -8,7 +8,7 @@ import client.ClientThread; /** - * Server allow the communication between many clients. + * Server allow the communication between many ClientThread. * @author Corentin * */ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy