diff --git a/Implementation/.classpath b/Implementation/.classpath
deleted file mode 100644
index e6f7288..0000000
--- a/Implementation/.classpath
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
Constructeur de l'application de chat
+ * + * @param pseudo Pseudo de l'utilisateur + * @param port Port de communication + */ + public ChatApp(String pseudo, Integer port, Application main){ + this.actifUsers = new ListUtilisateurs() ; + // Recuperer adresse IP de l'utilisateur + InetAddress ip = null ; + ip = UDPEchange.getCurrentIp(); + this.me = new Utilisateur(pseudo,port,ip); + this.actifUsers.addList(getMe()); + + this.main = main; + this.db= DataBase.getInstance(); + this.connecte=false; + } + + /** + *Methode permettant de créer qu'une seule instance de chatapp
+ * @param pseudo le pseudonyme que l'on souhaite donner à l'utilisateur + * @param port le port auquel on souhaite receptionner les requêtees UDP + * @param main le stage de l'interface graphique qui crée l'instance + * @return une instance de chatapp + */ + public static synchronized ChatApp getInstance(String pseudo, Integer port, Application main){ + if (chatapp == null) { + chatapp = new ChatApp(pseudo, port, main); + } + return chatapp; + } + + /** + * + * @return recupere l'instance de chatapp qui a ete creee au prealable + */ + public static ChatApp getInstance(){ + return chatapp; + } + + + + /*public void majHistorique2(MessageHorodate mh, String pseudo) { + Historique h = getMapHistorique().get(pseudo); + //h.addMessage(mh); + getMapHistorique().put(h.getUser2().getPseudo(),h); + }*/ + + + /** + *Modification du pseudo de l'utilisateur + * Envoie en broadcast ses informations utilisateurs et son nouveau pseudo
+ * + * @param nouveau correspond au nouveau pseudo + * @return False si modiferPseudo a echoue, True sinon + */ + public Boolean modifierPseudo(String nouveau) throws IOException { + // Message que l'on envoie à tous les utilisateurs actifs + String broadcastMessage = "Demande Modification Pseudo\n" + this.getMe().toString() + "\n" + nouveau + "\n"; + UDPEchange.EnvoiBroadcast(broadcastMessage); + try { + Thread.sleep(2000); + /* L'utilisateur doit attendre la reponse de tous les utilisateurs connectes + * pour savoir si son pseudo est accepte + */ + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (UDPEchange.getPseudoValide()) { + System.out.println("Modification pseudo reussie"); + //Envoi un msg en broadcast a tout les utilisateurs pour les prevenir de son nouveau pseudo// + broadcastMessage = "Modification pseudo reussie\n" + this.getMe().toString() + "\n" + nouveau + "\n"; + UDPEchange.EnvoiBroadcast(broadcastMessage); + //-------Change son propre nom d'utilisateur-------// + this.getActifUsers().modifierList(this.getMe().getPseudo(), nouveau); + this.getMe().setPseudo(nouveau); + db.majPseudo(this.me.getId(),nouveau); + System.out.println("Changement pseudo accepte, nouvelle liste des utilisateurs actifs:"); + this.getActifUsers().afficherListeUtilisateurs(); + return true; + } + else + { + System.out.println("Echec Modification pseudo"); + return false; + } + } + + + /** + *Methode appelee lors de la connexion d'un nouvel utilisateur. + * Il va prevenir les utilisateurs du reseau de son arrivee.
+ * @return False si Connexion a echoue, True sinon + */ + public Boolean connexion() throws IOException { + // Message que l'on envoie à tous les utilisateurs actifs + String broadcastMessage = "Connexion\n" + this.getMe().toString() ; + UDPEchange.EnvoiBroadcast(broadcastMessage); + try { + Thread.sleep(2000); // L'utilisateur doit attendre la reponse de tous les utilisateurs connectes + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (UDPEchange.getConnecte()) { + System.out.println("Connexion reussie"); + return true; + } + else + { + System.out.println("Connexion echoue"); + UDPEchange.setConnecte(true); + return false ; + } + } + + /** + *Methode appelee lors de la connexion de l'utilisateur, va prevenir les autres + * utlisateurs du reseau de l'arrivee de l'utilisateur sur celui-ci
+ * @param pseudo le pseudonyme avec lequel l'utilisateur souhaite se connecter + * @return False si Connexion a echoue, True sinon + * @throws IOException + */ + public Boolean connexion(String pseudo) throws IOException { + // Message que l'on envoie à tous les utilisateurs actifs + this.me.setPseudo(pseudo); + String broadcastMessage = "Connexion\n" + this.getMe().toString() ; + UDPEchange.EnvoiBroadcast(broadcastMessage); + try { + Thread.sleep(2000); // L'utilisateur doit attendre la reponse de tous les utilisateurs connectes + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (UDPEchange.getConnecte()) { + System.out.println("Connexion reussie"); + this.connecte=true; + this.db.ajoutUtilisateurs(this.me.getId(),pseudo); + this.db.majUtilisateursActifs(true,this.me.getId()); + return true; + } + else + { + System.out.println("Connexion echoue"); + UDPEchange.setConnecte(true); + return false ; + } + } + + /** + *Lance un thread pour ecouter les requetes TCP + * Informe le pcs que chatapp ecoute les notifications qu'il envoie
+ */ + public void activerEcouteTCP(){ + this.runnerEcouteTCP = new RunnerEcouteTCP(this); + this.runnerEcouteTCP.addPropertyChangeListener(this); + } + + /** + *Demarre une session de clavardage avec l'utilisateur dont le pseudo est entre en parametre
+ * @param pseudo le pseudo de l'utilisateur avec lequel on souhaite communiquer + */ + public void demarrerSession(String pseudo){ + Utilisateur u2 = this.actifUsers.getPseudoList(pseudo); + SessionClavardage session = new SessionClavardage(u2,this); + runnerEcouteTCP.addSession(session); + } + + /** + *Lance le thread pour receptionner les requetes UDP
+ */ + public void activerEcouteUDP(){ + this.runnerEcouteUDP = new RunnerEcouteUDP(this); + this.runnerEcouteUDP.start(); + } + /** + *Methode appelee lors de la deconnexion de l'utilisateur. + * Il va prevenir les utilisateurs du reseau de son depart.
+ * + */ + public void deconnexion() throws IOException { + // Message que l'on envoie à tous les utilisateurs actifs + String broadcastMessage = "Deconnexion\n" + this.getMe().toString() ; + UDPEchange.EnvoiBroadcast(broadcastMessage); + db.majUtilisateursActifs(false,this.me.getId()); + this.connecte=false; + try { + main.stop(); + } catch (Exception e) { + e.printStackTrace(); + } + Platform.exit(); + System.exit(0); + } + + /** + * Getter + * @return Utilisateur associee a ChatApp + */ + public Utilisateur getMe() { + return me; + } + + /** + * Getter + * @return Liste des utilisateurs actifs associee a ChatApp + */ + public ListUtilisateurs getActifUsers() { + return actifUsers; + } + + + + + /*public static void main (String[] args) throws IOException { + ChatApp app = new ChatApp(args[0],Integer.parseInt(args[1]),this.app) ; + System.out.println("On lance le chatapp"); + + + ExecutorService execUDP = Executors.newFixedThreadPool(1000); + execUDP.submit(new RunnerEcouteUDP(app)); + try { + app.connexion(); + } catch (IOException e) { + e.printStackTrace(); + } + ExecutorService execTCP = Executors.newFixedThreadPool(1000); + System.out.println("On lance l'écoute TCP de chatapp"); + execTCP.submit(new RunnerEcouteTCP(app)); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + if(app.getMe().getPseudo().equals("Marvel")) { + app.getHist("Doudou").afficher10derniers(); + System.out.println("Tentative de connexion avec Doudou"); + TCPEchange.demarrerSession(app, app.actifUsers.getPseudoList("Doudou")); + } + + + + }*/ + + /** + *Handler des differents evenements que chatapp ecoute
+ * @param evt l'evenement qui a ete indique par le pcs + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + switch (evt.getPropertyName()){ + case "chatCreated" : + SessionClavardage session = this.runnerEcouteTCP.getSessionClavardage(); + session.addPropertyChangeListener(this); + break; + } + } + + /** + *Permet de recuperer stage de l'interface graphique qui a cree l'instance
+ * @return le stage de l'interface graphique qui a cree l'instance + */ + public Application getMain() { + return main; + } + + /** + *Permet de recuperer la base de donnee associee
+ * @return la base de donnee associee + */ + public DataBase getDb(){return this.db;} +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Launcher.java b/Implementation/chatapp/src/main/java/chatapp/Launcher.java new file mode 100644 index 0000000..c464364 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Launcher.java @@ -0,0 +1,7 @@ +package chatapp; + +public class Launcher { + public static void main(String[] args) { + Main.main(args); + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Main.java b/Implementation/chatapp/src/main/java/chatapp/Main.java new file mode 100644 index 0000000..776724b --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Main.java @@ -0,0 +1,62 @@ +package chatapp; + +import chatapp.Controller.ChatApp; +import javafx.application.Application; +import javafx.application.Platform; +import javafx.fxml.FXMLLoader; +import javafx.geometry.Rectangle2D; +import javafx.scene.Scene; +import javafx.stage.Screen; +import javafx.stage.Stage; + +import java.io.IOException; + +public class Main extends Application { + ChatApp chatapp; + + /** + * Permet de lancer la fenetre principale de l'application + * @param primaryStage notre fenetre principale + * @throws Exception + */ + @Override + public void start(Stage primaryStage) throws Exception { + Rectangle2D tailleEcran = Screen.getPrimary().getBounds(); + this.chatapp = ChatApp.getInstance("Null",1234,this); + FXMLLoader fichier = new FXMLLoader(getClass().getResource("/fenetres/ConnexionScreen.fxml")); + Scene scene1 = new Scene(fichier.load(),600,400); + primaryStage.setScene(scene1); + primaryStage.setTitle("ChatApp"); + primaryStage.setMinWidth(600); + primaryStage.setMinHeight(400); + //primaryStage.setMaxWidth(600); + //primaryStage.setMaxHeight(400); + /*primaryStage.setMaxWidth(tailleEcran.getWidth()); + primaryStage.setMaxHeight(tailleEcran.getHeight());*/ + primaryStage.show(); + primaryStage.centerOnScreen(); + chatapp.activerEcouteTCP(); + chatapp.activerEcouteUDP(); + + } + + /** + *Handler associe a la fermeture de l'application
+ * @throws Exception + */ + @Override + public void stop() throws Exception { + if(chatapp.isConnecte()){ + chatapp.deconnexion(); + } + else { + super.stop(); + Platform.exit(); + System.exit(0); + } + } + + public static void main(String[] args) { + launch(args); + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java new file mode 100644 index 0000000..a7fbbd6 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java @@ -0,0 +1,482 @@ +package chatapp.Model; + +import java.sql.*; + +/** + *+ * Classe representant la Base de données. + * Celle-ci stocke la liste des utilisateurs ainsi que les échanges entre eux + *
+ */ +public class DataBase { + private final String DBurl = "jdbc:mysql://srv-bdens.insa-toulouse.fr:3306" ; + private Connection connection = null; + private final String login = "tp_servlet_006"; + private final String pswd = "baePh9ei"; + + + /*Format de la table Utilisateurs + +--------+-------------+---------+---------------------+ + | ID | Pseudo | Actif | Date d'inscription | + +--------+-------------+---------+---------------------+ + Id correspond à l'addresse IP + Pseudo : Dernier Pseudo utilisé pour cette adresse IP, va etre remplacé par le pseudo actuel avec majPseudo + Date d'inscription comme son nom l'indique le jour de l'inscription de cette utilisateur + Actif est un boolean indicant si l'utilisateur est actif + + Chaque communication entres utilisateurs sera stocké dans une table de la forme + +------------------+-----------+---------------+---------------+ + | Destinataire | Source | Message | Date d'envoi | + +--------+---------------------+---------------+---------------+ + Destinataire -> Id du destinataire du message + Source -> Id de celui qui envoie le message + Message -> Msg envoye + Date d'envoie -> Date a laquelle Source a envoye le message a destinataire + */ + + private static final DataBase instance = null; // Singleton + + /** + * Constructeur de la database + * On installe le driver et on établit la connection. + */ + public DataBase() { + try { + //Besoin d'installer le driver JDBC entre java IDE et le system DBMS pour faire un pont entre les deux + Class.forName("com.mysql.cj.jdbc.Driver"); + System.out.println("Driver Installe"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + System.out.println("Echec installation Driver"); + } + try { + //Etablir une connexion , forme : (url, "myLogin", "myPassword"); + // Nabil : DECOMMENTER CETTE LIGNE + //this.connection = DriverManager.getConnection("jdbc:mysql://localhost/POO_AL_NM?allowPublicKeyRetrieval=true&useSSL=false", "root", "1234"); + // Auriane : DECOMMENTER CETTE LIGNE + this.connection = DriverManager.getConnection("jdbc:mysql://localhost:8889/POO_AL_NM?allowPublicKeyRetrieval=true&useSSL=false", "root", "root"); + //this.connection = DriverManager.getConnection(this.DBurl,login,pswd); + System.out.println("Connexion Etablie"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec d'etablissement de la connexion"); + } + } + + /** + * Méthode permettant de renvoyer une instance de la classe DataBase + * @return Retourne l'instance du singleton DataBase. + */ + public static DataBase getInstance() { + synchronized (DataBase.class) { + return new DataBase(); + } + } + + /** + * Methode permettant de creer une table pour stocker les messages entre deux utilisateurs + * @param ID1 Id du premier utilisateur + * @param ID2 Id du second utilisateur + */ + public void CreationTableHistorique(String ID1 , String ID2) { + // Pour eviter d'avoir les tables en double + String petit; + String grand; + int comparaison = ID1.compareTo(ID2); + if (comparaison < 0) { + petit = ID1; + grand = ID2 ; + } + else { + petit = ID2; + grand = ID1 ; + } + String nomTable = "Chat_" + petit + "_" + grand ; + String Requete = "CREATE TABLE IF NOT EXISTS`" + nomTable +"` (\n" + "`Destinataire` varchar(100) NOT NULL,\n" + " `Source` varchar(100) NOT NULL,\n" + " `Envoi` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n" + " `Message` text NOT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ;"; + System.out.println(Requete); + PreparedStatement Ps = null ; + //Statement est utilisé pour envoyer une requete SQL à la base de donnee + try { + Ps = connection.prepareStatement(Requete); + System.out.println("Statement cree"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec creation Statement"); + } + //Execute la donnée SQL statement passe en parametre + try { + assert Ps != null; + Ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println(" Echec executeUpdate "); + } + } + + /** + * Methode permettant de mettre a jour le pseudo d'un utilisateur en fonction de son ID dans la base de donnee + * @param ID Id de l'utilisateur qui vient de changer de pseudo + * @param Pseudo Nouveau Pseudo de l'utilisateur + */ + public void majPseudo( String ID , String Pseudo) { + String requete= "UPDATE `Utilisateurs` SET `Pseudo`=? WHERE id=?"; + PreparedStatement Ps = null ; + //Statement est utilisé pour envoyer une requete SQL à la base de donnee + try { + Ps = connection.prepareStatement(requete); + Ps.setString(1, Pseudo); // ? n°1 devient la valeur contenu dans Pseudo + Ps.setString(2, ID); // ? n°2 devient la valeur contenu dans ID + System.out.println("Statement cree"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec creation Statement"); + } + //Execute la donnée SQL statement passe en parametre + try { + assert Ps != null; + Ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println(" Echec executeUpdate "); + } + } + + + + /** + * Methode permettant de mettre a jour le pseudo d'un utilisateur en fonction de son ID dans la base de donnee + * @param IDdest Id de l'utilisateur Destinataire du message + * @param IDsrc Id de celui qui envoi le message + * @param Msg Message envoye entre les deux utilisateurs + */ + public void ajoutHistorique(String IDdest , String IDsrc, String Msg) { + String petit; + String grand; + int comparaison = IDdest.compareTo(IDsrc); + if (comparaison < 0) { + petit = IDdest; + grand = IDsrc ; + } + else { + petit = IDsrc; + grand = IDdest ; + } + String nomTable = "Chat_" + petit + "_" + grand ; + String requete= "INSERT INTO `"+ nomTable +"`(`Destinataire`, `Source`, `Message`) VALUES ( ? , ? , ?)"; + PreparedStatement Ps = null ; + //Statement est utilisé pour envoyer une requete SQL à la base de donnee + try { + Ps = connection.prepareStatement(requete); + Ps.setString(1, IDdest); // ? n°1 devient la valeur contenu dans IDdest + Ps.setString(2, IDsrc); // ? n°2 devient la valeur contenu dans IDsrc + Ps.setString(3, Msg); // ? n°3 devient la valeur contenu dans Msg + //La date de l'envoi n'a pas besoin d'être renseigné, elle est automatique + System.out.println("Statement cree"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec creation Statement"); + } + //Execute la donnée SQL statement passe en parametre + try { + assert Ps != null; + Ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println(" Echec executeUpdate "); + } + } + + + /** + * Methode permettant d'ajouter un utilisateur dans la base de donnée si celui-ci n'existe pas deja + * @param ID Id de l'utilisateur que l'on veut rajouter + * @param Pseudo pseudo actuelle de l'utilisateur + */ + public void ajoutUtilisateurs(String ID , String Pseudo ) { + if(this.idExiste(ID)){ + this.majPseudo(ID, Pseudo); + } + else { + // L'utilisateur n'existe pas , on va le rajouter. + System.out.println("On rajoute l'utilisateur " + Pseudo); + String requete = "INSERT INTO `Utilisateurs` (`ID`, `Pseudo`, `Actif`) VALUES ( ? , ? , '1')"; + PreparedStatement Ps = null; + //Statement est utilisé pour envoyer une requete SQL à la base de donnee + try { + Ps = connection.prepareStatement(requete); + Ps.setString(1, ID); // ? n°1 devient la valeur contenu dans ID + Ps.setString(2, Pseudo); // ? n°2 devient la valeur contenu dans Pseudo + System.out.println("Statement cree"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec creation Statement"); + } + //Execute la donnée SQL statement passe en parametre + try { + assert Ps != null; + Ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println(" Echec executeUpdate "); + } + } + } + + /** + * Methode permettant de mettre a jour les utilisateurs actuellement actif + * @param Id Id de l'utilisateur qui vient de se connecter ou deconnecter + * @param Connecte Boolean true si il est connecte , false sinon + */ + public void majUtilisateursActifs(Boolean Connecte, String Id) { + String requete= "UPDATE `Utilisateurs` SET `Actif`=? WHERE id=?"; + PreparedStatement Ps = null ; + int Actif = Connecte ? 1 : 0; // True -> 1 , False -> 0 + //Statement est utilisé pour envoyer une requete SQL à la base de donnee + try { + Ps = connection.prepareStatement(requete); + Ps.setInt(1, Actif); // ? n°1 devient la valeur contenu dans Actif (1 ou 0) + Ps.setString(2, Id); // // ? n°2 devient la valeur contenu dans Id + System.out.println("Statement cree"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec creation Statement"); + } + //Execute la donnée SQL statement passe en parametre + try { + assert Ps != null; + Ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println(" Echec executeUpdate "); + } + } + + /** + * Methode permettant de recuperer les N derniers messages envoyés entre 2 utilisateurs + * @param ID Utilisateur associé a ChatApp + * @param IDdestinataire Celui avec qui correspond ID + * @param N le nombre de messages souhaités + * @return Les N derniers Messages + */ + public String recupNMsg(String ID, String IDdestinataire, int N) { + StringBuilder Msg = new StringBuilder(); + String petit; + String grand; + int comparaison = ID.compareTo(IDdestinataire); + if (comparaison < 0) { + petit = ID; + grand = IDdestinataire; + } + else { + petit = IDdestinataire; + grand = ID ; + } + String nomTable = "Chat_" + petit + "_" + grand ; + String requete = "SELECT * FROM `"+ nomTable +"`"; + Statement stmt = null; + ResultSet rs = null ; + try { + stmt = this.connection.createStatement(); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + try { + assert stmt != null; + rs = stmt.executeQuery(requete); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + Integer Taille = tailleBDD(nomTable); + if(Taille < N ){ + N = Taille ; + } + for(int i = 0 ; i < N; i++){ + try { + assert rs != null; + if( rs.next()){ + String IDSource = rs.getString("Source"); + String Envoi = rs.getTimestamp("Envoi").toString(); + String Message = rs.getString("Message"); + if (IDSource.equals(ID)) Msg.append("Moi (").append(Envoi).append(") : ").append(Message); + else { + String PseudoSource = getPseudo(IDSource) ; + Msg.append(PseudoSource).append(" (").append(Envoi).append(") : ").append(Message); + } + Msg.append('\n'); + } + // MSG de la forme : + // Source (Date) : Texte + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + } + return Msg.toString(); + } + + /** + * Methode permettant de recuperer le pseudo actuel d'un utilisateur en fonction de son ID + * @param idSource Id de l'utilsateur dont on veut connaitre le pseudo + * @return Pseudo + */ + private String getPseudo(String idSource) { + String Pseudo = "" ; + String requete= "SELECT * FROM `Utilisateurs` WHERE `ID` LIKE '" + idSource + "'"; + Statement stmt = null; + ResultSet rs = null ; + try { + stmt = this.connection.createStatement(); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + try { + assert stmt != null; + rs = stmt.executeQuery(requete); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + try { + assert rs != null; + if (rs.next()){ + Pseudo = rs.getString("Pseudo") ; + } + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + return Pseudo ; + } + + /** + * Methode permettant de recuperer les messages d'une plage de donnée [deb,fin] envoyés entre 2 utilisateurs + * @param ID Utilisateur associé a ChatApp + * @param IDdestinataire Celui avec qui correspond ID + * @param deb On veut les messages à partir de l'indice deb + * @param fin On veut les messages jusqu'a l'indice fin + * @return Les messages d'une plage de donnée [deb,fin] + */ + public String recupMsg(String ID, String IDdestinataire, int deb , int fin) { + StringBuilder Msg = new StringBuilder(); + String petit; + String grand; + int comparaison = ID.compareTo(IDdestinataire); + if (comparaison < 0) { + petit = ID; + grand = IDdestinataire; + } + else { + petit = IDdestinataire; + grand = ID ; + } + String nomTable = "Chat_" + petit + "_" + grand ; + String requete = "SELECT * FROM `"+ nomTable+"`"; + Statement stmt = null; + ResultSet rs = null ; + try { + stmt = this.connection.createStatement(); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + try { + assert stmt != null; + rs = stmt.executeQuery(requete); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + Integer Taille = tailleBDD(nomTable); + if(Taille < fin ){ + fin = Taille ; + } + for(int i = 0 ; i < fin; i++){ + try { + assert rs != null; + if( rs.next()){ + String IDSource = rs.getString("Source"); + String Envoi = rs.getTimestamp("Envoi").toString(); + String Message = rs.getString("Message"); + if (i >= deb) { + if (IDSource.equals(ID)) { + Msg.append("Moi (").append(Envoi).append(") : ").append(Message); + } else { + String PseudoSource = getPseudo(IDSource); + Msg.append(PseudoSource).append(" (").append(Envoi).append(") : ").append(Message); + } + Msg.append('\n'); + } + } + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + } + + return Msg.toString(); + } + + /** + * Cette méthode sert à recuperer la taille d'un base de donnée + * @param nomTable Nom de la table de donnée dont on veut récuperer le nom + * @return Taille de la BDD + */ + public Integer tailleBDD(String nomTable) { + Integer Taille = 0 ; + String requete = "SELECT * FROM `"+nomTable+ "`"; + Statement stmt = null; + ResultSet rs = null ; + try { + stmt = this.connection.createStatement(); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + try { + assert stmt != null; + rs = stmt.executeQuery(requete); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + while(true){ + try { + assert rs != null; + if (!rs.next()) break; + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + Taille++; // on incremente Taille pour chaque solution trouvée + } + return Taille; + } + + /** + * Methode permettant de savoir si un utilisateur existe dans la base de donnée 'Utilisateurs' + * @param ID On recherche l'utilisateur dont l'ID est ID + * @return True si l'utilisateur existe , False sinon + */ + public boolean idExiste(String ID){ + boolean existe = false ; + // Verification que l'utilisateur n'existe pas + String requete = "SELECT * FROM `Utilisateurs` WHERE `ID` LIKE '" + ID +"'"; + Statement stmt; + ResultSet rs = null ; + try { + stmt = this.connection.createStatement(); + rs = stmt.executeQuery(requete); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + existe = (!rs.equals(null)); + return existe; + } + + public String getNomTable(Utilisateur U1, Utilisateur U2){ + String petit; + String grand; + int comparaison; + comparaison = U1.getId().compareTo(U2.getId()); + if (comparaison < 0) { + petit = U1.getId(); + grand = U2.getId(); + } + else { + petit = U2.getId() ; + grand = U1.getId() ; + } + return "Chat_" + petit + "_" + grand ; + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/ListUtilisateurs.java b/Implementation/chatapp/src/main/java/chatapp/Model/ListUtilisateurs.java new file mode 100644 index 0000000..cf755af --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Model/ListUtilisateurs.java @@ -0,0 +1,142 @@ +package chatapp.Model; + +import java.net.InetAddress; +import java.util.ArrayList; + +/** + *+ * Classe representant La liste des utilisateurs actifs, stockée localement + *
+ */ +public class ListUtilisateurs { + + // On conserve dans cette liste tout les utilisateurs actuellement actifs + private ArrayList+ * Classe representant les messages envoyes en TCP lors d'une session de clavardage. + * Un message Horodate est compose d'un destintaire, d'une source , d'un message et d'une date d'envoie. + *
+ */ +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; + } + + /** + * Setter: Date d'horodatage + * On modifie le date d'horodatage + */ + 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]); + 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"; + } + return new MessageHorodate(destinataire, source, payload, type); + } + + /** + * Getter: Utilisateur Source + * @return Utilisateur a l'origine du message + */ + public Utilisateur getSource() { + return source; + } + + /** + * Setter: Utilisateur Source + * On modifie l'utilisateur source + */ + public void setSource(Utilisateur source) { + this.source = source; + } + + /** + * Getter: Utilisateur Destinataire + * @return Utilisateur recevant le message + */ + public Utilisateur getDestinataire() { + return destinataire; + } + + /** + * Setter: Utilisateur Destinataire + * On modifie l'utilisateur Destinataire + */ + public void setDestinataire(Utilisateur destinataire) { + this.destinataire = destinataire; + } + + /** + * Getter: Message envoye + * @return Le message envoye + */ + public String getMessage() { + return Message; + } + + /** + * Setter: Message envoye + * On modifie le message envoye + */ + public void setMessage(String message) { + Message = message; + } + + /** + * Getter: 'Type' du message + * @return On recupere le Type du message + */ + public int getType() { + return type; + } + /** + * Setter: 'Type' du message horodate + * On modifie l'integer 'Type' + */ + public void setType(int Type) { + this.type = type; + } + + /** + * Getter: Date d'horodatage + * @return On recupere le date + */ + public Date getDateHorodatage() { + return dateHorodatage; + } + + /** + * Setter: Date d'horodatage + * On modifie le date. + */ + 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..dabb920 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Model/Utilisateur.java @@ -0,0 +1,90 @@ +package chatapp.Model; + + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + *+ * Classe representant un Utilisateur + * Un Utilisateur est associe avec un pseudo, un numero de port, une addresse IP ainsi qu'un ID. + *
+ */ +public class Utilisateur { + + private String pseudo ; + private Integer port; + private final InetAddress ip ; + private final String id ; + + /** + * Constructeur : Utilisateur + * @param pseudo Le pseudo associe + * @param port + * @param ip + */ + 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..7e09bf4 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteTCP.java @@ -0,0 +1,92 @@ +package chatapp.Protocol; + +import chatapp.Controller.ChatApp; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; + +/** + *+ * Classe permettant de gérer les multiples connexions en TCP. + * Extend la classe Thread. + *
+ */ +public class RunnerEcouteTCP extends Thread { + public ChatApp app ; + private PropertyChangeSupport pcs; + // on conserve les sessions actives dans un attribut liste + private ArrayList+ * Methode pour qu'un objet de la classe ChatApp soit constamment en a l'ecoute de potentielles connexions + * @param app L'utilisateur en ecoute de potentielles communications + *
+ */ + public void ecouteTCP(ChatApp app) { + ServerSocket ss; + 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(); + } + } + + /** + * Methode permettant d'ajouter une session active dans la liste 'ListeSessions' + * @param session Session Active que l'on souhaite rajouter + */ + public void addSession(SessionClavardage session){ + this.ListeSessions.add(session); + pcs.firePropertyChange("NouvelleSession",false,true); + } + + /** + * Methode permettant de recupere la derniere session de clavardage creee dans 'ListeSessions' + * @return Premiere Session Active + */ + public SessionClavardage getSessionClavardage() { + return(this.ListeSessions.remove(0)); + } + + /** + * Methode qui vient ecraser la méthode run de la classe Thread. + * La méthode 'ecouteTCP' est appele. + */ + @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..0a4f3d5 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java @@ -0,0 +1,186 @@ +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.DataBase; +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 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 ; + } + + + /**+ * Permet de recuperer l'adresse de l'hote sur le reseau au format IPv4. + * Si plusieurs adresses sont disponibles (plusieurs cartes réseaux), choisit la premiere trouvee + *
+ * @return l'adresse IP au format IPv4 + */ + 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..b5f82b9 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java @@ -0,0 +1,99 @@ + +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 + /** + *Handler permettant de retourner au menu principal sur pression du MenuButton
+ */ + void retourMenu(ActionEvent event) { + System.out.println("Retour au menu principal"); + 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 + /** + *Handler permettant de lancer la verrification de l'unicite du ppseudo sur pression du validtionButton
+ */ + 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(); + } + } + + /** + *Initialization de la classe ChangementPseudo et permet d'initialiser les parametres
+ */ + @FXML // This method is called by the FXMLLoader when initialization is complete + void initialize() { + chatApp = ChatApp.getInstance(); + pseudonyme1.setText(chatApp.getMe().getPseudo()); + this.validationButton.setDefaultButton(true); + //System.out.println(this.validationButton.isDefaultButton()); + } +} \ 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..aa859e8 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java @@ -0,0 +1,139 @@ +package chatapp.View; + + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.net.URL; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.ResourceBundle; + +import chatapp.Controller.ChatApp; +import chatapp.Model.MessageHorodate; +import chatapp.Model.Utilisateur; +import chatapp.Protocol.SessionClavardage; +import javafx.application.Platform; +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; +import javafx.stage.Stage; + +public class Clavardage implements Initializable, PropertyChangeListener { + @FXML //fx:id="plusButton" + public Button plusButton; + + @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 Utilisateur u2; + private SessionClavardage session; + private String nomTable; + @FXML + /** + *Handler gerant l'envoi du message contenu dans le TextField AEnvoyer et sur pression du bouton EnvoyerButton
+ */ + void envoyerMessage(ActionEvent event) { + String msg = AEnvoyer.getText(); + AEnvoyer.clear(); + if(!msg.equals("")) { + session.envoiMsg(msg); + Date d = new Date(); + DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:0"); + msg = "Moi (" + format.format(d).toString() + ") : " + msg + "\n"; + ChatText.appendText(msg); + + } + } + + + /** + * Setter + * @param session la session a associer a la classe + */ + public void setSession(SessionClavardage session) { + + this.session = session; + + this.session.addPropertyChangeListener(this); + this.u2=session.getU2(); + this.pseudonyme1.setText(u2.getPseudo()); + } + + /** + *Handler des differents evenements auxquels s'est abonne le PropertyChangeListener + * La classe est informee lorsque la session recoit un message ou lorsque la session se termine
+ * @param evt l'evenement informe par le pcs + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + switch (evt.getPropertyName()){ + case "MessageRecu" : + MessageHorodate msgh = session.getDernierMsg(); + DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:0"); + Date d = new Date(); + String msg = u2.getPseudo(); + msg += " ("+ format.format(d).toString() +") "; + msg+=": "+msgh.getMessage(); + ChatText.appendText(msg); + break; + case "FinDeLaSession" : + this.session.arretSession(); + Platform.runLater(new Runnable() { + @Override + public void run() { + Stage stage = (Stage) AEnvoyer.getScene().getWindow(); + stage.close(); + } + }); + } + + } + + public SessionClavardage getSession(){ + return session; + } + + /** + * Permet d'initialiser les differents parametres de la classe + * @param location + * @param resources + */ + @Override + public void initialize(URL location, ResourceBundle resources) { + EnvoyerButton.setDefaultButton(true); + this.ChatText.setEditable(false); + } + + /** + *Permet de recepurer plus de messages stoces dans la database en appuyant sur le bouton plusButton
+ * @param actionEvent + */ + public void ajouterMessagesHistorique(ActionEvent actionEvent) { + this.nomTable = this.session.getApp().getDb().getNomTable(u2,this.session.getApp().getMe()); + String historique = this.session.getApp().getDb().recupNMsg(session.getApp().getMe().getId(),this.u2.getId(), this.session.getApp().getDb().tailleBDD("Chat_mbp-de-auriane.home_mbp-de-auriane.home")); + ChatText.clear(); + ChatText.insertText(0,historique); + } +} \ 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..6ae272f --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/ConnexionScreen.java @@ -0,0 +1,70 @@ + +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() { + connexionButton.setDefaultButton(true); + + } + + /** + *Handler permettant de lancer la connexion avec le pseudonyme contenu dans le TextField pseudonyme en appuyant sur le connexionButton + *
+ * @param actionEvent + */ + 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..4d987f4 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/DemarrerSession.java @@ -0,0 +1,77 @@ +/** + * 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 ComboBoxHandler permettant de demarrer une session de clavardage avec le contact choisi dans la comboBox choixContaact
+ * @param event + */ + @FXML + void demarrerSessionAvec(ActionEvent event) { + chatApp.demarrerSession(choixContact.getValue()); + } + + /** + *Handler permettant de retourner au menu principal sur pression du MenuButton
+ */ + @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(); + } + + /** + *Initialization de la classe ChangementPseudo et permet d'initialiser les parametres
+ */ + @FXML // This method is called by the FXMLLoader when initialization is complete + void initialize() { + this.chatApp = ChatApp.getInstance(); + ListUtilisateurs utils = chatApp.getActifUsers(); + for(Utilisateur u : utils.getActifUsers()){ + choixContact.getItems().add(u.getPseudo()); + } + + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/View/FenetreSession.java b/Implementation/chatapp/src/main/java/chatapp/View/FenetreSession.java new file mode 100644 index 0000000..4ca243d --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/FenetreSession.java @@ -0,0 +1,46 @@ +package chatapp.View; + +import chatapp.Protocol.SessionClavardage; +import javafx.event.EventHandler; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; +import javafx.stage.WindowEvent; + +import java.beans.PropertyChangeListener; +import java.io.IOException; + +public class FenetreSession extends Stage { + SessionClavardage session; + /** + *Permet l'ouverture de la fenetre associee a la session de clavardage
+ */ + public FenetreSession(SessionClavardage session) { + FXMLLoader fichier = new FXMLLoader(getClass().getResource("/fenetres/View_Clavardage.fxml")); + try{ + Parent rootchat = fichier.load(); + Clavardage controller = fichier.getController(); + System.out.println("Session id "+session.getSessionID()); + //controller.printsalut(); + controller.setSession(session); + Scene scene1 = null; + scene1 = new Scene(rootchat,600,400); + this.setScene(scene1); + this.setTitle("Session avec "+session.getU2().getPseudo()); + this.setMinWidth(600); + this.setMinHeight(400); + //this.setMaxWidth(600); + //this.setMaxHeight(400); + this.show(); + this.centerOnScreen(); + this.setOnCloseRequest(new EventHandlerHandler permettant d'aller a la scene View_Utilisateurs pour afficher la liste des utilisateurs actifs
+ * @param actionEvent + */ + public void afficherUtilsActifs(ActionEvent actionEvent) { + Stage stage = (Stage) pseudonyme.getScene().getWindow(); + Parent root = null; + try { + root = FXMLLoader.load(getClass().getResource("/fenetres/View_Utilisateurs.fxml")); + } catch (IOException e) { + e.printStackTrace(); + } + Scene scene = new Scene(root); + stage.setScene(scene); + stage.show(); + } + + /** + *Handler permettant d'aller a la scene Demarrer_Session pour choisir un utilisateur avec qui clavarder + * @param actionEvent + */ + public void demarrerSession(ActionEvent actionEvent) { + Stage stage = (Stage) pseudonyme.getScene().getWindow(); + Parent root = null; + try { + root = FXMLLoader.load(getClass().getResource("/fenetres/View_Demarrer_Session.fxml")); + } catch (IOException e) { + e.printStackTrace(); + } + Scene scene = new Scene(root); + stage.setScene(scene); + stage.show(); + } + + /** + *
Handler permettant d'aller a la scene View_ChangementPseudo pour changer son pseudonyme + * @param actionEvent + */ + public void changerPseudo(ActionEvent actionEvent) { + Stage stage = (Stage) pseudonyme.getScene().getWindow(); + Parent root = null; + try { + root = FXMLLoader.load(getClass().getResource("/fenetres/View_ChangementPseudo.fxml")); + } catch (IOException e) { + e.printStackTrace(); + } + Scene scene = new Scene(root); + stage.setScene(scene); + stage.show(); + } + + /** + *
Handler permettant de se deconnecter et fermer l'application + * @param actionEvent + */ + public void deconnexion(ActionEvent actionEvent) { + try { + chatapp.deconnexion(); + /*chatapp.getMain().stop(); + Platform.exit(); + System.exit(0);*/ + } catch (IOException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/View/View_Utilisateurs.java b/Implementation/chatapp/src/main/java/chatapp/View/View_Utilisateurs.java new file mode 100644 index 0000000..96fcb3e --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/View_Utilisateurs.java @@ -0,0 +1,57 @@ +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 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.TextArea; +import javafx.stage.Stage; + +public class View_Utilisateurs { + + public TextArea ListeUtilisateurs; + public Button MenuButton; + @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() { + ListUtilisateurs utilisateurs = ChatApp.getInstance().getActifUsers(); + + ListeUtilisateurs.setText(""); + for(Utilisateur elem : utilisateurs.getActifUsers()) { + ListeUtilisateurs.appendText( " - " +elem.getPseudo() + '\n'); + } + ListeUtilisateurs.setEditable(false); + + + } + + /** + *
Handler permettant de retourner au menu principal sur pression du MenuButton
+ */ + public void retourMenu(ActionEvent actionEvent) { + 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(); + } +} diff --git a/Implementation/chatapp/src/main/resources/fenetres/ConnexionScreen.fxml b/Implementation/chatapp/src/main/resources/fenetres/ConnexionScreen.fxml new file mode 100644 index 0000000..c09f679 --- /dev/null +++ b/Implementation/chatapp/src/main/resources/fenetres/ConnexionScreen.fxml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + +-* 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