+ * Classe permettant de sauvegarder les échanges entre deux utilisateurs + *
+ */ +public class Historique { + private Utilisateur User1; + private Utilisateur User2; + // Liste conservant les differents échanges + private ArrayList+ * Constructeur : un historique sauvegarde les echanges entre + * User1 et User2 + * @param User1 - un utilisateur + * @param User2 - un second utilisateur + *
+ */ + public Historique(Utilisateur User1, Utilisateur User2) { + this.User1 = User1; + this.User2 = User2; + this.HistoriqueHorodate = new ArrayList+ * On ajoute un message échangé dans la liste 'HistoriqueHorodate' + * + * @param mh - le message horodate échangé + *
+ */ + public void addMessage(MessageHorodate mh) { + this.HistoriqueHorodate.add(mh); + } + + /** + *+ * getter pour recuperer le second utilisateur + *
+ */ + public Utilisateur getUser2() { + return User2; + } + + public void afficher10derniers() { + System.out.println("Demarrage de l'affichage partiel de l'historique"); + System.out.println("Il y a actuellement " + HistoriqueHorodate.size() +" elements dans l'historique"); + int n =10; + if(HistoriqueHorodate.size()<=10) { + n = HistoriqueHorodate.size(); + } + for(int i = 0; i+ * Classe representant les messages envoyés en TCP lors d'une session de clavardage + *
+ */ +public class MessageHorodate implements Serializable { + private Utilisateur destinataire ; + private Utilisateur source ; + private Date dateHorodatage ; + private int type; // 0 = debut de la communication, 1= message de communication, 2 = fin de la communicataion + private String Message; + + /** + *+ * Constructeur , le message va etre horodate + * @param destinataire - Destinataire du message + * @param source - Source du message + * @param Message - Message envoye + *
+ */ + public MessageHorodate(Utilisateur destinataire, Utilisateur source, String Message, int type) { + this.setDestinataire(destinataire) ; + this.setSource(source) ; + this.setMessage(Message) ; + this.setDateHorodatage(new Date()); + this.type = type; + } + + public void setDate(Date d) { + this.setDateHorodatage(d); + } + + /** + *+ * permet de creer une representation string du message + * @return Les differents attributs de la classe sous forme de string + *
+ */ + @Override + public String toString() { + String Msg = ""; + Msg += ("Destinataire::" + this.getDestinataire() + "\n") ; + Msg += ("Source::" + this.getSource()+ "\n") ; + Msg += ("Type::"+ this.type+ "\n"); + Msg += ("Date::" + this.dateToString() + "\n") ; + Msg += ("Message::" + this.getMessage() + "\n" ); + return Msg ; + } + + /** + *+ * permet de creer une representation string de la date d'horodatage + * @return La date d'horodatage du message en format yyyy/MM/dd HH:mm:ss + *
+ */ + public String dateToString() { + DateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + return format.format(this.getDateHorodatage()); + } + + + /** + *+ * Permet de re creer un message horodate a partir d'un string + * @return un messageHorodate + *
+ */ + public static MessageHorodate stringToMessageHorodate(String s) { + + String mots[] = s.split("\n"); + Utilisateur destinataire = Utilisateur.stringToUtilisateur(mots[0].split("::")[1]); + Utilisateur source = Utilisateur.stringToUtilisateur(mots[1].split("::")[1]); + int type = Integer.parseInt(mots[2].split("::")[1]); + DateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + Date date = new Date(); + /*try { + date = format.parse(mots[3].split("::")[1]); + } catch (Exception e) { + e.printStackTrace(); + }*/ + String payload = ""; + for(int i=4; i< mots.length; i++) { + if(mots[i].startsWith("Message::")) { + mots[i]=mots[i].split("::")[1]; + } + payload += mots[i]+"\n"; + } + + MessageHorodate mh = new MessageHorodate(destinataire, source, payload, type); + //mh.setDate(date); + + return mh ; + } + + public Utilisateur getSource() { + return source; + } + + public void setSource(Utilisateur source) { + this.source = source; + } + + public Utilisateur getDestinataire() { + return destinataire; + } + + public void setDestinataire(Utilisateur destinataire) { + this.destinataire = destinataire; + } + + public String getMessage() { + return Message; + } + + public void setMessage(String message) { + Message = message; + } + + public int getType() { + return type; + } + + public void setType(int Type) { + this.type = type; + } + + public Date getDateHorodatage() { + return dateHorodatage; + } + + public void setDateHorodatage(Date dateHorodatage) { + this.dateHorodatage = dateHorodatage; + } + +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/Utilisateur.java b/Implementation/chatapp/src/main/java/chatapp/Model/Utilisateur.java new file mode 100644 index 0000000..1103c33 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Model/Utilisateur.java @@ -0,0 +1,78 @@ +package chatapp.Model; + + +import java.net.InetAddress; +import java.net.UnknownHostException; + +public class Utilisateur { + + private String pseudo ; + private Integer port; + private final InetAddress ip ; + private final String id ; + + public Utilisateur(String pseudo,Integer port, InetAddress ip ){ + this.setPseudo(pseudo) ; + this.setPort(port); + this.ip = ip ; + this.id = ip.getHostName() ; + } + + public String getPseudo() { + return pseudo; + } + + public void setPseudo(String pseudo) { + this.pseudo = pseudo; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public InetAddress getIp() { + return ip; + } + public String getId() { + return id; + } + + @Override + public String toString(){ + String s = ""; + s+="pseudo " + this.pseudo + " | "; + s+="port " + (this.port).toString() + " | "; + s+="ip " + (this.ip).toString() + " | "; + s+="id " + (this.id).toString() + " | "; + return s; + } + + public static Utilisateur stringToUtilisateur(String s) { + String name; + Integer port = 0; + String ip = "" ; + String id = ""; + String mots[] = s.split(" "); + name=mots[1]; + port=Integer.parseInt(mots[4]); + ip=mots[7]; + id=mots[10]; + Utilisateur user = null; + try { + user = new Utilisateur(name,port,InetAddress.getByName(ip.split("/")[1])); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + return user; + } + + + public Boolean equals(Utilisateur u) { + return this.getId().equals( u.getId() ) ; + } + +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteTCP.java b/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteTCP.java new file mode 100644 index 0000000..577d836 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteTCP.java @@ -0,0 +1,67 @@ +package chatapp.Protocol; + +import chatapp.Controller.ChatApp; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class RunnerEcouteTCP extends Thread { + public ChatApp app ; + private PropertyChangeSupport pcs; + private ArrayList+ * Méthode pour qu'un objet de la classe ChatApp soit constamment en écoute de potentielles connexions + * @param app L'utilisateur en écoute de potentielles communications + *
+ */ + public void ecouteTCP(ChatApp app) { + ServerSocket ss = null; + System.out.println("Ecoute TCP activee"); + try { + ss = new ServerSocket(5000); // On ecoute sur le port 5000 + System.out.println("Socket d'ecoute cree"); + while(true) { // Ecoute en boucle + System.out.println("Attente Session de clavardage"); + Socket link = ss.accept(); // Blocante + SessionClavardage session = new SessionClavardage(link,app); + this.ListeSessions.add(session); + pcs.firePropertyChange("NouvelleSession",false,true); + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void addSession(SessionClavardage session){ + this.ListeSessions.add(session); + pcs.firePropertyChange("NouvelleSession",false,true); + } + public SessionClavardage getSessionClavardage() { + return(this.ListeSessions.remove(0)); + } + @Override + public void run() { + ecouteTCP(this.app); + + + } +} \ No newline at end of file diff --git a/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteUDP.java b/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteUDP.java new file mode 100644 index 0000000..06f2d9a --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteUDP.java @@ -0,0 +1,16 @@ +package chatapp.Protocol; + +import chatapp.Controller.ChatApp; + +public class RunnerEcouteUDP extends Thread { + ChatApp app ; + public RunnerEcouteUDP(ChatApp app) { + this.app = app ; + } + @Override + public void run() { + + UDPEchange.ecouteUDP(app); + + } +} \ No newline at end of file diff --git a/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java b/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java new file mode 100644 index 0000000..f2551c5 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java @@ -0,0 +1,183 @@ +package chatapp.Protocol; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.util.ArrayList; + +import chatapp.Controller.ChatApp; +import chatapp.Model.MessageHorodate; +import chatapp.Model.Utilisateur; +import chatapp.View.FenetreSession; +import javafx.application.Platform; + +public class SessionClavardage extends Thread { + private Socket link; + private ChatApp app; + private Utilisateur u2; + private ObjectOutputStream out; + private ObjectInputStream in; + private PropertyChangeSupport pcs; + private ArrayList+ * Classe representant les échanges TCP entre utilisateurs. + *
+ */ +public class TCPEchange { + + /** + *+ * Equivalent a un handshake. + * L'utilisateur associé a app souhaite entamé une discussion avec User2 + * @param app L'app associé à l'utilisateur qui souhaite entamé la discussion + * @param User2 Le destinataire + *
+ */ + public static void demarrerSession(ChatApp app,Utilisateur User2 ) throws IOException { + System.out.println("Demmarrage d'une session de clavardage"); + Socket s = new Socket(User2.getIp(),5000); + System.out.println("Socket de demarrage d'une session cree"); + //ExecutorService exec = Executors.newFixedThreadPool(1000); + Thread t1 = new Thread(new RunnerTCPEcoute(s,app)); + Thread t2 = new Thread(new RunnerTCPEnvoi(s,app,User2,false)); + t1.start(); + t2.start(); + try { + t1.join(); + t2.join(); + }catch(InterruptedException e) { + System.out.println("Un thread s'est arrete brusquement"); + } + System.out.println("Tout s'est passe creme"); + app.getHist(User2.getPseudo()).afficher10derniers(); + + } + + /*public static void envoiTCP(ChatApp app,Utilisateur User2, String Msg, int type ) { + // On cree un messagehorodate + MessageHorodate mh = new MessageHorodate(app.getMe(), User2, Msg, type); + if( type == 1 ) { + // on ajoute le msg à son historique + Historique h = app.getHist(User2.getPseudo()); + h.addMessage(mh); + // on update la liste des historiques de app + app.majHistorique(h); + } + + try { + Socket s = new Socket(User2.getIp(), User2.getPort()); + PrintStream output = new PrintStream(s.getOutputStream()); + output.println(mh.toString()); + output.close(); + s.close(); + } catch (Exception e) { + e.printStackTrace(); + } + }*/ + + + /** + *+ * Méthode pour qu'un objet de la classe ChatApp soit constamment en écoute de potentielles connexions + * @param app L'utilisateur en écoute de potentielles communications + *
+ */ + public static void ecouteTCP(ChatApp app) { + ServerSocket ss = null; + ExecutorService exec = Executors.newFixedThreadPool(1000); + System.out.println("Ecoute TCP activee"); + try { + ss = new ServerSocket(5000); // On ecoute sur le port 5000 + System.out.println("Socket d'ecoute cree"); + while(true) { // Ecoute en boucle + System.out.println("Attente Session de clavardage"); + Socket link = ss.accept(); // Blocante + exec.submit(new RunnerTCPEcoute(link,app)); // On crée un thread qui va gerer la connexion recu + System.out.println("L'ecoute TCP continue apres le premier thread demarre"); + } + } + catch (Exception e) { + e.printStackTrace(); + } + } +} + + +/** + *+ * Classe representant les threads s'occupant de l'envoie de messages en utilisant le protocole TCP. + * Cette classe implemente l'interface Runnable. + *
+ */ +class RunnerTCPEnvoi implements Runnable { + private Socket link; + private ChatApp app ; + private Utilisateur Destinataire; + final BufferedReader in; + final PrintWriter out; + final Scanner sc=new Scanner(System.in); + private boolean bonjourEnvoye = false; + + /** + *+ * Constructeur de la classe RunnerTCPEnvoi + * @param link + * @param app Un objet ChatApp dont l'utilisateur associé souhaite entame une discussion + * @param user2 Destinataire + * @param bonjour Boolean true si c'est le debut d'une connexion, false sinon + *
+ */ + public RunnerTCPEnvoi(Socket link,ChatApp app, Utilisateur user2, boolean bonjour ) throws IOException { + this.link = link; + this.app = app; + this.Destinataire = user2; + this.out = new PrintWriter(link.getOutputStream()); + this.in = new BufferedReader (new InputStreamReader (link.getInputStream())); + this.bonjourEnvoye = bonjour; + } + + @Override + public void run() { + System.out.println("Creation d'un thread d'envoi"); + String msg; + + while(true){ + if(!bonjourEnvoye) { // bonjourEnvoye est a false si c'est le debut d'une communication + MessageHorodate mh = new MessageHorodate(Destinataire,app.getMe(),"Bonjour",2); + bonjourEnvoye = true; + System.out.println("Envoi d'un bonjour"); + out.println(mh); + out.flush(); + } + else { + try { + msg = sc.nextLine(); + }catch(NoSuchElementException e) { + break; + } + MessageHorodate mh = new MessageHorodate(Destinataire,app.getMe(),msg,1); + if(msg.equals("--STOP--")) { + mh = new MessageHorodate(Destinataire,app.getMe(),msg,0); // ENVOYER JUSTE --STOP-- SUFFIT + out.println(mh); + out.flush(); + break; + } + /* while(!app.isHistoriqueAvailable()) { + try{wait(); + }catch(InterruptedException e) {} + }*/ + //app.setHistoriqueAvailable(false); + synchronized( this.app.getMapHistorique()) { + Historique h = app.getHist(Destinataire.getPseudo()); + h.addMessage(mh); + app.majHistorique(h); + } + + // on update la liste des historiques de app + + //app.majHistorique2(mh.toString(),Destinataire.getPseudo()); + //app.setHistoriqueAvailable(false); + //notifyAll(); + out.println(mh); + System.out.println("Envoi d'un mesage"); + out.flush(); + } + } + try { + System.out.println("Fermeture du thread d'envoi"); + in.close(); + link.close(); + }catch(Exception e) { + // Gestion de l'exception de la fermeture de la socket + } + } + +} + + + +/** + *+ * Classe representant les threads s'occupant de la reception de messages en utilisant le protocole TCP. + * Cette classe implemente l'interface Runnable. + *
+ */ +class RunnerTCPEcoute implements Runnable { + final Socket link; + private ChatApp app ; + private Utilisateur u2; + private boolean u2Initialise; + public RunnerTCPEcoute(Socket link,ChatApp app ) { + this.link = link; + this.app = app; + this.u2Initialise=false; + } + + @Override + public void run() { + System.out.println("Creation d'un thread d'ecoute"); + try { + PrintStream output = new PrintStream(link.getOutputStream()); + //InputStream is = link.getInputStream(); + BufferedReader in = new BufferedReader (new InputStreamReader (link.getInputStream())); + + String line = ""; + String dest = ""; + String src = ""; + String type = ""; + String date = ""; + String payload = ""; + String msg = ""; + line = in.readLine(); + while (line != null) { + + + if(line.split("::")[0].equals("Destinataire")) { + if(msg.equals("")) { + dest = line+"\n"; + msg="."; + } + else { + msg=dest+src+type+date+payload; + payload = ""; + MessageHorodate mh = MessageHorodate.stringToMessageHorodate(msg); + System.out.println("Type du message:"+mh.getType()); + if(mh.getType()==1) { + /*while(!app.isHistoriqueAvailable()) { + try{wait(); + }catch(InterruptedException e) {} + } + app.setHistoriqueAvailable(false);*/ + System.out.println("Historique mis à jour lors de la reception"); + Historique h = app.getHist(mh.getSource().getPseudo()); + h.addMessage(mh); + app.majHistorique(h); + //app.setHistoriqueAvailable(true); + //notifyAll(); + //app.majHistorique2(mh,mh.getSource().getPseudo()); + } + else if(mh.getType()==0) { + break; + } + + } + } + else if(line.split("::")[0].equals("Source")) { + src = line+"\n"; + if(!u2Initialise) { + u2=Utilisateur.stringToUtilisateur(src.split("::")[1].replaceAll("\n", "")); + System.out.println("u2Initialise !"); + u2Initialise = true; + } + } + else if(line.split("::")[0].equals("Type")) { + if(line.split("::")[1].equals("2")) { + System.out.println("Bonjour recu!"); + //System.out.println(src.split("::")[1].replaceAll("\n", "")); + u2=Utilisateur.stringToUtilisateur(src.split("::")[1].replaceAll("\n", "")); + u2Initialise = true; + System.out.println("Pseudo du poto: >>"+u2.getPseudo()+"<<"); + Thread t = new Thread(new RunnerTCPEnvoi(link,app,u2,true)); + t.start(); + System.out.println("Thread d'envoi envoye"); + } + type = line+"\n"; + } + else if(line.split("::")[0].equals("Date")) { + date = line+"\n"; + } + else if(line.split("::")[0].equals("Message")){ + payload = line+"\n"; + + } + else { + payload += line+"\n"; + } + + System.out.println("Received: "+ line); + line = in.readLine(); + + + } + System.out.println("Affichage de l'histo"); + System.out.println("Pseudo du poto: >>"+u2.getPseudo()+"<<"); + app.getHist(u2.getPseudo()).afficher10derniers(); + in.close(); + link.close(); + } catch (IOException e) { + //e.printStackTrace(); + } finally { + System.out.println("Finishing thread"); + System.out.println("Affichage de l'histo"); + System.out.println("Pseudo du poto: >>"+u2.getPseudo()+"<<"); + app.getHist(u2.getPseudo()).afficher10derniers(); + + + } + + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Protocol/UDPEchange.java b/Implementation/chatapp/src/main/java/chatapp/Protocol/UDPEchange.java new file mode 100644 index 0000000..133ce44 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/UDPEchange.java @@ -0,0 +1,360 @@ +package chatapp.Protocol; + +import java.io.IOException; + +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.Inet4Address; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import chatapp.Controller.*; +import chatapp.Model.*; +/** + *+ * Classe representant les echanges UDP entre utilisateurs. + *
+ */ + +public class UDPEchange { + + private static Boolean Connecte = true; + // True si l'utilisateur peut se connecter avec ce nom d'utilisateur , False sinon + + private static Boolean EcouteEnCours = false; + /** + * Getter + * @return le boolean connecte (True s'il peut se connecter avec ce nom d'utilisateur , False sinon) + */ + public static Boolean getConnecte() { + return Connecte; + } + + /** + * Setter + * @param value La nouvelle valeur du boolean de connexion + */ + public static void setConnecte(Boolean value) { + Connecte = value ; + } + + private static Boolean PseudoValide = true; + // True si l'utilisateur a (ou demande) un pseudo valide , False sinon + + /** + * Getter + * @return le boolean PseudoValide (True s'il peut utiliser ce pseudo , False sinon) + */ + public static Boolean getPseudoValide() { + return PseudoValide; + } + + /** + * Setter + * @param value La nouvelle valeur du boolean concernant le pseudo valide + */ + public static void setPseudoValide(Boolean value) { + PseudoValide = value ; + } + + + + public static InetAddress getCurrentIp() { + try { + Enumeration+ * Méthode permettant d'envoyer un message à tout les utilisateurs + * a l'aide du protocole UDP + *
+ * @param broadcastMessage correspond au message a transmettre aux utilisateurs + */ + public static void EnvoiBroadcast(String broadcastMessage) throws IOException { + int port = 1234 ; + // Envoie en broadcast à tous les utilsateurs + for (InetAddress broadcastAddr : listAllBroadcastAddresses()) { + DatagramSocket socket = new DatagramSocket(); + socket.setBroadcast(true); + byte[]buffer = broadcastMessage.getBytes(); + DatagramPacket packet = new DatagramPacket( buffer, buffer.length, broadcastAddr,port); + socket.send(packet); + socket.close(); + System.out.println("Broadcast sent with address " + broadcastAddr.toString()); + System.out.println("***********Message envoye***********"); + System.out.println("Dest Ip: " + broadcastAddr.toString()); + System.out.println("Dest port: " + String.valueOf(port)); + System.out.println("Contenu: "); + System.out.println(broadcastMessage); + System.out.println("************************************"); + } + } + + /** + *+ * Methode permettant la reception de messages d'utilisateurs + * a l'aide du protocole UDP + *
+ * @param app L'application de chat de l'utilisateur qui receptionne le message + */ + public static void ecouteUDP(ChatApp app) + { + DatagramSocket socket = null; + ExecutorService exec = Executors.newFixedThreadPool(1000); + try { + socket = new DatagramSocket(1234); + } catch (SocketException e1) { + e1.printStackTrace(); + } + byte buffer[] = new byte[1024]; + System.out.println("Ecoute sur le port: 1234"); + while(true) + { + DatagramPacket data = new DatagramPacket(buffer,buffer.length); + try { + socket.receive(data); + } catch (IOException e) { + e.printStackTrace(); + } + // Un thread est lance à chaque reception d'un message + System.out.println("Message recu!"); + exec.submit(new RunnerUDP(data,app)); + } + } + + /** + *+ * Methode permettant d'envoyer un message a utilisateur en particulier + * a l'aide du protocole UDP + *
+ * @param Adress l'addresse de l'utilisateur + * @param Message correspond au message à transmettre a l'utilisateur + */ + public static void envoiUnicast( InetAddress Adress , String Message ) throws IOException { + DatagramSocket socket = new DatagramSocket(); + byte[]buffer = Message.getBytes(); + DatagramPacket packet = new DatagramPacket( buffer, buffer.length, Adress, 1234 ); + socket.send(packet); + socket.close(); + System.out.println("***********Message envoye***********"); + System.out.println("Dest Ip: " + Adress.toString()); + System.out.println("Dest port: " + String.valueOf(1234)); + System.out.println("Contenu: "); + System.out.println(Message); + System.out.println("************************************"); + } + + /** + *+ * Methode permettant de recuperer la liste des adresses de broadcast, chacune associer à une interface de la machine + *
+ */ + static List+ * Classe implementant l'interface Runnable. + * Contient les traitements a executer dans un thread lancer par des methodes de la class UDPEchange + *
+ */ +class RunnerUDP implements Runnable { + final DatagramPacket data ; + ChatApp app ; + + public RunnerUDP(DatagramPacket data, ChatApp app) { + this.data= data; + this.app = app ; + } + + /** + *+ * Methode qui redefinie les traitements qui seront executes dans le thread: + * Met à jour la liste des utilisateurs actifs + *
+ * + */ + @Override + public void run() { + System.out.println("Thread started"); + String received = new String(data.getData(), 0, data.getLength()); + System.out.println("***********Message recu***********"); + System.out.println(received); + System.out.println("**********************************"); + String Type = received.split("\n")[0]; + + //**************************************************************************************************** + //**************************************************************************************************** + //****************************************Demande de connexion**************************************** + //**************************************************************************************************** + //**************************************** + if (Type.equals("Connexion")) { // un utilisateur vient d'arriver sur le reseau + System.out.println("Reception d'une demande de connexion"); + Utilisateur u = Utilisateur.stringToUtilisateur(received.split("\n")[1]); + if (! u.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même + String reponse = "Reponse Connexion\n"; + if (!( app.getActifUsers() ).verifierUnicite(u.getPseudo())) { + System.out.println("Pseudo deja present dans la liste"); + reponse += "false\n"; + } + else { + System.out.println("Ajout d'un nouvel utilisateur dans la liste des Utilisateurs"); + ( app.getActifUsers() ).addList(u); + reponse += "true\n"; + + } + reponse += app.getMe().toString(); + + try { + UDPEchange.envoiUnicast(u.getIp(),reponse); + }catch(IOException e) + { + System.out.println("Echec de l'envoi du message"); + } + + ( app.getActifUsers() ).afficherListeUtilisateurs(); + } + } + //******************************************************************************************************* + //******************************************************************************************************* + //****************************************Reponse d'une connexion**************************************** + //******************************************************************************************************* + //******************************************************************************************************* + + if (Type.equals("Reponse Connexion")) { // Un utilisateur te repond suite à ta demande de connexion + + if((received.split("\n")[1]).equals("true")) { + Utilisateur u = Utilisateur.stringToUtilisateur(received.split("\n")[2]); + app.getActifUsers().addList(u); + app.getActifUsers().afficherListeUtilisateurs(); + } + else { + System.out.println("Pseudo deja pris"); + UDPEchange.setConnecte(false); + } + } + + //******************************************************************************************************************* + //******************************************************************************************************************* + //****************************************Demande de modification d'un pseudo**************************************** + //******************************************************************************************************************* + //******************************************************************************************************************* + + if (Type.equals("Demande Modification Pseudo")) { + Utilisateur Source = Utilisateur.stringToUtilisateur(received.split("\n")[1]); + if (! Source.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même + String nouveau = received.split("\n")[2] ; + String Message = ""; + if(( app.getActifUsers() ).verifierUnicite(nouveau)) { + Message = "Bon Choix Pseudo\n" + nouveau ; + } + else { + Message = "Mauvais Choix Pseudo\n" ; + } + System.out.println(Message); + try { + UDPEchange.envoiUnicast(Source.getIp(),Message); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + //************************************************************************************************************ + //************************************************************************************************************ + //**************************************** Modification pseudo reussi **************************************** + //************************************************************************************************************ + //************************************************************************************************************ + + if (Type.equals("Modification pseudo reussi")) { + Utilisateur Source = Utilisateur.stringToUtilisateur(received.split("\n")[1]); + if (! Source.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même + String nouveau = received.split("\n")[2] ; + if(app.getActifUsers().appartient(Source)) { // On verifie d'abord que Source appartient bien a la liste des utilisateurs actifs + app.getActifUsers().modifierList(Source.getPseudo(), nouveau); + } + { + // Suite a une perte d'un message lors d'une connexion l'utilisateur Source n'apparait pas dans la liste + app.getActifUsers().addList(Source); + } + } + } + //********************************************************************************************************* + //********************************************************************************************************* + //****************************************Mauvais choix d'un pseudo**************************************** + //********************************************************************************************************* + //********************************************************************************************************* + if (Type.equals("Mauvais Choix Pseudo")) { + System.out.println("Ce choix de pseudo est déjà pris il te faut en choisir un autre"); + UDPEchange.setPseudoValide(false); + } + + //****************************************************************************************************************** + //****************************************************************************************************************** + //****************************************Bon choix d'un pseudo***************************************************** + //****************************************************************************************************************** + //****************************************************************************************************************** + + if (Type.equals("Bon Choix Pseudo")) { + // Il n'y a rien a faire ici + } + + //********************************************************************************************************* + //********************************************************************************************************* + //****************************************Demande d'une deconnexion**************************************** + //********************************************************************************************************* + //********************************************************************************************************* + + if (Type.equals("Deconnexion")) { + ( app.getActifUsers() ).supprimerList(Utilisateur.stringToUtilisateur(received.split("\n")[1])); + } + } + + + + +} diff --git a/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java b/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java new file mode 100644 index 0000000..51ccf41 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java @@ -0,0 +1,87 @@ + +package chatapp.View; + + import java.io.IOException; + import java.net.URL; + import java.util.ResourceBundle; + + import chatapp.Controller.ChatApp; + import javafx.event.ActionEvent; + import javafx.fxml.FXML; + import javafx.fxml.FXMLLoader; + import javafx.scene.Parent; + import javafx.scene.Scene; + import javafx.scene.control.Alert; + import javafx.scene.control.Button; + import javafx.scene.control.TextField; + import javafx.scene.text.Text; + import javafx.stage.Stage; + +public class ChangementPseudo { + + @FXML // ResourceBundle that was given to the FXMLLoader + private ResourceBundle resources; + + @FXML // URL location of the FXML file that was given to the FXMLLoader + private URL location; + + @FXML // fx:id="validationButton" + private Button validationButton; // Value injected by FXMLLoader + + @FXML // fx:id="pseudonyme" + private TextField pseudonyme; // Value injected by FXMLLoader + + @FXML // fx:id="pseudonyme1" + private Text pseudonyme1; // Value injected by FXMLLoader + + @FXML // fx:id="MenuButton" + private Button MenuButton; // Value injected by FXMLLoader + + private ChatApp chatApp; + @FXML + void nouveauPseudo(ActionEvent event) { + + } + + @FXML + void retourMenu(ActionEvent event) { + Stage stage = (Stage) MenuButton.getScene().getWindow(); + Parent root = null; + try { + root = FXMLLoader.load(getClass().getResource("/fenetres/View_Menu.fxml")); + } catch (IOException e) { + e.printStackTrace(); + } + Scene scene = new Scene(root); + stage.setScene(scene); + stage.show(); + } + + @FXML + void validerPseudo(ActionEvent event) { + boolean pseudoOK = false; + try { + pseudoOK = chatApp.modifierPseudo(pseudonyme.getText()); + } catch (IOException e) { + e.printStackTrace(); + } + if(pseudoOK){ + this.retourMenu(null); + } + else{ + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle("Changement pseudo"); + // Header Text: null + alert.setHeaderText(null); + alert.setContentText("Echec de Connexion: le pseudo "+pseudonyme.getText()+" est deja pris"); + alert.showAndWait(); + } + } + + @FXML // This method is called by the FXMLLoader when initialization is complete + void initialize() { + chatApp = ChatApp.getInstance(); + pseudonyme1.setText(chatApp.getMe().getPseudo()); + + } +} \ No newline at end of file diff --git a/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java b/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java new file mode 100644 index 0000000..ac34cdc --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java @@ -0,0 +1,97 @@ +package chatapp.View; + + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.net.URL; +import java.util.ResourceBundle; + +import chatapp.Controller.ChatApp; +import chatapp.Model.MessageHorodate; +import chatapp.Model.Utilisateur; +import chatapp.Protocol.SessionClavardage; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Button; +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; +import javafx.scene.text.Text; + +public class Clavardage implements Initializable, PropertyChangeListener { + + @FXML // ResourceBundle that was given to the FXMLLoader + private ResourceBundle resources; + + @FXML // URL location of the FXML file that was given to the FXMLLoader + private URL location; + + @FXML // fx:id="AEnvoyer" + private TextField AEnvoyer; // Value injected by FXMLLoader + + @FXML // fx:id="EnvoyerButton" + private Button EnvoyerButton; // Value injected by FXMLLoader + + @FXML // fx:id="pseudonyme1" + private Text pseudonyme1; // Value injected by FXMLLoader + + @FXML // fx:id="ChatText" + private TextArea ChatText; // Value injected by FXMLLoader + + @FXML // fx:id="MenuButton" + private Button MenuButton; // Value injected by FXMLLoader + private Utilisateur u2; + private SessionClavardage session; + public int Clav = 3; + @FXML + void envoyerMessage(ActionEvent event) { + String msg = AEnvoyer.getText(); + AEnvoyer.clear(); + session.envoiMsg(msg); + msg= "Moi: "+msg+"\n"; + ChatText.appendText(msg); + } + + @FXML + void retourMenu(ActionEvent event) { + + } + + @FXML // This method is called by the FXMLLoader when initialization is complete + void initialize() { + } + public void printsalut(){ + System.out.println("wesh"); + } + public void setSession(SessionClavardage session) { + //this.printsalut(); + this.session = session; + System.out.println("1"); + this.session.addPropertyChangeListener(this); + System.out.println("2"); + this.u2=session.getU2(); + System.out.println("3"); + this.pseudonyme1.setText(u2.getPseudo()); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + switch (evt.getPropertyName()){ + case "MessageRecu" : + MessageHorodate msgh = session.getDernierMsg(); + String msg = u2.getPseudo(); + msg+=": "+msgh.getMessage(); + ChatText.appendText(msg); + break; + } + + } + + public SessionClavardage getSession(){ + return session; + } + + @Override + public void initialize(URL location, ResourceBundle resources) { + } +} \ No newline at end of file diff --git a/Implementation/chatapp/src/main/java/chatapp/View/ConnexionScreen.java b/Implementation/chatapp/src/main/java/chatapp/View/ConnexionScreen.java new file mode 100644 index 0000000..a8043bb --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/ConnexionScreen.java @@ -0,0 +1,64 @@ + +package chatapp.View; + +import java.io.IOException; +import java.net.URL; +import java.util.ResourceBundle; + +import chatapp.Controller.ChatApp; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.TextField; +import javafx.stage.Stage; + +public class ConnexionScreen { + + public Button connexionButton; + + public TextField pseudonyme; + + @FXML // ResourceBundle that was given to the FXMLLoader + private ResourceBundle resources; + + @FXML // URL location of the FXML file that was given to the FXMLLoader + private URL location; + + @FXML // This method is called by the FXMLLoader when initialization is complete + void initialize() { + + } + + public void connexion(ActionEvent actionEvent) { + Boolean connexion = false; + try { + connexion = ChatApp.getInstance().connexion(pseudonyme.getText()); + } catch (IOException e) { + e.printStackTrace(); + } + if(!connexion){ + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle("Connexion"); + // Header Text: null + alert.setHeaderText(null); + alert.setContentText("Echec de Connexion: le pseudo "+pseudonyme.getText()+" est deja pris"); + alert.showAndWait(); + } + else{ + Stage stage = (Stage) connexionButton.getScene().getWindow(); + Parent root = null; + try { + root = FXMLLoader.load(getClass().getResource("/fenetres/View_Menu.fxml")); + } catch (IOException e) { + e.printStackTrace(); + } + Scene scene = new Scene(root); + stage.setScene(scene); + stage.show(); + } + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/View/DemarrerSession.java b/Implementation/chatapp/src/main/java/chatapp/View/DemarrerSession.java new file mode 100644 index 0000000..d0ac6b0 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/DemarrerSession.java @@ -0,0 +1,67 @@ +/** + * Sample Skeleton for 'View_Demarrer_Session.fxml' Controller Class + */ + +package chatapp.View; + +import java.io.IOException; +import java.net.URL; +import java.util.ResourceBundle; + +import chatapp.Controller.ChatApp; +import chatapp.Model.ListUtilisateurs; +import chatapp.Model.Utilisateur; +import chatapp.Protocol.RunnerEcouteTCP; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.stage.Stage; + +public class DemarrerSession { + + @FXML // ResourceBundle that was given to the FXMLLoader + private ResourceBundle resources; + + @FXML // URL location of the FXML file that was given to the FXMLLoader + private URL location; + + @FXML // fx:id="choixContact" + private ComboBox-* Classe recapitulant toutes les actions possibles pour un utilisateur -*
-*/ - -public class ChatApp { - - /* Liste des utilisateurs actifs */ - private ListUtilisateurs actifUsers ; - - /* Map on l'on stocke localement les historiques des messages */ - private Map-* Classe permettant de sauvegarder les échanges entre deux utilisateurs -*
-*/ -public class Historique { - private Utilisateur User1; - private Utilisateur User2; - // Liste conservant les differents échanges - private ArrayList- * Constructeur : un historique sauvegarde les echanges entre - * User1 et User2 - * @param User1 - un utilisateur - * @param User2 - un second utilisateur - *
- */ - public Historique(Utilisateur User1, Utilisateur User2) { - this.User1 = User1; - this.User2 = User2; - this.HistoriqueHorodate = new ArrayList- * On ajoute un message échangé dans la liste 'HistoriqueHorodate' - * - * @param mh - le message horodate échangé - *
- */ - public void addMessage(MessageHorodate mh) { - this.HistoriqueHorodate.add(mh); - } - - /** - *- * getter pour recuperer le second utilisateur - *
- */ - public Utilisateur getUser2() { - return User2; - } - - public void afficher10derniers() { - System.out.println("Demarrage de l'affichage partiel de l'historique"); - System.out.println("Il y a actuellement " + HistoriqueHorodate.size() +" elements dans l'historique"); - int n =10; - if(HistoriqueHorodate.size()<=10) { - n = HistoriqueHorodate.size(); - } - for(int i = 0; i-* Classe representant les messages envoyés en TCP lors d'une session de clavardage -*
-*/ -public class MessageHorodate { - private Utilisateur destinataire ; - private Utilisateur source ; - private Date dateHorodatage ; - private int type; // 0 = debut de la communication, 1= message de communication, 2 = fin de la communicataion - private String Message; - - /** - *- * Constructeur , le message va etre horodate - * @param destinataire - Destinataire du message - * @param source - Source du message - * @param Message - Message envoye - *
- */ - public MessageHorodate(Utilisateur destinataire, Utilisateur source, String Message, int type) { - this.setDestinataire(destinataire) ; - this.setSource(source) ; - this.setMessage(Message) ; - this.setDateHorodatage(new Date()); - this.type = type; - } - - public void setDate(Date d) { - this.setDateHorodatage(d); - } - - /** - *- * permet de creer une representation string du message - * @return Les differents attributs de la classe sous forme de string - *
- */ - @Override - public String toString() { - String Msg = ""; - Msg += ("Destinataire::" + this.getDestinataire() + "\n") ; - Msg += ("Source::" + this.getSource()+ "\n") ; - Msg += ("Type::"+ this.type+ "\n"); - Msg += ("Date::" + this.dateToString() + "\n") ; - Msg += ("Message::" + this.getMessage() + "\n" ); - return Msg ; - } - - /** - *- * permet de creer une representation string de la date d'horodatage - * @return La date d'horodatage du message en format yyyy/MM/dd HH:mm:ss - *
- */ - public String dateToString() { - DateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - return format.format(this.getDateHorodatage()); - } - - - /** - *- * Permet de re creer un message horodate a partir d'un string - * @return un messageHorodate - *
- */ - public static MessageHorodate stringToMessageHorodate(String s) { - - String mots[] = s.split("\n"); - Utilisateur destinataire = Utilisateur.stringToUtilisateur(mots[0].split("::")[1]); - Utilisateur source = Utilisateur.stringToUtilisateur(mots[1].split("::")[1]); - int type = Integer.parseInt(mots[2].split("::")[1]); - DateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - Date date = new Date(); - /*try { - date = format.parse(mots[3].split("::")[1]); - } catch (Exception e) { - e.printStackTrace(); - }*/ - String payload = ""; - for(int i=4; i< mots.length; i++) { - if(mots[i].startsWith("Message::")) { - mots[i]=mots[i].split("::")[1]; - } - payload += mots[i]+"\n"; - } - - MessageHorodate mh = new MessageHorodate(destinataire, source, payload, type); - //mh.setDate(date); - - return mh ; - } - - public Utilisateur getSource() { - return source; - } - - public void setSource(Utilisateur source) { - this.source = source; - } - - public Utilisateur getDestinataire() { - return destinataire; - } - - public void setDestinataire(Utilisateur destinataire) { - this.destinataire = destinataire; - } - - public String getMessage() { - return Message; - } - - public void setMessage(String message) { - Message = message; - } - - public int getType() { - return type; - } - - public void setType(int Type) { - this.type = type; - } - - public Date getDateHorodatage() { - return dateHorodatage; - } - - public void setDateHorodatage(Date dateHorodatage) { - this.dateHorodatage = dateHorodatage; - } - -} diff --git a/Implementation/src/Controller/Modification_Pseudo.java b/Implementation/src/Controller/Modification_Pseudo.java deleted file mode 100644 index e34b110..0000000 --- a/Implementation/src/Controller/Modification_Pseudo.java +++ /dev/null @@ -1,51 +0,0 @@ -package src.Controller; - -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.IOException; - -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTextField; -import javax.swing.SwingConstants; - -public class Modification_Pseudo extends JPanel{ - ChatApp app; - public Modification_Pseudo(String name, ChatApp app) { - this.app = app ; - JLabel Text = new JLabel("Entrez un nouveau nom d'utilisateur!", SwingConstants.CENTER); - JTextField pseudofield = new JTextField(2); // Zone d'insertion de texte - JButton home = new JButton(new ImageIcon("/Users/auriane/Desktop/ChatApp-AL-NM/Implementation/src/images/Home.png")); - //Ajout d'un bouton Valider - JButton Valider = new JButton("Valider"); - this.getRootPane().setDefaultButton(Valider); - //Listen to events from the Valider button. - Valider.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent event) { - String nouveau = pseudofield.getText(); - try { - Boolean resultat = app.modifierPseudo(nouveau); - if(resultat) { - - } - else { - //JOptionPane.showMessageDialog(this, "Echec de modification de pseudo, " + nouveau +" deja pris", JOptionPane.WARNING_MESSAGE); - - } - } catch (IOException e) { - e.printStackTrace(); - } - } - }); - this.add(home); - this.add(Text); - this.add(BorderLayout.CENTER,pseudofield); - this.add(BorderLayout.SOUTH,Valider); - -} -} diff --git a/Implementation/src/Controller/Utilisateur.java b/Implementation/src/Controller/Utilisateur.java deleted file mode 100644 index 9a35547..0000000 --- a/Implementation/src/Controller/Utilisateur.java +++ /dev/null @@ -1,77 +0,0 @@ -package src.Controller; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -public class Utilisateur extends Object { - - private String pseudo ; - private Integer port; - private InetAddress ip ; - private String id ; - - public Utilisateur(String pseudo,Integer port, InetAddress ip ){ - this.setPseudo(pseudo) ; - this.setPort(port); - this.ip = ip ; - this.id = ip.getHostName() ; - } - - public String getPseudo() { - return pseudo; - } - - public void setPseudo(String pseudo) { - this.pseudo = pseudo; - } - - public Integer getPort() { - return port; - } - - public void setPort(Integer port) { - this.port = port; - } - - public InetAddress getIp() { - return ip; - } - public String getId() { - return id; - } - - @Override - public String toString(){ - String s = ""; - s+="pseudo " + this.pseudo + " | "; - s+="port " + (this.port).toString() + " | "; - s+="ip " + (this.ip).toString() + " | "; - s+="id " + (this.id).toString() + " | "; - return s; - } - - public static Utilisateur stringToUtilisateur(String s) { - String name = ""; - Integer port = 0; - String ip = "" ; - String id = ""; - String mots[] = s.split(" "); - name=mots[1]; - port=Integer.parseInt(mots[4]); - ip=mots[7]; - id=mots[10]; - Utilisateur user = null; - try { - user = new Utilisateur(name,port,InetAddress.getByName(ip.split("/")[1])); - } catch (UnknownHostException e) { - e.printStackTrace(); - } - return user; - } - - - public Boolean equals(Utilisateur u) { - return this.getId().equals( u.getId() ) ; - } - -} diff --git a/Implementation/src/Protocoles/RunnerEcouteTCP.java b/Implementation/src/Protocoles/RunnerEcouteTCP.java deleted file mode 100644 index 2706ea4..0000000 --- a/Implementation/src/Protocoles/RunnerEcouteTCP.java +++ /dev/null @@ -1,16 +0,0 @@ -package src.Protocoles; - -import src.Controller.ChatApp; - -public class RunnerEcouteTCP implements Runnable { - ChatApp app ; - public RunnerEcouteTCP(ChatApp app) { - this.app = app ; - } - @Override - public void run() { - - TCPEchange.ecouteTCP(app); - - } -} \ No newline at end of file diff --git a/Implementation/src/Protocoles/RunnerEcouteUDP.java b/Implementation/src/Protocoles/RunnerEcouteUDP.java deleted file mode 100644 index 7810123..0000000 --- a/Implementation/src/Protocoles/RunnerEcouteUDP.java +++ /dev/null @@ -1,16 +0,0 @@ -package src.Protocoles; - -import src.Controller.ChatApp; - -public class RunnerEcouteUDP implements Runnable { - ChatApp app ; - public RunnerEcouteUDP(ChatApp app) { - this.app = app ; - } - @Override - public void run() { - - UDPEchange.ecouteUDP(app); - - } -} \ No newline at end of file diff --git a/Implementation/src/Protocoles/TCPEchange.java b/Implementation/src/Protocoles/TCPEchange.java deleted file mode 100644 index 77c8be5..0000000 --- a/Implementation/src/Protocoles/TCPEchange.java +++ /dev/null @@ -1,320 +0,0 @@ -package src.Protocoles; - -import java.io.InputStream; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.OutputStream; -import java.net.DatagramSocket; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; -import java.util.NoSuchElementException; -import java.util.Scanner; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import src.Controller.*; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -/** -*-* Classe representant les échanges TCP entre utilisateurs. -*
-*/ -public class TCPEchange { - - /** - *- * Equivalent a un handshake. - * L'utilisateur associé a app souhaite entamé une discussion avec User2 - * @param app L'app associé à l'utilisateur qui souhaite entamé la discussion - * @param User2 Le destinataire - *
- */ - public static void demarrerSession(ChatApp app,Utilisateur User2 ) throws IOException { - System.out.println("Demmarrage d'une session de clavardage"); - Socket s = new Socket(User2.getIp(),5000); - System.out.println("Socket de demarrage d'une session cree"); - //ExecutorService exec = Executors.newFixedThreadPool(1000); - Thread t1 = new Thread(new RunnerTCPEcoute(s,app)); - Thread t2 = new Thread(new RunnerTCPEnvoi(s,app,User2,false)); - t1.start(); - t2.start(); - try { - t1.join(); - t2.join(); - }catch(InterruptedException e) { - System.out.println("Un thread s'est arrete brusquement"); - } - System.out.println("Tout s'est passe creme"); - app.getHist(User2.getPseudo()).afficher10derniers(); - - } - - /*public static void envoiTCP(ChatApp app,Utilisateur User2, String Msg, int type ) { - // On cree un messagehorodate - MessageHorodate mh = new MessageHorodate(app.getMe(), User2, Msg, type); - if( type == 1 ) { - // on ajoute le msg à son historique - Historique h = app.getHist(User2.getPseudo()); - h.addMessage(mh); - // on update la liste des historiques de app - app.majHistorique(h); - } - - try { - Socket s = new Socket(User2.getIp(), User2.getPort()); - PrintStream output = new PrintStream(s.getOutputStream()); - output.println(mh.toString()); - output.close(); - s.close(); - } catch (Exception e) { - e.printStackTrace(); - } - }*/ - - - /** - *- * Méthode pour qu'un objet de la classe ChatApp soit constamment en écoute de potentielles connexions - * @param app L'utilisateur en écoute de potentielles communications - *
- */ - public static void ecouteTCP(ChatApp app) { - ServerSocket ss = null; - ExecutorService exec = Executors.newFixedThreadPool(1000); - System.out.println("Ecoute TCP activee"); - try { - ss = new ServerSocket(5000); // On ecoute sur le port 5000 - System.out.println("Socket d'ecoute cree"); - while(true) { // Ecoute en boucle - System.out.println("Attente Session de clavardage"); - Socket link = ss.accept(); // Blocante - exec.submit(new RunnerTCPEcoute(link,app)); // On crée un thread qui va gerer la connexion recu - System.out.println("L'ecoute TCP continue apres le premier thread demarre"); - } - } - catch (Exception e) { - e.printStackTrace(); - } - } -} - - -/** -*-* Classe representant les threads s'occupant de l'envoie de messages en utilisant le protocole TCP. -* Cette classe implemente l'interface Runnable. -*
-*/ -class RunnerTCPEnvoi implements Runnable { - private Socket link; - private ChatApp app ; - private Utilisateur Destinataire; - final BufferedReader in; - final PrintWriter out; - final Scanner sc=new Scanner(System.in); - private boolean bonjourEnvoye = false; - - /** - *- * Constructeur de la classe RunnerTCPEnvoi - * @param link - * @param app Un objet ChatApp dont l'utilisateur associé souhaite entame une discussion - * @param user2 Destinataire - * @param bonjour Boolean true si c'est le debut d'une connexion, false sinon - *
- */ - public RunnerTCPEnvoi(Socket link,ChatApp app, Utilisateur user2, boolean bonjour ) throws IOException { - this.link = link; - this.app = app; - this.Destinataire = user2; - this.out = new PrintWriter(link.getOutputStream()); - this.in = new BufferedReader (new InputStreamReader (link.getInputStream())); - this.bonjourEnvoye = bonjour; - } - - @Override - public void run() { - System.out.println("Creation d'un thread d'envoi"); - String msg; - - while(true){ - if(!bonjourEnvoye) { // bonjourEnvoye est a false si c'est le debut d'une communication - MessageHorodate mh = new MessageHorodate(Destinataire,app.getMe(),"Bonjour",2); - bonjourEnvoye = true; - System.out.println("Envoi d'un bonjour"); - out.println(mh); - out.flush(); - } - else { - try { - msg = sc.nextLine(); - }catch(NoSuchElementException e) { - break; - } - MessageHorodate mh = new MessageHorodate(Destinataire,app.getMe(),msg,1); - if(msg.equals("--STOP--")) { - mh = new MessageHorodate(Destinataire,app.getMe(),msg,0); // ENVOYER JUSTE --STOP-- SUFFIT - out.println(mh); - out.flush(); - break; - } - /* while(!app.isHistoriqueAvailable()) { - try{wait(); - }catch(InterruptedException e) {} - }*/ - //app.setHistoriqueAvailable(false); - synchronized( this.app.getMapHistorique()) { - Historique h = app.getHist(Destinataire.getPseudo()); - h.addMessage(mh); - app.majHistorique(h); - } - - // on update la liste des historiques de app - - //app.majHistorique2(mh.toString(),Destinataire.getPseudo()); - //app.setHistoriqueAvailable(false); - //notifyAll(); - out.println(mh); - System.out.println("Envoi d'un mesage"); - out.flush(); - } - } - try { - System.out.println("Fermeture du thread d'envoi"); - in.close(); - link.close(); - }catch(Exception e) { - // Gestion de l'exception de la fermeture de la socket - } -} - -} - - - -/** -*-* Classe representant les threads s'occupant de la reception de messages en utilisant le protocole TCP. -* Cette classe implemente l'interface Runnable. -*
-*/ -class RunnerTCPEcoute implements Runnable { - final Socket link; - private ChatApp app ; - private Utilisateur u2; - private boolean u2Initialise; - public RunnerTCPEcoute(Socket link,ChatApp app ) { - this.link = link; - this.app = app; - this.u2Initialise=false; - } - - @Override - public void run() { - System.out.println("Creation d'un thread d'ecoute"); - try { - PrintStream output = new PrintStream(link.getOutputStream()); - //InputStream is = link.getInputStream(); - BufferedReader in = new BufferedReader (new InputStreamReader (link.getInputStream())); - - String line = ""; - String dest = ""; - String src = ""; - String type = ""; - String date = ""; - String payload = ""; - String msg = ""; - line = in.readLine(); - while (line != null) { - - - if(line.split("::")[0].equals("Destinataire")) { - if(msg.equals("")) { - dest = line+"\n"; - msg="."; - } - else { - msg=dest+src+type+date+payload; - payload = ""; - MessageHorodate mh = MessageHorodate.stringToMessageHorodate(msg); - System.out.println("Type du message:"+mh.getType()); - if(mh.getType()==1) { - /*while(!app.isHistoriqueAvailable()) { - try{wait(); - }catch(InterruptedException e) {} - } - app.setHistoriqueAvailable(false);*/ - System.out.println("Historique mis à jour lors de la reception"); - Historique h = app.getHist(mh.getSource().getPseudo()); - h.addMessage(mh); - app.majHistorique(h); - //app.setHistoriqueAvailable(true); - //notifyAll(); - //app.majHistorique2(mh,mh.getSource().getPseudo()); - } - else if(mh.getType()==0) { - break; - } - - } - } - else if(line.split("::")[0].equals("Source")) { - src = line+"\n"; - if(!u2Initialise) { - u2=Utilisateur.stringToUtilisateur(src.split("::")[1].replaceAll("\n", "")); - System.out.println("u2Initialise !"); - u2Initialise = true; - } - } - else if(line.split("::")[0].equals("Type")) { - if(line.split("::")[1].equals("2")) { - System.out.println("Bonjour recu!"); - //System.out.println(src.split("::")[1].replaceAll("\n", "")); - u2=Utilisateur.stringToUtilisateur(src.split("::")[1].replaceAll("\n", "")); - u2Initialise = true; - System.out.println("Pseudo du poto: >>"+u2.getPseudo()+"<<"); - Thread t = new Thread(new RunnerTCPEnvoi(link,app,u2,true)); - t.start(); - System.out.println("Thread d'envoi envoye"); - } - type = line+"\n"; - } - else if(line.split("::")[0].equals("Date")) { - date = line+"\n"; - } - else if(line.split("::")[0].equals("Message")){ - payload = line+"\n"; - - } - else { - payload += line+"\n"; - } - - System.out.println("Received: "+ line); - line = in.readLine(); - - - } - System.out.println("Affichage de l'histo"); - System.out.println("Pseudo du poto: >>"+u2.getPseudo()+"<<"); - app.getHist(u2.getPseudo()).afficher10derniers(); - in.close(); - link.close(); - } catch (IOException e) { - //e.printStackTrace(); - } finally { - System.out.println("Finishing thread"); - System.out.println("Affichage de l'histo"); - System.out.println("Pseudo du poto: >>"+u2.getPseudo()+"<<"); - app.getHist(u2.getPseudo()).afficher10derniers(); - - - } - - } - } diff --git a/Implementation/src/Protocoles/UDPEchange.java b/Implementation/src/Protocoles/UDPEchange.java deleted file mode 100644 index 4652a0d..0000000 --- a/Implementation/src/Protocoles/UDPEchange.java +++ /dev/null @@ -1,358 +0,0 @@ -package src.Protocoles; - -import java.io.IOException; - -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.net.Inet4Address; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import src.Controller.*; -/** -*-* Classe representant les echanges UDP entre utilisateurs. -*
-*/ - -public class UDPEchange { - - private static Boolean Connecte = true; - // True si l'utilisateur peut se connecter avec ce nom d'utilisateur , False sinon - - /** - * Getter - * @return le boolean connecte (True s'il peut se connecter avec ce nom d'utilisateur , False sinon) - */ - public static Boolean getConnecte() { - return Connecte; - } - - /** - * Setter - * @param value La nouvelle valeur du boolean de connexion - */ - public static void setConnecte(Boolean value) { - Connecte = value ; - } - - private static Boolean PseudoValide = true; - // True si l'utilisateur a (ou demande) un pseudo valide , False sinon - - /** - * Getter - * @return le boolean PseudoValide (True s'il peut utiliser ce pseudo , False sinon) - */ - public static Boolean getPseudoValide() { - return PseudoValide; - } - - /** - * Setter - * @param value La nouvelle valeur du boolean concernant le pseudo valide - */ - public static void setPseudoValide(Boolean value) { - PseudoValide = value ; - } - - - - public static InetAddress getCurrentIp() { - try { - Enumeration- * Méthode permettant d'envoyer un message à tout les utilisateurs - * a l'aide du protocole UDP - *
- * @param broadcastMessage correspond au message a transmettre aux utilisateurs - */ - public static void EnvoiBroadcast(String broadcastMessage) throws IOException { - int port = 1234 ; - // Envoie en broadcast à tous les utilsateurs - for (InetAddress broadcastAddr : listAllBroadcastAddresses()) { - DatagramSocket socket = new DatagramSocket(); - socket.setBroadcast(true); - byte[]buffer = broadcastMessage.getBytes(); - DatagramPacket packet = new DatagramPacket( buffer, buffer.length, broadcastAddr,port); - socket.send(packet); - socket.close(); - System.out.println("Broadcast sent with address " + broadcastAddr.toString()); - System.out.println("***********Message envoye***********"); - System.out.println("Dest Ip: " + broadcastAddr.toString()); - System.out.println("Dest port: " + String.valueOf(port)); - System.out.println("Contenu: "); - System.out.println(broadcastMessage); - System.out.println("************************************"); - } - } - - /** - *- * Methode permettant la reception de messages d'utilisateurs - * a l'aide du protocole UDP - *
- * @param app L'application de chat de l'utilisateur qui receptionne le message - */ - public static void ecouteUDP(ChatApp app) - { - DatagramSocket socket = null; - ExecutorService exec = Executors.newFixedThreadPool(1000); - try { - socket = new DatagramSocket(1234); - } catch (SocketException e1) { - e1.printStackTrace(); - } - byte buffer[] = new byte[1024]; - System.out.println("Ecoute sur le port: 1234"); - while(true) - { - DatagramPacket data = new DatagramPacket(buffer,buffer.length); - try { - socket.receive(data); - } catch (IOException e) { - e.printStackTrace(); - } - // Un thread est lance à chaque reception d'un message - System.out.println("Message recu!"); - exec.submit(new RunnerUDP(data,app)); - } - } - - /** - *- * Methode permettant d'envoyer un message a utilisateur en particulier - * a l'aide du protocole UDP - *
- * @param Adress l'addresse de l'utilisateur - * @param Message correspond au message à transmettre a l'utilisateur - */ - public static void envoiUnicast( InetAddress Adress , String Message ) throws IOException { - DatagramSocket socket = new DatagramSocket(); - byte[]buffer = Message.getBytes(); - DatagramPacket packet = new DatagramPacket( buffer, buffer.length, Adress, 1234 ); - socket.send(packet); - socket.close(); - System.out.println("***********Message envoye***********"); - System.out.println("Dest Ip: " + Adress.toString()); - System.out.println("Dest port: " + String.valueOf(1234)); - System.out.println("Contenu: "); - System.out.println(Message); - System.out.println("************************************"); - } - - /** - *- * Methode permettant de recuperer la liste des adresses de broadcast, chacune associer à une interface de la machine - *
- */ - static List-* Classe implementant l'interface Runnable. -* Contient les traitements a executer dans un thread lancer par des methodes de la class UDPEchange -*
-*/ -class RunnerUDP implements Runnable { - final DatagramPacket data ; - ChatApp app ; - - public RunnerUDP(DatagramPacket data, ChatApp app) { - this.data= data; - this.app = app ; - } - - /** - *- * Methode qui redefinie les traitements qui seront executes dans le thread: - * Met à jour la liste des utilisateurs actifs - *
- * - */ - @Override - public void run() { - System.out.println("Thread started"); - String received = new String(data.getData(), 0, data.getLength()); - System.out.println("***********Message recu***********"); - System.out.println(received); - System.out.println("**********************************"); - String Type = received.split("\n")[0]; - - //**************************************************************************************************** - //**************************************************************************************************** - //****************************************Demande de connexion**************************************** - //**************************************************************************************************** - //**************************************** - if (Type.equals("Connexion")) { // un utilisateur vient d'arriver sur le reseau - System.out.println("Reception d'une demande de connexion"); - Utilisateur u = Utilisateur.stringToUtilisateur(received.split("\n")[1]); - if (! u.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même - String reponse = "Reponse Connexion\n"; - if (!( app.getActifUsers() ).verifierUnicite(u.getPseudo())) { - System.out.println("Pseudo deja present dans la liste"); - reponse += "false\n"; - } - else { - System.out.println("Ajout d'un nouvel utilisateur dans la liste des Utilisateurs"); - ( app.getActifUsers() ).addList(u); - reponse += "true\n"; - - } - reponse += app.getMe().toString(); - - try { - UDPEchange.envoiUnicast(u.getIp(),reponse); - }catch(IOException e) - { - System.out.println("Echec de l'envoi du message"); - } - - ( app.getActifUsers() ).afficherListeUtilisateurs(); - } - } - //******************************************************************************************************* - //******************************************************************************************************* - //****************************************Reponse d'une connexion**************************************** - //******************************************************************************************************* - //******************************************************************************************************* - - if (Type.equals("Reponse Connexion")) { // Un utilisateur te repond suite à ta demande de connexion - - if((received.split("\n")[1]).equals("true")) { - Utilisateur u = Utilisateur.stringToUtilisateur(received.split("\n")[2]); - app.getActifUsers().addList(u); - app.getActifUsers().afficherListeUtilisateurs(); - } - else { - System.out.println("Pseudo deja pris"); - UDPEchange.setConnecte(false); - } - } - - //******************************************************************************************************************* - //******************************************************************************************************************* - //****************************************Demande de modification d'un pseudo**************************************** - //******************************************************************************************************************* - //******************************************************************************************************************* - - if (Type.equals("Demande Modification Pseudo")) { - Utilisateur Source = Utilisateur.stringToUtilisateur(received.split("\n")[1]); - if (! Source.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même - String nouveau = received.split("\n")[2] ; - String Message = ""; - if(( app.getActifUsers() ).verifierUnicite(nouveau)) { - Message = "Bon Choix Pseudo\n" + nouveau ; - } - else { - Message = "Mauvais Choix Pseudo\n" ; - } - System.out.println(Message); - try { - UDPEchange.envoiUnicast(Source.getIp(),Message); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - //************************************************************************************************************ - //************************************************************************************************************ - //**************************************** Modification pseudo reussi **************************************** - //************************************************************************************************************ - //************************************************************************************************************ - - if (Type.equals("Modification pseudo reussi")) { - Utilisateur Source = Utilisateur.stringToUtilisateur(received.split("\n")[1]); - if (! Source.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même - String nouveau = received.split("\n")[2] ; - if(app.getActifUsers().appartient(Source)) { // On verifie d'abord que Source appartient bien a la liste des utilisateurs actifs - app.getActifUsers().modifierList(Source.getPseudo(), nouveau); - } - { - // Suite a une perte d'un message lors d'une connexion l'utilisateur Source n'apparait pas dans la liste - app.getActifUsers().addList(Source); - } - } - } - //********************************************************************************************************* - //********************************************************************************************************* - //****************************************Mauvais choix d'un pseudo**************************************** - //********************************************************************************************************* - //********************************************************************************************************* - if (Type.equals("Mauvais Choix Pseudo")) { - System.out.println("Ce choix de pseudo est déjà pris il te faut en choisir un autre"); - UDPEchange.setPseudoValide(false); - } - - //****************************************************************************************************************** - //****************************************************************************************************************** - //****************************************Bon choix d'un pseudo***************************************************** - //****************************************************************************************************************** - //****************************************************************************************************************** - - if (Type.equals("Bon Choix Pseudo")) { - // Il n'y a rien a faire ici - } - - //********************************************************************************************************* - //********************************************************************************************************* - //****************************************Demande d'une deconnexion**************************************** - //********************************************************************************************************* - //********************************************************************************************************* - - if (Type.equals("Deconnexion")) { - ( app.getActifUsers() ).supprimerList(Utilisateur.stringToUtilisateur(received.split("\n")[1])); - } - } - - - - -} diff --git a/Implementation/src/View/View_Accueil.java b/Implementation/src/View/View_Accueil.java deleted file mode 100644 index 3f349cb..0000000 --- a/Implementation/src/View/View_Accueil.java +++ /dev/null @@ -1,133 +0,0 @@ -package src.View; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.IOException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTextField; -import javax.swing.SwingConstants; - -import src.Controller.*; -import src.Protocoles.*; - - -/* - * Classe represenyant la fenetre d'accueil pour la connexion d'un utilisateur. - */ -public class View_Accueil implements ActionListener{ - JFrame frame; - JPanel panel; - JTextField pseudofield; - JLabel Text; - JButton Connexion; - - /* - * Constructeur d'une fenetre d'affichage pour la connexion d'un utilisateur. - * Cette fenetre sera munie d'un bouton de connexion et d'une zone de saisie de pseudo. - */ - public View_Accueil () { - //creer une instance JFrame - frame = new JFrame("ChatApp-AL-NM"); - //sortir quand l’utilisateur ferme le frame - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - // fixer les dimensions de la fenetre - frame.setSize(new Dimension(120, 40)); - //Creer le JPanel - panel = new JPanel(new GridLayout(3,1)); - //Ajouter les elements - this.addWidgets(); - //Set the default button. - frame.getRootPane().setDefaultButton(Connexion); - //Ajouter le panel a la window - frame.getContentPane().add(panel, BorderLayout.CENTER); - //L'utilisateur ne pourra pas aggrandir la fenetre - this.frame.setResizable(false); - //Afficher la fenetre - frame.pack(); - frame.setVisible(true); - } - - /** - * Creer et ajouter les outils de la fenetre - */ - private void addWidgets() { - // Créer Zone d'insertion de texte pour le pseudo - this.pseudofield = new JTextField(2); - // creation d'un label qui contiendra un txt au centre - this.Text = new JLabel("Bonjour, Entrez un nom d'utilisateur!", SwingConstants.CENTER); - //Ajout d'un bouton Connexion - this.Connexion = new JButton("Connexion"); - //On associe au bouton Connexion des actions a realiser - this.Connexion.addActionListener(this); - // On ajouter les differents elements au panel - panel.add(pseudofield); - panel.add(Text); - panel.add(Connexion); - //ajouter un effet de bord transparent au composant Jlabel - Text.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); - } - - /* - * Definir des traitements en réponse à un clic sur le bouton connexion - * @param event Un clic sur le bouton connexion - */ - public void actionPerformed(ActionEvent event) { - // on recupere le texte entree dans la zone de saisie - String pseudo = pseudofield.getText(); - // On crée un objet de type ChatApp - ChatApp app = new ChatApp(pseudo, 3000) ; - // on crée un thread qui va ecouter les connexions entrantes - ExecutorService execUDP = Executors.newFixedThreadPool(1000); - execUDP.submit(new RunnerEcouteUDP(app)); - Boolean connexion = false ; - try { - // on tente une connexion avec ce pseudo - connexion = app.connexion(); - } catch (IOException e) { - e.printStackTrace(); - } - // Dans les deux cas de figures (reussite ou echec) on affiche un pop-up pour expliquer la situation - if(connexion) { - // La connexion a reussi - JOptionPane.showMessageDialog(frame, "Bonjour " + pseudo) ; - frame.dispose(); - // on lance une nouvelle fenetre de type View_Menu - View_Menu fenetreCourante= new View_Menu(app); - } - else { - // La connexion a echoue, il est possible de rentrer un nouveau pseudo - JOptionPane.showMessageDialog(frame, "Echec de Connexion , ce pseudo est deja pris !"); - } - } - - private static void createAndShowGUI() { - // Etre certain d'avoir une joli fenetre - JFrame.setDefaultLookAndFeelDecorated(true); - // On crée une fentre d'acceuil - View_Accueil fenetre = new View_Accueil(); - } - - public static void main(String[] args) { - //Schedule a job for the event-dispatching thread: - //creating and showing this application's GUI. - javax.swing.SwingUtilities.invokeLater(new Runnable() { - public void run() { - createAndShowGUI(); - } - }); - } - -} diff --git a/Implementation/src/View/View_Clavardage.java b/Implementation/src/View/View_Clavardage.java deleted file mode 100644 index 767ec92..0000000 --- a/Implementation/src/View/View_Clavardage.java +++ /dev/null @@ -1,167 +0,0 @@ -package src.View; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.IOException; - -import javax.swing.BoxLayout; -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.SwingConstants; - -import src.Controller.*; - -import java.awt.GridBagLayout; -import java.awt.Font; -import java.awt.Color; -import java.awt.GridBagConstraints; -import java.awt.Insets; - -/* - * Classe representant la fenetre pour chaque session de clavardage. - */ -public class View_Clavardage { - JFrame frame ; - ChatApp app; - Utilisateur destination ; // Celui avec qui on va discuter - Utilisateur source; //Nous - WindowAdapter wa ; - JPanel panel ; - JTextArea textAreaAffichage ; - - /* - * Constructeur d'une fenetre de session de clavardage. - * @param app Un objet de type ChatApp pour posseder toutes les informations de l'utilisateur - * @param User2 L'utilisateur avec qui l'on souhaite discuter et passer en parametre sous forme de String - */ - public View_Clavardage(ChatApp app, String User2) { - this.app = app ; - this.frame = new JFrame("ChatApp-AL-NM"); - this.source = this.app.getMe(); - this.destination = Utilisateur.stringToUtilisateur(User2); - this.frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); - // fixer les dimensions de la fenetre - this.frame.setSize(new Dimension(394, 344)); - this.frame.setResizable(false); - wa = new WindowAdapter(){ - public void windowClosing(WindowEvent e){ - int reponse = View_Menu.showConfirmDialog(); - if (reponse==0){ - frame.dispose(); - } - }}; - addWidgets(); - frame.addWindowListener( wa ) ; - frame.setVisible(true); - } - - /** - * Creer et ajouter les outils de la fenetre - */ - private void addWidgets() { - GridBagLayout gridBagLayout = new GridBagLayout(); - gridBagLayout.columnWidths = new int[]{394, 0}; - gridBagLayout.rowHeights = new int[]{16, 220, 74, 0}; - gridBagLayout.columnWeights = new double[]{0.0, Double.MIN_VALUE}; - gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE}; - this.frame.getContentPane().setLayout(gridBagLayout); - this.panel = new JPanel(); - // Zone pour ecrire de nouveau message - JTextArea textAreaSaisie = new JTextArea(5,3); - textAreaSaisie.setLineWrap(true); - textAreaSaisie.setForeground(Color.LIGHT_GRAY); - textAreaSaisie.setFont(new Font("Lucida Grande", Font.ITALIC, 11)); - textAreaSaisie.setText("Entrer du texte ici !!!"); - JScrollPane scrollPane = new JScrollPane(textAreaSaisie); - // Creation d'un bouton envoye - JButton send = new JButton("Envoye"); - frame.getRootPane().setDefaultButton(send); - send.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent event) { - //UTILISER TCPENVOI - String AEnvoyer = textAreaSaisie.getText(); - textAreaAffichage.append(AEnvoyer); - textAreaSaisie.setText(""); - }}); - // Creation d'un bouton vider la zone de saisie de texte - JButton reset = new JButton("Vider"); - reset.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent event) { - textAreaSaisie.setText(""); - }}); - JLabel titre = new JLabel("Chat avec "+ this.destination.getPseudo(),SwingConstants.CENTER); - GridBagConstraints gbc_titre = new GridBagConstraints(); - gbc_titre.anchor = GridBagConstraints.NORTH; - gbc_titre.fill = GridBagConstraints.HORIZONTAL; - gbc_titre.insets = new Insets(0, 0, 5, 0); - gbc_titre.gridx = 0; - gbc_titre.gridy = 0; - frame.getContentPane().add(titre, gbc_titre); - // Zone d'affichage de l'historique - this.textAreaAffichage = new JTextArea(10,5); - textAreaAffichage.setLineWrap(true); - this.textAreaAffichage.setText(""); - JScrollPane scrollPaneAffichage = new JScrollPane(this.textAreaAffichage); - this.textAreaAffichage.setEditable(false); // il sert juste a afficher - GridBagConstraints gbc_textAreaAffichage = new GridBagConstraints(); - gbc_textAreaAffichage.fill = GridBagConstraints.BOTH; - gbc_textAreaAffichage.insets = new Insets(0, 0, 5, 0); - gbc_textAreaAffichage.gridx = 0; - gbc_textAreaAffichage.gridy = 1; - frame.getContentPane().add(scrollPaneAffichage, gbc_textAreaAffichage); - panel.add(BorderLayout.CENTER, scrollPane); - panel.add(BorderLayout.SOUTH,send); - panel.add(BorderLayout.SOUTH,reset); - panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); - //Add the panel to the window. - GridBagConstraints gbc_panel = new GridBagConstraints(); - gbc_panel.anchor = GridBagConstraints.NORTH; - gbc_panel.fill = GridBagConstraints.HORIZONTAL; - gbc_panel.gridx = 0; - gbc_panel.gridy = 2; - frame.getContentPane().add(panel, gbc_panel); - /* - * - *JTextArea textAreaAffichage = new JTextArea(10,5); - textAreaAffichage.setEditable(false); - JTextArea textAreaSaisie = new JTextArea(10,5); - textAreaSaisie.setForeground(Color.LIGHT_GRAY); - textAreaSaisie.setFont(new Font("Lucida Grande", Font.ITALIC, 11)); - textAreaSaisie.setText("Entrer du texte ici !!!"); - JScrollPane scrollPane = new JScrollPane(textAreaSaisie); - JButton send = new JButton("Envoye"); - frame.getRootPane().setDefaultButton(send); - send.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent event) { - //UTILISER TCPENVOI - textAreaSaisie.setText(""); - }}); - JButton reset = new JButton("Vider"); - reset.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent event) { - textAreaSaisie.setText(""); - }}); - JLabel titre = new JLabel("Chat avec "+ this.destination.getPseudo(),SwingConstants.CENTER); - panel.add(BorderLayout.CENTER, scrollPane); - //panel.add(scrollPane); - panel.add(BorderLayout.SOUTH,send); - panel.add(BorderLayout.SOUTH,reset); - panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); - //Add the panel to the window. - frame.getContentPane().add(BorderLayout.SOUTH, panel); - frame.getContentPane().add(BorderLayout.CENTER, textAreaAffichage); - frame.getContentPane().add(BorderLayout.NORTH, titre); - */ - } - - -} diff --git a/Implementation/src/View/View_Menu.java b/Implementation/src/View/View_Menu.java deleted file mode 100644 index 3ffea35..0000000 --- a/Implementation/src/View/View_Menu.java +++ /dev/null @@ -1,256 +0,0 @@ -package src.View; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.util.Vector; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import javax.imageio.ImageIO; -import javax.swing.AbstractAction; -import javax.swing.BorderFactory; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JTextArea; -import javax.swing.JTextField; -import javax.swing.SwingConstants; - -import src.Controller.*; - -import java.awt.Font; -import java.awt.Color; -import java.awt.ComponentOrientation; -import java.awt.SystemColor; - -/* - * Classe representant la fenetre de menu. Lance apres la connexion d'un utilisateur - */ -public class View_Menu { - JFrame frame; - JPanel panel; - JMenuBar menu; - ChatApp app; - JLabel jlabel; - JLabel Txt; - WindowAdapter wa ; - - /* - * Constructeur d'une fenetre de menu apres la connexion d'un utilisateur. - * @param app Un objet de type ChatApp pour posseder toutes les informations de l'utilisateur - */ - public View_Menu(ChatApp app) { - this.app = app ; - //creer une instance JFrame - frame = new JFrame("ChatApp-AL-NM"); - frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); - // fixer les dimensions de la fenetre - frame.setSize(new Dimension(394, 344)); - // Lorsque l'utilisateur souhaite quitter la fenetre on affiche un pop-up pour verifier son choix - wa = new WindowAdapter(){ - public void windowClosing(WindowEvent e){ - int reponse = showConfirmDialog(); - if (reponse==0){ - try { - // on deconnecte l'app avant de quitter - // Tout les utilisateurs sont donc prevenus du depart - app.deconnexion(); - } catch (IOException e1) { - e1.printStackTrace(); - } - frame.dispose(); - } - }}; - frame.addWindowListener( wa ) ; - // Menu pour les differentes actions réalisables - menu = new JMenuBar(); - //Creation d'un JPanel - panel = new JPanel(new GridLayout(3,1)); - panel.setForeground(SystemColor.menuText); - // Ajouter tout les elements a la fenetre - this.addWidgets(); - // ajouter le panel a la fenetre - frame.getContentPane().add(panel, BorderLayout.CENTER); - // Afficher la fenetre - frame.pack(); - frame.setVisible(true); - } - - /** - * Methode static creant un pop-up demandant a l'utilisateur si il souhaite vraiment quitter. - */ - static int showConfirmDialog(){ - return JOptionPane.showConfirmDialog( - null, - "Voulez-vous vraiment quitter?", - "Quitter", - JOptionPane.YES_NO_OPTION); - } - /** - * Creer et ajouter les outils de la fenetre - */ - private void addWidgets() { - // On ajoute une jolie icone - jlabel = new JLabel(new ImageIcon("/Users/auriane/Desktop/ChatApp-AL-NM/Implementation/src/images/Logo.png"), JLabel.CENTER); - - Txt = new JLabel("Menu principal de " + app.getMe().getPseudo()); - Txt.setFont(new Font("Tamil MN", Font.PLAIN, 30)); - Txt.setHorizontalAlignment(SwingConstants.CENTER); - - //On cree une item Actions que l'on ajoutera a la bar de menu - JMenu Actions = new JMenu("Actions"); - Actions.setForeground(Color.WHITE); - Actions.setHorizontalAlignment(SwingConstants.CENTER); - // Définir le sous-menu pour Actions - JMenuItem actifs = new JMenuItem("Utilisateurs actifs"); - JMenuItem session = new JMenuItem("Session de Clavardage"); - JMenuItem pseudo = new JMenuItem("Modifier Pseudo"); - JMenuItem deconnexion = new JMenuItem("Deconnexion"); - // Ajouter les sous items a actions - Actions.add(actifs); - Actions.add(session); - Actions.add(pseudo); - Actions.add(deconnexion); - // On ajoute l'item Action dans la bar de menu - menu.add(Actions); - // On ajouter les differents elements au panel - panel.add(BorderLayout.NORTH , menu); - panel.add(BorderLayout.CENTER, jlabel); - panel.add(BorderLayout.SOUTH , Txt ); - - //****************************************************************************************************************** - //**************************************** Actions lorsque l'on clique sur actifs ********************************** - //****************************************************************************************************************** - actifs.addActionListener( new ActionListener(){ - public void actionPerformed(ActionEvent event) { - JPanel panel1 = new JPanel(); - JButton home = new JButton(new ImageIcon("/Users/auriane/Desktop/ChatApp-AL-NM/Implementation/src/images/Home.png")); - - JTextArea textArea = new JTextArea(20,20); - textArea.insert("Liste Utilisateurs Actifs \n",0); - JScrollPane scrollPane = new JScrollPane(textArea); - - String utilisateurs = app.getActifUsers().afficherListeUtilisateurs(); - for(String elem : utilisateurs.split("\n")) { - textArea.append( " - " +Utilisateur.stringToUtilisateur(elem).getPseudo() + '\n'); - } - panel1.add(textArea); - home.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent event) { - frame.dispose(); - new View_Menu(app); - } }); - textArea.setEditable(false); - frame.getContentPane().removeAll(); - frame.getContentPane().add(BorderLayout.CENTER, panel1); - frame.getContentPane().add(BorderLayout.NORTH , home); - frame.setVisible(true); - }}); - - //****************************************************************************************************************** - //**************************************** Actions lorsque l'on clique sur Session ********************************* - //****************************************************************************************************************** - session.addActionListener( new ActionListener(){ - public void actionPerformed(ActionEvent event) { - JButton home = new JButton(new ImageIcon("/Users/auriane/Desktop/ChatApp-AL-NM/Implementation/src/images/Home.png")); - home.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent event) { - frame.dispose(); - new View_Menu(app); - } }); - String utilisateurs = app.getActifUsers().afficherListeUtilisateurs(); - Vector