diff --git a/Implementation/.classpath b/Implementation/.classpath deleted file mode 100644 index e6f7288..0000000 --- a/Implementation/.classpath +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/Implementation/.gitignore b/Implementation/.gitignore index ae3c172..5b76f25 100644 --- a/Implementation/.gitignore +++ b/Implementation/.gitignore @@ -1 +1,37 @@ -/bin/ +# Created by https://www.gitignore.io/api/java,gradle + +### Java ### +*.class + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + + +### Gradle ### +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +# End of https://www.gitignore.io/api/java,gradle diff --git a/Implementation/.project b/Implementation/.project deleted file mode 100644 index f54e1c1..0000000 --- a/Implementation/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - Implementation - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/Implementation/.settings/org.eclipse.jdt.core.prefs b/Implementation/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 8b9e3c7..0000000 --- a/Implementation/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,10 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=13 -org.eclipse.jdt.core.compiler.compliance=13 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=13 diff --git a/Implementation/chatapp/.idea/.gitignore b/Implementation/chatapp/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/Implementation/chatapp/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/Implementation/chatapp/.idea/artifacts/chatapp.xml b/Implementation/chatapp/.idea/artifacts/chatapp.xml new file mode 100644 index 0000000..72f7f8f --- /dev/null +++ b/Implementation/chatapp/.idea/artifacts/chatapp.xml @@ -0,0 +1,6 @@ + + + $PROJECT_DIR$/out/artifacts/chatapp + + + \ No newline at end of file diff --git a/Implementation/chatapp/.idea/compiler.xml b/Implementation/chatapp/.idea/compiler.xml new file mode 100644 index 0000000..fb7f4a8 --- /dev/null +++ b/Implementation/chatapp/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Implementation/chatapp/.idea/gradle.xml b/Implementation/chatapp/.idea/gradle.xml new file mode 100644 index 0000000..611e7c8 --- /dev/null +++ b/Implementation/chatapp/.idea/gradle.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/Implementation/chatapp/.idea/jarRepositories.xml b/Implementation/chatapp/.idea/jarRepositories.xml new file mode 100644 index 0000000..fdc392f --- /dev/null +++ b/Implementation/chatapp/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Implementation/chatapp/.idea/libraries/lib.xml b/Implementation/chatapp/.idea/libraries/lib.xml new file mode 100644 index 0000000..bcdcd04 --- /dev/null +++ b/Implementation/chatapp/.idea/libraries/lib.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Implementation/chatapp/.idea/misc.xml b/Implementation/chatapp/.idea/misc.xml new file mode 100644 index 0000000..e513ffa --- /dev/null +++ b/Implementation/chatapp/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Implementation/chatapp/.idea/modules.xml b/Implementation/chatapp/.idea/modules.xml new file mode 100644 index 0000000..9509de3 --- /dev/null +++ b/Implementation/chatapp/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Implementation/chatapp/.idea/modules/chatapp.iml b/Implementation/chatapp/.idea/modules/chatapp.iml new file mode 100644 index 0000000..fd15dcb --- /dev/null +++ b/Implementation/chatapp/.idea/modules/chatapp.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Implementation/chatapp/build.gradle b/Implementation/chatapp/build.gradle new file mode 100644 index 0000000..3fe60d2 --- /dev/null +++ b/Implementation/chatapp/build.gradle @@ -0,0 +1,42 @@ +plugins { + id 'java' + id 'application' + id 'org.openjfx.javafxplugin' version '0.0.9' + id 'org.beryx.jlink' version '2.15.1' +} + +group 'org.example' +version '1.0-SNAPSHOT' + +sourceCompatibility = 11 + +repositories { + mavenCentral() +} + +javafx { + version = "11.0.2" + modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.graphics', 'javafx.base'] +} + + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' + runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:win" + runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:linux" + runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:mac" +} + +mainClassName = 'chatapp.Launcher' + +jlink { + options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages'] + launcher { + name = 'hellofx' + } +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/Implementation/chatapp/build/resources/main/fenetres/ConnexionScreen.fxml b/Implementation/chatapp/build/resources/main/fenetres/ConnexionScreen.fxml new file mode 100644 index 0000000..c09f679 --- /dev/null +++ b/Implementation/chatapp/build/resources/main/fenetres/ConnexionScreen.fxml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Implementation/chatapp/build/resources/main/fenetres/View_ChangementPseudo.fxml b/Implementation/chatapp/build/resources/main/fenetres/View_ChangementPseudo.fxml new file mode 100644 index 0000000..0a7885a --- /dev/null +++ b/Implementation/chatapp/build/resources/main/fenetres/View_ChangementPseudo.fxml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Implementation/chatapp/build/resources/main/fenetres/View_Clavardage.fxml b/Implementation/chatapp/build/resources/main/fenetres/View_Clavardage.fxml new file mode 100644 index 0000000..9e8975e --- /dev/null +++ b/Implementation/chatapp/build/resources/main/fenetres/View_Clavardage.fxml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt new file mode 100644 index 0000000..a074e7b --- /dev/null +++ b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt @@ -0,0 +1,42 @@ +chatapp/Model/ListUtilisateurs.java + chatapp.Model.ListUtilisateurs +chatapp/Model/MessageHorodate.java + chatapp.Model.MessageHorodate +chatapp/Model/Utilisateur.java + chatapp.Model.Utilisateur +chatapp/Model/Historique.java + chatapp.Model.Historique +chatapp/Launcher.java + chatapp.Launcher +chatapp/Protocol/RunnerEcouteTCP.java + chatapp.Protocol.RunnerEcouteTCP +chatapp/View/FenetreSession.java + chatapp.View.FenetreSession + chatapp.View.FenetreSession$1 +chatapp/Controller/ChatApp.java + chatapp.Controller.ChatApp +chatapp/View/ChangementPseudo.java + chatapp.View.ChangementPseudo +chatapp/Protocol/RunnerEcouteUDP.java + chatapp.Protocol.RunnerEcouteUDP +chatapp/Protocol/TCPEchange.java + chatapp.Protocol.RunnerTCPEcoute + chatapp.Protocol.RunnerTCPEnvoi + chatapp.Protocol.TCPEchange +chatapp/Protocol/UDPEchange.java + chatapp.Protocol.RunnerUDP + chatapp.Protocol.UDPEchange +chatapp/Main.java + chatapp.Main +chatapp/View/Clavardage.java + chatapp.View.Clavardage +chatapp/Protocol/SessionClavardage.java + chatapp.Protocol.SessionClavardage +chatapp/View/ConnexionScreen.java + chatapp.View.ConnexionScreen +chatapp/View/View_Utilisateurs.java + chatapp.View.View_Utilisateurs +chatapp/View/View_Menu.java + chatapp.View.View_Menu +chatapp/View/DemarrerSession.java + chatapp.View.DemarrerSession diff --git a/Implementation/chatapp/gradle/wrapper/gradle-wrapper.jar b/Implementation/chatapp/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/Implementation/chatapp/gradle/wrapper/gradle-wrapper.jar differ diff --git a/Implementation/chatapp/gradle/wrapper/gradle-wrapper.properties b/Implementation/chatapp/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..be52383 --- /dev/null +++ b/Implementation/chatapp/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/Implementation/chatapp/gradlew b/Implementation/chatapp/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/Implementation/chatapp/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/Implementation/chatapp/gradlew.bat b/Implementation/chatapp/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/Implementation/chatapp/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/Implementation/chatapp/settings.gradle b/Implementation/chatapp/settings.gradle new file mode 100644 index 0000000..876b43d --- /dev/null +++ b/Implementation/chatapp/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'chatapp' + diff --git a/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java new file mode 100644 index 0000000..227305a --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java @@ -0,0 +1,309 @@ +package chatapp.Controller; + +import chatapp.Model.Historique; +import chatapp.Model.ListUtilisateurs; +import chatapp.Model.MessageHorodate; +import chatapp.Model.Utilisateur; +import chatapp.Protocol.*; +import javafx.application.Application; +import javafx.application.Platform; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.IOException; +import java.net.InetAddress; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class ChatApp implements PropertyChangeListener { + + /* Liste des utilisateurs actifs */ + private ListUtilisateurs actifUsers ; + + /* Map on l'on stocke localement les historiques des messages */ + private Map mapHistorique ; + private boolean historiqueAvailable = true; + + /* ChatApp est associe a un utilisateur */ + private Utilisateur me; + + /* ChatApp est associe a une application qui le lance et que chatapp doit fermer a la fin */ + + private Application main; + + private static ChatApp chatapp = null; + private RunnerEcouteTCP runnerEcouteTCP; + private RunnerEcouteUDP runnerEcouteUDP; + + + /** + * 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.mapHistorique = new HashMap() ; + this.main = main; + } + + public static synchronized ChatApp getInstance(String pseudo, Integer port, Application main){ + if (chatapp == null) { + chatapp = new ChatApp(pseudo, port, main); + } + return chatapp; + } + + public static ChatApp getInstance(){ + return chatapp; + } + + /** + * Mettre a jour dans Maphistorique, l'historique avec un utilisateur dont le nom est pseudo + * + * @param h nouvel Historique entre les deux utilisateurs + */ + public synchronized void majHistorique(Historique h) { + getMapHistorique().put(h.getUser2().getPseudo(),h); + } + + /*public void majHistorique2(MessageHorodate mh, String pseudo) { + Historique h = getMapHistorique().get(pseudo); + //h.addMessage(mh); + getMapHistorique().put(h.getUser2().getPseudo(),h); + }*/ + + public void majHistorique2(String mh, String pseudo) { + Historique h = getMapHistorique().get(pseudo); + MessageHorodate msghor = new MessageHorodate(this.getMe(),this.getMe(),"rien",1); + System.out.println(">>"+mh+"<<"); + System.out.print(msghor.getDateHorodatage()); + System.out.println(msghor.getDestinataire()); + System.out.println(msghor.getSource()); + System.out.println(msghor.getType()); + + h.addMessage(msghor); + 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); + 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 ; + } + } + + 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"); + return true; + } + else + { + System.out.println("Connexion echoue"); + UDPEchange.setConnecte(true); + return false ; + } + } + + + public void activerEcouteTCP(){ + this.runnerEcouteTCP = new RunnerEcouteTCP(this); + this.runnerEcouteTCP.addPropertyChangeListener(this); + } + public void demarrerSession(String pseudo){ + Utilisateur u2 = this.actifUsers.getPseudoList(pseudo); + SessionClavardage session = new SessionClavardage(u2,this); + runnerEcouteTCP.addSession(session); + } + 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); + + 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; + } + + /** + * Getter + * @return la map des historiques + */ + public Map getMapHistorique() { + return mapHistorique; + } + + /** + * Obtenir l'historique entre deux utilisateurs + * @param pseudo Pseudo de l'utilisateur dont on souhaite obtenir l'historique + * @return Un historique + */ + public synchronized Historique getHist(String pseudo) { + Historique h = this.mapHistorique.get(pseudo); + if( h != null) { + return h ; + } + else { + h = new Historique(this.me, this.getActifUsers().getPseudoList(pseudo)); + return h ; + } + } + + /*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")); + } + + + + }*/ + + public boolean isHistoriqueAvailable() { + return historiqueAvailable; + } + + public void setHistoriqueAvailable(boolean historiqueAvailable) { + this.historiqueAvailable = historiqueAvailable; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + switch (evt.getPropertyName()){ + case "chatCreated" : + SessionClavardage session = this.runnerEcouteTCP.getSessionClavardage(); + session.addPropertyChangeListener(this); + break; + } + } + + public Application getMain() { + return main; + } +} 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..f745c9c --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Main.java @@ -0,0 +1,31 @@ +package chatapp; + +import chatapp.Controller.ChatApp; +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.stage.Stage; + +public class Main extends Application { + + + @Override + public void start(Stage primaryStage) throws Exception { + ChatApp 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.show(); + primaryStage.centerOnScreen(); + chatapp.activerEcouteTCP(); + chatapp.activerEcouteUDP(); + + } + + public static void main(String[] args) { + launch(args); + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/Historique.java b/Implementation/chatapp/src/main/java/chatapp/Model/Historique.java new file mode 100644 index 0000000..97cfbd6 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Model/Historique.java @@ -0,0 +1,63 @@ +package chatapp.Model; + +import java.util.ArrayList; + +/** + *

+ * 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 HistoriqueHorodate ; + + /** + *

+ * 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 actifUsers ; + + public ListUtilisateurs() { + this.actifUsers = new ArrayList() ; + } + /** + * Ajouter des utilisateurs actifs dans l'attribut liste 'actifUsers' + * + * @param u on va rajouter cet utilisateur dans la liste + */ + public void addList(Utilisateur u) { + if((verifierUnicite(u.getPseudo()))) { + this.actifUsers.add(u); + } + + + } + + /** + * Recuperer un utilisateur à partir de son pseudo + * + * @param pseudo Pseudo de l'utilisateur que l'on souhaite retrouver + */ + public Utilisateur getPseudoList(String pseudo) { + for(Utilisateur elem: this.actifUsers) + { + if (elem.getPseudo().equals(pseudo) ) { + return elem ; + } + } + return null ; + } + + public Utilisateur getIPList(InetAddress ip) throws Exception { + for(Utilisateur elem: this.actifUsers) + { + if (elem.getIp().equals(ip) ) { + return elem ; + } + } + throw new Exception("No such user with this IP address") ; + } + + /** + * Supprimer de la liste des utilisateurs actifs 'actifUsers' un certain utilisateur + * + * @param u on va supprimer cet utilisateur dans la liste + */ + public void supprimerList(Utilisateur u) { + Boolean Sup = false ; + for(Utilisateur elem: this.actifUsers) + { + if (elem.equals(u) ) { + this.actifUsers.remove(elem); + Sup = true ; + this.afficherListeUtilisateurs(); + } + } + if (!Sup) { + System.out.println("Tentative de retirer un objet non contenu dans la liste"); + } + } + + /** + * Modifie le nom d'un utilisateur dans la liste des utilisateurs actifs 'actifUsers' + * + * @param ancien correspond au pseudo remplacer + * @param nouveau correspond au nouveau pseudo + */ + public void modifierList(String ancien , String nouveau) { + for(Utilisateur elem: this.actifUsers) + { + if (ancien.equals( elem.getPseudo() ) ) { + this.actifUsers.remove(elem); + elem.setPseudo(nouveau);; + this.addList(elem); + + } + } + this.afficherListeUtilisateurs(); + } + + public Boolean appartient(Utilisateur u) { + return this.actifUsers.contains(u); + } + + + + /** + * Verifie qu'aucun autre utilisateur ne possède le même pseudo + * + * @param pseudo on va supprimer cet utilisateur dans la liste + */ + public Boolean verifierUnicite(String pseudo) { + for(Utilisateur elem: this.actifUsers) + { + if (pseudo.equals( elem.getPseudo() ) ) { + return false ; + } + } + return true; + } + + /** + * Méthode affichant la liste des utilisateurs actifs + * + */ + public String afficherListeUtilisateurs() { + System.out.println ("Liste des utilisateurs actifs : "); + String Utilisateur = "" ; + for(Utilisateur elem: this.actifUsers) + { + System.out.println (elem.toString()); + Utilisateur += (elem + "\n"); + } + return Utilisateur; + } + + public ArrayList getActifUsers(){ + return this.actifUsers; + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/MessageHorodate.java b/Implementation/chatapp/src/main/java/chatapp/Model/MessageHorodate.java new file mode 100644 index 0000000..266c435 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Model/MessageHorodate.java @@ -0,0 +1,143 @@ +package chatapp.Model; + + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.io.Serializable; +/** + *

+ * Classe representant les messages envoyés en TCP lors d'une session de clavardage + *

+ */ +public class MessageHorodate implements Serializable { + private Utilisateur destinataire ; + private Utilisateur source ; + private Date dateHorodatage ; + private int type; // 0 = debut de la communication, 1= message de communication, 2 = fin de la communicataion + private String Message; + + /** + *

+ * Constructeur , le message va etre horodate + * @param destinataire - Destinataire du message + * @param source - Source du message + * @param Message - Message envoye + *

+ */ + public MessageHorodate(Utilisateur destinataire, Utilisateur source, String Message, int type) { + this.setDestinataire(destinataire) ; + this.setSource(source) ; + this.setMessage(Message) ; + this.setDateHorodatage(new Date()); + this.type = type; + } + + public void setDate(Date d) { + this.setDateHorodatage(d); + } + + /** + *

+ * permet de creer une representation string du message + * @return Les differents attributs de la classe sous forme de string + *

+ */ + @Override + public String toString() { + String Msg = ""; + Msg += ("Destinataire::" + this.getDestinataire() + "\n") ; + Msg += ("Source::" + this.getSource()+ "\n") ; + Msg += ("Type::"+ this.type+ "\n"); + Msg += ("Date::" + this.dateToString() + "\n") ; + Msg += ("Message::" + this.getMessage() + "\n" ); + return Msg ; + } + + /** + *

+ * permet de creer une representation string de la date d'horodatage + * @return La date d'horodatage du message en format yyyy/MM/dd HH:mm:ss + *

+ */ + public String dateToString() { + DateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + return format.format(this.getDateHorodatage()); + } + + + /** + *

+ * Permet de re creer un message horodate a partir d'un string + * @return un messageHorodate + *

+ */ + public static MessageHorodate stringToMessageHorodate(String s) { + + String mots[] = s.split("\n"); + Utilisateur destinataire = Utilisateur.stringToUtilisateur(mots[0].split("::")[1]); + Utilisateur source = Utilisateur.stringToUtilisateur(mots[1].split("::")[1]); + int type = Integer.parseInt(mots[2].split("::")[1]); + DateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + Date date = new Date(); + /*try { + date = format.parse(mots[3].split("::")[1]); + } catch (Exception e) { + e.printStackTrace(); + }*/ + String payload = ""; + for(int i=4; i< mots.length; i++) { + if(mots[i].startsWith("Message::")) { + mots[i]=mots[i].split("::")[1]; + } + payload += mots[i]+"\n"; + } + + MessageHorodate mh = new MessageHorodate(destinataire, source, payload, type); + //mh.setDate(date); + + return mh ; + } + + public Utilisateur getSource() { + return source; + } + + public void setSource(Utilisateur source) { + this.source = source; + } + + public Utilisateur getDestinataire() { + return destinataire; + } + + public void setDestinataire(Utilisateur destinataire) { + this.destinataire = destinataire; + } + + public String getMessage() { + return Message; + } + + public void setMessage(String message) { + Message = message; + } + + public int getType() { + return type; + } + + public void setType(int Type) { + this.type = type; + } + + public Date getDateHorodatage() { + return dateHorodatage; + } + + public void setDateHorodatage(Date dateHorodatage) { + this.dateHorodatage = dateHorodatage; + } + +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/Utilisateur.java b/Implementation/chatapp/src/main/java/chatapp/Model/Utilisateur.java new file mode 100644 index 0000000..1103c33 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Model/Utilisateur.java @@ -0,0 +1,78 @@ +package chatapp.Model; + + +import java.net.InetAddress; +import java.net.UnknownHostException; + +public class Utilisateur { + + private String pseudo ; + private Integer port; + private final InetAddress ip ; + private final String id ; + + public Utilisateur(String pseudo,Integer port, InetAddress ip ){ + this.setPseudo(pseudo) ; + this.setPort(port); + this.ip = ip ; + this.id = ip.getHostName() ; + } + + public String getPseudo() { + return pseudo; + } + + public void setPseudo(String pseudo) { + this.pseudo = pseudo; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public InetAddress getIp() { + return ip; + } + public String getId() { + return id; + } + + @Override + public String toString(){ + String s = ""; + s+="pseudo " + this.pseudo + " | "; + s+="port " + (this.port).toString() + " | "; + s+="ip " + (this.ip).toString() + " | "; + s+="id " + (this.id).toString() + " | "; + return s; + } + + public static Utilisateur stringToUtilisateur(String s) { + String name; + Integer port = 0; + String ip = "" ; + String id = ""; + String mots[] = s.split(" "); + name=mots[1]; + port=Integer.parseInt(mots[4]); + ip=mots[7]; + id=mots[10]; + Utilisateur user = null; + try { + user = new Utilisateur(name,port,InetAddress.getByName(ip.split("/")[1])); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + return user; + } + + + public Boolean equals(Utilisateur u) { + return this.getId().equals( u.getId() ) ; + } + +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteTCP.java b/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteTCP.java new file mode 100644 index 0000000..577d836 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteTCP.java @@ -0,0 +1,67 @@ +package chatapp.Protocol; + +import chatapp.Controller.ChatApp; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class RunnerEcouteTCP extends Thread { + public ChatApp app ; + private PropertyChangeSupport pcs; + private ArrayList ListeSessions = new ArrayList(); + public RunnerEcouteTCP(ChatApp app) { + this.app = app ; + this.pcs = new PropertyChangeSupport(this); + this.start(); + } + + + public void addPropertyChangeListener(PropertyChangeListener pcl) { + this.pcs.addPropertyChangeListener("NouvelleSession",pcl); + } + + /** + *

+ * Méthode pour qu'un objet de la classe ChatApp soit constamment en écoute de potentielles connexions + * @param app L'utilisateur en écoute de potentielles communications + *

+ */ + public void ecouteTCP(ChatApp app) { + ServerSocket ss = null; + System.out.println("Ecoute TCP activee"); + try { + ss = new ServerSocket(5000); // On ecoute sur le port 5000 + System.out.println("Socket d'ecoute cree"); + while(true) { // Ecoute en boucle + System.out.println("Attente Session de clavardage"); + Socket link = ss.accept(); // Blocante + SessionClavardage session = new SessionClavardage(link,app); + this.ListeSessions.add(session); + pcs.firePropertyChange("NouvelleSession",false,true); + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void addSession(SessionClavardage session){ + this.ListeSessions.add(session); + pcs.firePropertyChange("NouvelleSession",false,true); + } + public SessionClavardage getSessionClavardage() { + return(this.ListeSessions.remove(0)); + } + @Override + public void run() { + ecouteTCP(this.app); + + + } +} \ No newline at end of file diff --git a/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteUDP.java b/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteUDP.java new file mode 100644 index 0000000..06f2d9a --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteUDP.java @@ -0,0 +1,16 @@ +package chatapp.Protocol; + +import chatapp.Controller.ChatApp; + +public class RunnerEcouteUDP extends Thread { + ChatApp app ; + public RunnerEcouteUDP(ChatApp app) { + this.app = app ; + } + @Override + public void run() { + + UDPEchange.ecouteUDP(app); + + } +} \ No newline at end of file diff --git a/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java b/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java new file mode 100644 index 0000000..f2551c5 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java @@ -0,0 +1,183 @@ +package chatapp.Protocol; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.util.ArrayList; + +import chatapp.Controller.ChatApp; +import chatapp.Model.MessageHorodate; +import chatapp.Model.Utilisateur; +import chatapp.View.FenetreSession; +import javafx.application.Platform; + +public class SessionClavardage extends Thread { + private Socket link; + private ChatApp app; + private Utilisateur u2; + private ObjectOutputStream out; + private ObjectInputStream in; + private PropertyChangeSupport pcs; + private ArrayList derniersMsg; // on met temporairement les derniers msgs pour éviter les pb de synchro inter-threads + private int SessionID; + public SessionClavardage(Socket link, ChatApp app) { + this.setLink(link); + this.setApp(app); + try { + this.setU2(app.getActifUsers().getIPList(link.getInetAddress())); + this.setOut(new ObjectOutputStream(link.getOutputStream())); + this.setIn(new ObjectInputStream(link.getInputStream())); + }catch(Exception e) { + e.getStackTrace(); + } + this.derniersMsg = new ArrayList(); + this.SessionID = 2; + + Platform.runLater( () -> + new FenetreSession(this) + ); + this.pcs = new PropertyChangeSupport(this); + this.start(); + } + + public SessionClavardage(Utilisateur u2, ChatApp app) { + this.setU2(u2); + this.setApp(app); + try { + Socket s = new Socket(u2.getIp(),5000); + this.setOut(new ObjectOutputStream(s.getOutputStream())); + this.setIn(new ObjectInputStream(s.getInputStream())); + this.setLink(s); + } catch (IOException e) { + + e.printStackTrace(); + } + this.derniersMsg = new ArrayList(); + this.pcs = new PropertyChangeSupport(this); + this.start(); + Platform.runLater( () -> + new FenetreSession(this) + ); + } + + + public void addPropertyChangeListener(PropertyChangeListener pcl){ + this.pcs.addPropertyChangeListener("MessageRecu",pcl); + this.pcs.addPropertyChangeListener("FinDeLaSession",pcl); + } + + public void arretSession() { + MessageHorodate msgh = new MessageHorodate(getU2(),getApp().getMe(),".",2); + try { + getOut().writeObject(msgh.toString()); + } catch (IOException e) { + //e.printStackTrace(); + } + finally { + try { + link.close(); + } catch (IOException e) { + + } + } + } + public void envoiMsg(String msg) { + MessageHorodate msgh = new MessageHorodate(getU2(),getApp().getMe(),msg,1); + try { + getOut().writeObject(msgh.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public MessageHorodate getDernierMsg() { + return this.derniersMsg.remove(0); + } + + + + public void run() { + String plaintext = null; + MessageHorodate msg = null; + System.out.println("Session demarre"); + while(true) { + try { + plaintext = (String) getIn().readObject(); + msg = MessageHorodate.stringToMessageHorodate(plaintext); + + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + pcs.firePropertyChange("FinDeLaSession", false, true); + break; + } + if(msg.getType() == 2) { + pcs.firePropertyChange("FinDeLaSession", false, true); + try { + link.close(); + } catch (IOException e) { + break; + } + break; + } + derniersMsg.add(msg); + pcs.firePropertyChange("MessageRecu",false,true); + + } + } + + public ObjectOutputStream getOut() { + return out; + } + + public void setOut(ObjectOutputStream out) { + this.out = out; + } + + public ObjectInputStream getIn() { + return in; + } + + public void setIn(ObjectInputStream in) { + this.in = in; + } + + public Socket getLink() { + return link; + } + + public void setLink(Socket link) { + this.link = link; + } + + public ChatApp getApp() { + return app; + } + + public void setApp(ChatApp app) { + this.app = app; + } + + public Utilisateur getU2() { + return u2; + } + + public void setU2(Utilisateur u2) { + this.u2 = u2; + } + + + public int getSessionID() { + return SessionID; + } + + public void setSessionID(int sessionID) { + SessionID = sessionID; + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Protocol/TCPEchange.java b/Implementation/chatapp/src/main/java/chatapp/Protocol/TCPEchange.java new file mode 100644 index 0000000..4d60d50 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/TCPEchange.java @@ -0,0 +1,322 @@ +package chatapp.Protocol; + + +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 chatapp.Controller.*; +import chatapp.Model.*; + +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/chatapp/src/main/java/chatapp/Protocol/UDPEchange.java b/Implementation/chatapp/src/main/java/chatapp/Protocol/UDPEchange.java new file mode 100644 index 0000000..133ce44 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/UDPEchange.java @@ -0,0 +1,360 @@ +package chatapp.Protocol; + +import java.io.IOException; + +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.Inet4Address; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import chatapp.Controller.*; +import chatapp.Model.*; +/** + *

+ * Classe representant les echanges UDP entre utilisateurs. + *

+ */ + +public class UDPEchange { + + private static Boolean Connecte = true; + // True si l'utilisateur peut se connecter avec ce nom d'utilisateur , False sinon + + private static Boolean EcouteEnCours = false; + /** + * Getter + * @return le boolean connecte (True s'il peut se connecter avec ce nom d'utilisateur , False sinon) + */ + public static Boolean getConnecte() { + return Connecte; + } + + /** + * Setter + * @param value La nouvelle valeur du boolean de connexion + */ + public static void setConnecte(Boolean value) { + Connecte = value ; + } + + private static Boolean PseudoValide = true; + // True si l'utilisateur a (ou demande) un pseudo valide , False sinon + + /** + * Getter + * @return le boolean PseudoValide (True s'il peut utiliser ce pseudo , False sinon) + */ + public static Boolean getPseudoValide() { + return PseudoValide; + } + + /** + * Setter + * @param value La nouvelle valeur du boolean concernant le pseudo valide + */ + public static void setPseudoValide(Boolean value) { + PseudoValide = value ; + } + + + + public static InetAddress getCurrentIp() { + try { + Enumeration networkInterfaces = NetworkInterface + .getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + NetworkInterface ni = (NetworkInterface) networkInterfaces + .nextElement(); + Enumeration nias = ni.getInetAddresses(); + while(nias.hasMoreElements()) { + InetAddress ia= (InetAddress) nias.nextElement(); + if (!ia.isLinkLocalAddress() + && !ia.isLoopbackAddress() + && ia instanceof Inet4Address) { + return ia; + } + } + } + } catch (Exception e) { + System.out.println("unable to get current IP " + e.getMessage()); + } + return null; + } + /** + *

+ * 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 listAllBroadcastAddresses() throws SocketException { + List broadcastList = new ArrayList<>(); + Enumeration interfaces + = NetworkInterface.getNetworkInterfaces(); + while (interfaces.hasMoreElements()) { + NetworkInterface networkInterface = interfaces.nextElement(); + + if (networkInterface.isLoopback() || !networkInterface.isUp()) { + continue; + } + + networkInterface.getInterfaceAddresses().stream() + .map(a -> a.getBroadcast()) + .filter(Objects::nonNull) + .forEach(broadcastList::add); + } + return broadcastList; + } + +} + + + +/** + *

+ * Classe implementant l'interface Runnable. + * Contient les traitements a executer dans un thread lancer par des methodes de la class UDPEchange + *

+ */ +class RunnerUDP implements Runnable { + final DatagramPacket data ; + ChatApp app ; + + public RunnerUDP(DatagramPacket data, ChatApp app) { + this.data= data; + this.app = app ; + } + + /** + *

+ * Methode qui redefinie les traitements qui seront executes dans le thread: + * Met à jour la liste des utilisateurs actifs + *

+ * + */ + @Override + public void run() { + System.out.println("Thread started"); + String received = new String(data.getData(), 0, data.getLength()); + System.out.println("***********Message recu***********"); + System.out.println(received); + System.out.println("**********************************"); + String Type = received.split("\n")[0]; + + //**************************************************************************************************** + //**************************************************************************************************** + //****************************************Demande de connexion**************************************** + //**************************************************************************************************** + //**************************************** + if (Type.equals("Connexion")) { // un utilisateur vient d'arriver sur le reseau + System.out.println("Reception d'une demande de connexion"); + Utilisateur u = Utilisateur.stringToUtilisateur(received.split("\n")[1]); + if (! u.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même + String reponse = "Reponse Connexion\n"; + if (!( app.getActifUsers() ).verifierUnicite(u.getPseudo())) { + System.out.println("Pseudo deja present dans la liste"); + reponse += "false\n"; + } + else { + System.out.println("Ajout d'un nouvel utilisateur dans la liste des Utilisateurs"); + ( app.getActifUsers() ).addList(u); + reponse += "true\n"; + + } + reponse += app.getMe().toString(); + + try { + UDPEchange.envoiUnicast(u.getIp(),reponse); + }catch(IOException e) + { + System.out.println("Echec de l'envoi du message"); + } + + ( app.getActifUsers() ).afficherListeUtilisateurs(); + } + } + //******************************************************************************************************* + //******************************************************************************************************* + //****************************************Reponse d'une connexion**************************************** + //******************************************************************************************************* + //******************************************************************************************************* + + if (Type.equals("Reponse Connexion")) { // Un utilisateur te repond suite à ta demande de connexion + + if((received.split("\n")[1]).equals("true")) { + Utilisateur u = Utilisateur.stringToUtilisateur(received.split("\n")[2]); + app.getActifUsers().addList(u); + app.getActifUsers().afficherListeUtilisateurs(); + } + else { + System.out.println("Pseudo deja pris"); + UDPEchange.setConnecte(false); + } + } + + //******************************************************************************************************************* + //******************************************************************************************************************* + //****************************************Demande de modification d'un pseudo**************************************** + //******************************************************************************************************************* + //******************************************************************************************************************* + + if (Type.equals("Demande Modification Pseudo")) { + Utilisateur Source = Utilisateur.stringToUtilisateur(received.split("\n")[1]); + if (! Source.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même + String nouveau = received.split("\n")[2] ; + String Message = ""; + if(( app.getActifUsers() ).verifierUnicite(nouveau)) { + Message = "Bon Choix Pseudo\n" + nouveau ; + } + else { + Message = "Mauvais Choix Pseudo\n" ; + } + System.out.println(Message); + try { + UDPEchange.envoiUnicast(Source.getIp(),Message); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + //************************************************************************************************************ + //************************************************************************************************************ + //**************************************** Modification pseudo reussi **************************************** + //************************************************************************************************************ + //************************************************************************************************************ + + if (Type.equals("Modification pseudo reussi")) { + Utilisateur Source = Utilisateur.stringToUtilisateur(received.split("\n")[1]); + if (! Source.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même + String nouveau = received.split("\n")[2] ; + if(app.getActifUsers().appartient(Source)) { // On verifie d'abord que Source appartient bien a la liste des utilisateurs actifs + app.getActifUsers().modifierList(Source.getPseudo(), nouveau); + } + { + // Suite a une perte d'un message lors d'une connexion l'utilisateur Source n'apparait pas dans la liste + app.getActifUsers().addList(Source); + } + } + } + //********************************************************************************************************* + //********************************************************************************************************* + //****************************************Mauvais choix d'un pseudo**************************************** + //********************************************************************************************************* + //********************************************************************************************************* + if (Type.equals("Mauvais Choix Pseudo")) { + System.out.println("Ce choix de pseudo est déjà pris il te faut en choisir un autre"); + UDPEchange.setPseudoValide(false); + } + + //****************************************************************************************************************** + //****************************************************************************************************************** + //****************************************Bon choix d'un pseudo***************************************************** + //****************************************************************************************************************** + //****************************************************************************************************************** + + if (Type.equals("Bon Choix Pseudo")) { + // Il n'y a rien a faire ici + } + + //********************************************************************************************************* + //********************************************************************************************************* + //****************************************Demande d'une deconnexion**************************************** + //********************************************************************************************************* + //********************************************************************************************************* + + if (Type.equals("Deconnexion")) { + ( app.getActifUsers() ).supprimerList(Utilisateur.stringToUtilisateur(received.split("\n")[1])); + } + } + + + + +} diff --git a/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java b/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java new file mode 100644 index 0000000..51ccf41 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java @@ -0,0 +1,87 @@ + +package chatapp.View; + + import java.io.IOException; + import java.net.URL; + import java.util.ResourceBundle; + + import chatapp.Controller.ChatApp; + import javafx.event.ActionEvent; + import javafx.fxml.FXML; + import javafx.fxml.FXMLLoader; + import javafx.scene.Parent; + import javafx.scene.Scene; + import javafx.scene.control.Alert; + import javafx.scene.control.Button; + import javafx.scene.control.TextField; + import javafx.scene.text.Text; + import javafx.stage.Stage; + +public class ChangementPseudo { + + @FXML // ResourceBundle that was given to the FXMLLoader + private ResourceBundle resources; + + @FXML // URL location of the FXML file that was given to the FXMLLoader + private URL location; + + @FXML // fx:id="validationButton" + private Button validationButton; // Value injected by FXMLLoader + + @FXML // fx:id="pseudonyme" + private TextField pseudonyme; // Value injected by FXMLLoader + + @FXML // fx:id="pseudonyme1" + private Text pseudonyme1; // Value injected by FXMLLoader + + @FXML // fx:id="MenuButton" + private Button MenuButton; // Value injected by FXMLLoader + + private ChatApp chatApp; + @FXML + void nouveauPseudo(ActionEvent event) { + + } + + @FXML + void retourMenu(ActionEvent event) { + Stage stage = (Stage) MenuButton.getScene().getWindow(); + Parent root = null; + try { + root = FXMLLoader.load(getClass().getResource("/fenetres/View_Menu.fxml")); + } catch (IOException e) { + e.printStackTrace(); + } + Scene scene = new Scene(root); + stage.setScene(scene); + stage.show(); + } + + @FXML + void validerPseudo(ActionEvent event) { + boolean pseudoOK = false; + try { + pseudoOK = chatApp.modifierPseudo(pseudonyme.getText()); + } catch (IOException e) { + e.printStackTrace(); + } + if(pseudoOK){ + this.retourMenu(null); + } + else{ + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle("Changement pseudo"); + // Header Text: null + alert.setHeaderText(null); + alert.setContentText("Echec de Connexion: le pseudo "+pseudonyme.getText()+" est deja pris"); + alert.showAndWait(); + } + } + + @FXML // This method is called by the FXMLLoader when initialization is complete + void initialize() { + chatApp = ChatApp.getInstance(); + pseudonyme1.setText(chatApp.getMe().getPseudo()); + + } +} \ No newline at end of file diff --git a/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java b/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java new file mode 100644 index 0000000..ac34cdc --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java @@ -0,0 +1,97 @@ +package chatapp.View; + + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.net.URL; +import java.util.ResourceBundle; + +import chatapp.Controller.ChatApp; +import chatapp.Model.MessageHorodate; +import chatapp.Model.Utilisateur; +import chatapp.Protocol.SessionClavardage; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Button; +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; +import javafx.scene.text.Text; + +public class Clavardage implements Initializable, PropertyChangeListener { + + @FXML // ResourceBundle that was given to the FXMLLoader + private ResourceBundle resources; + + @FXML // URL location of the FXML file that was given to the FXMLLoader + private URL location; + + @FXML // fx:id="AEnvoyer" + private TextField AEnvoyer; // Value injected by FXMLLoader + + @FXML // fx:id="EnvoyerButton" + private Button EnvoyerButton; // Value injected by FXMLLoader + + @FXML // fx:id="pseudonyme1" + private Text pseudonyme1; // Value injected by FXMLLoader + + @FXML // fx:id="ChatText" + private TextArea ChatText; // Value injected by FXMLLoader + + @FXML // fx:id="MenuButton" + private Button MenuButton; // Value injected by FXMLLoader + private Utilisateur u2; + private SessionClavardage session; + public int Clav = 3; + @FXML + void envoyerMessage(ActionEvent event) { + String msg = AEnvoyer.getText(); + AEnvoyer.clear(); + session.envoiMsg(msg); + msg= "Moi: "+msg+"\n"; + ChatText.appendText(msg); + } + + @FXML + void retourMenu(ActionEvent event) { + + } + + @FXML // This method is called by the FXMLLoader when initialization is complete + void initialize() { + } + public void printsalut(){ + System.out.println("wesh"); + } + public void setSession(SessionClavardage session) { + //this.printsalut(); + this.session = session; + System.out.println("1"); + this.session.addPropertyChangeListener(this); + System.out.println("2"); + this.u2=session.getU2(); + System.out.println("3"); + this.pseudonyme1.setText(u2.getPseudo()); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + switch (evt.getPropertyName()){ + case "MessageRecu" : + MessageHorodate msgh = session.getDernierMsg(); + String msg = u2.getPseudo(); + msg+=": "+msgh.getMessage(); + ChatText.appendText(msg); + break; + } + + } + + public SessionClavardage getSession(){ + return session; + } + + @Override + public void initialize(URL location, ResourceBundle resources) { + } +} \ No newline at end of file diff --git a/Implementation/chatapp/src/main/java/chatapp/View/ConnexionScreen.java b/Implementation/chatapp/src/main/java/chatapp/View/ConnexionScreen.java new file mode 100644 index 0000000..a8043bb --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/ConnexionScreen.java @@ -0,0 +1,64 @@ + +package chatapp.View; + +import java.io.IOException; +import java.net.URL; +import java.util.ResourceBundle; + +import chatapp.Controller.ChatApp; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.TextField; +import javafx.stage.Stage; + +public class ConnexionScreen { + + public Button connexionButton; + + public TextField pseudonyme; + + @FXML // ResourceBundle that was given to the FXMLLoader + private ResourceBundle resources; + + @FXML // URL location of the FXML file that was given to the FXMLLoader + private URL location; + + @FXML // This method is called by the FXMLLoader when initialization is complete + void initialize() { + + } + + public void connexion(ActionEvent actionEvent) { + Boolean connexion = false; + try { + connexion = ChatApp.getInstance().connexion(pseudonyme.getText()); + } catch (IOException e) { + e.printStackTrace(); + } + if(!connexion){ + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle("Connexion"); + // Header Text: null + alert.setHeaderText(null); + alert.setContentText("Echec de Connexion: le pseudo "+pseudonyme.getText()+" est deja pris"); + alert.showAndWait(); + } + else{ + Stage stage = (Stage) connexionButton.getScene().getWindow(); + Parent root = null; + try { + root = FXMLLoader.load(getClass().getResource("/fenetres/View_Menu.fxml")); + } catch (IOException e) { + e.printStackTrace(); + } + Scene scene = new Scene(root); + stage.setScene(scene); + stage.show(); + } + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/View/DemarrerSession.java b/Implementation/chatapp/src/main/java/chatapp/View/DemarrerSession.java new file mode 100644 index 0000000..d0ac6b0 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/DemarrerSession.java @@ -0,0 +1,67 @@ +/** + * Sample Skeleton for 'View_Demarrer_Session.fxml' Controller Class + */ + +package chatapp.View; + +import java.io.IOException; +import java.net.URL; +import java.util.ResourceBundle; + +import chatapp.Controller.ChatApp; +import chatapp.Model.ListUtilisateurs; +import chatapp.Model.Utilisateur; +import chatapp.Protocol.RunnerEcouteTCP; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.stage.Stage; + +public class DemarrerSession { + + @FXML // ResourceBundle that was given to the FXMLLoader + private ResourceBundle resources; + + @FXML // URL location of the FXML file that was given to the FXMLLoader + private URL location; + + @FXML // fx:id="choixContact" + private ComboBox choixContact; // Value injected by FXMLLoader + + @FXML // fx:id="MenuButton" + private Button MenuButton; // Value injected by FXMLLoader + private ChatApp chatApp; + + @FXML + void demarrerSessionAvec(ActionEvent event) { + chatApp.demarrerSession(choixContact.getValue()); + } + + @FXML + void retourMenu(ActionEvent event) { + Stage stage = (Stage) MenuButton.getScene().getWindow(); + Parent root = null; + try { + root = FXMLLoader.load(getClass().getResource("/fenetres/View_Menu.fxml")); + } catch (IOException e) { + e.printStackTrace(); + } + Scene scene = new Scene(root); + stage.setScene(scene); + stage.show(); + } + + @FXML // 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..9be24c5 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/FenetreSession.java @@ -0,0 +1,41 @@ +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; + 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.show(); + this.centerOnScreen(); + this.setOnCloseRequest(new EventHandler() { + public void handle(WindowEvent we) { + session.arretSession(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/Implementation/chatapp/src/main/java/chatapp/View/View_Menu.java b/Implementation/chatapp/src/main/java/chatapp/View/View_Menu.java new file mode 100644 index 0000000..0da233c --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/View_Menu.java @@ -0,0 +1,89 @@ +package chatapp.View; + + +import java.io.IOException; +import java.net.URL; +import java.util.ResourceBundle; + +import chatapp.Controller.ChatApp; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.MenuItem; +import javafx.scene.text.Text; +import javafx.stage.Stage; + +public class View_Menu { + + public Text pseudonyme; + public MenuItem utilsActifsButton; + public MenuItem demarrerSessionButton; + public MenuItem changerPseudoButton; + @FXML // ResourceBundle that was given to the FXMLLoader + private ResourceBundle resources; + private ChatApp chatapp; + @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() { + this.chatapp = ChatApp.getInstance(); + this.pseudonyme.setText(this.chatapp.getMe().getPseudo()); + } + + 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(); + } + + 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(); + } + + 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(); + } + + 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..6dc3779 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/View/View_Utilisateurs.java @@ -0,0 +1,54 @@ +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); + + + } + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Implementation/chatapp/src/main/resources/fenetres/View_ChangementPseudo.fxml b/Implementation/chatapp/src/main/resources/fenetres/View_ChangementPseudo.fxml new file mode 100644 index 0000000..0a7885a --- /dev/null +++ b/Implementation/chatapp/src/main/resources/fenetres/View_ChangementPseudo.fxml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Implementation/chatapp/src/main/resources/fenetres/View_Clavardage.fxml b/Implementation/chatapp/src/main/resources/fenetres/View_Clavardage.fxml new file mode 100644 index 0000000..9e8975e --- /dev/null +++ b/Implementation/chatapp/src/main/resources/fenetres/View_Clavardage.fxml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Implementation/src/Controller/ChatApp.java b/Implementation/src/Controller/ChatApp.java deleted file mode 100644 index ff0cabe..0000000 --- a/Implementation/src/Controller/ChatApp.java +++ /dev/null @@ -1,240 +0,0 @@ -package src.Controller; - -import java.io.IOException; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.InterfaceAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import src.Protocoles.*; - -/** -*

-* 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 mapHistorique ; - private boolean historiqueAvailable = true; - - /* ChatApp est associe a un utilisateur */ - private Utilisateur me; - - /** - * Constructeur de l'application de chat - * - * @param pseudo Pseudo de l'utilisateur - * @param port Port de communication - */ - public ChatApp(String pseudo, Integer port){ - 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.mapHistorique = new HashMap() ; - } - - /** - * Mettre a jour dans Maphistorique, l'historique avec un utilisateur dont le nom est pseudo - * - * @param pseudo Pseudo de l'utilisateur - * @param h nouvel Historique entre les deux utilisateurs - */ - public synchronized void majHistorique(Historique h) { - getMapHistorique().put(h.getUser2().getPseudo(),h); - } - - /*public void majHistorique2(MessageHorodate mh, String pseudo) { - Historique h = getMapHistorique().get(pseudo); - //h.addMessage(mh); - getMapHistorique().put(h.getUser2().getPseudo(),h); - }*/ - - public void majHistorique2(String mh, String pseudo) { - Historique h = getMapHistorique().get(pseudo); - MessageHorodate msghor = new MessageHorodate(this.getMe(),this.getMe(),"rien",1); - System.out.println(">>"+mh+"<<"); - System.out.print(msghor.getDateHorodatage()); - System.out.println(msghor.getDestinataire()); - System.out.println(msghor.getSource()); - System.out.println(msghor.getType()); - - h.addMessage(msghor); - 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); - 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 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); - System.exit(1); - } - - /** - * 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; - } - - /** - * Getter - * @return la map des historiques - */ - public Map getMapHistorique() { - return mapHistorique; - } - - /** - * Obtenir l'historique entre deux utilisateurs - * @param pseudo Pseudo de l'utilisateur dont on souhaite obtenir l'historique - * @return Un historique - */ - public synchronized Historique getHist(String pseudo) { - Historique h = this.mapHistorique.get(pseudo); - if( h != null) { - return h ; - } - else { - h = new Historique(this.me, this.getActifUsers().getPseudoList(pseudo)); - return h ; - } - } - - public static void main (String[] args) throws IOException { - ChatApp app = new ChatApp(args[0],Integer.parseInt(args[1])) ; - - - - - ExecutorService execUDP = Executors.newFixedThreadPool(1000); - execUDP.submit(new RunnerEcouteUDP(app)); - try { - app.connexion(); - } catch (IOException e) { - e.printStackTrace(); - } - ExecutorService execTCP = Executors.newFixedThreadPool(1000); - 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")); - } - - - - } - - public boolean isHistoriqueAvailable() { - return historiqueAvailable; - } - - public void setHistoriqueAvailable(boolean historiqueAvailable) { - this.historiqueAvailable = historiqueAvailable; - } - -} - diff --git a/Implementation/src/Controller/Historique.java b/Implementation/src/Controller/Historique.java deleted file mode 100644 index 270502a..0000000 --- a/Implementation/src/Controller/Historique.java +++ /dev/null @@ -1,63 +0,0 @@ -package src.Controller; - -import java.util.ArrayList; - -/** -*

-* 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 HistoriqueHorodate ; - - /** - *

- * 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 actifUsers ; - - public ListUtilisateurs() { - this.actifUsers = new ArrayList() ; - } - /** - * Ajouter des utilisateurs actifs dans l'attribut liste 'actifUsers' - * - * @param u on va rajouter cet utilisateur dans la liste - */ - public void addList(Utilisateur u) { - if((verifierUnicite(u.getPseudo()))) { - this.actifUsers.add(u); - } - - - } - - /** - * Recuperer un utilisateur à partir de son pseudo - * - * @param pseudo Pseudo de l'utilisateur que l'on souhaite retrouver - */ - public Utilisateur getPseudoList(String pseudo) { - for(Utilisateur elem: this.actifUsers) - { - if (elem.getPseudo().equals(pseudo) ) { - return elem ; - } - } - return null ; - } - - /** - * Supprimer de la liste des utilisateurs actifs 'actifUsers' un certain utilisateur - * - * @param u on va supprimer cet utilisateur dans la liste - */ - public void supprimerList(Utilisateur u) { - Boolean Sup = false ; - for(Utilisateur elem: this.actifUsers) - { - if (elem.equals(u) ) { - this.actifUsers.remove(elem); - Sup = true ; - this.afficherListeUtilisateurs(); - } - } - if (!Sup) { - System.out.println("Tentative de retirer un objet non contenu dans la liste"); - } - } - - /** - * Modifie le nom d'un utilisateur dans la liste des utilisateurs actifs 'actifUsers' - * - * @param ancien correspond au pseudo remplacer - * @param nouveau correspond au nouveau pseudo - */ - public void modifierList(String ancien , String nouveau) { - for(Utilisateur elem: this.actifUsers) - { - if (ancien.equals( elem.getPseudo() ) ) { - this.actifUsers.remove(elem); - elem.setPseudo(nouveau);; - this.addList(elem); - - } - } - this.afficherListeUtilisateurs(); - } - - public Boolean appartient(Utilisateur u) { - return this.actifUsers.contains(u); - } - - - - /** - * Verifie qu'aucun autre utilisateur ne possède le même pseudo - * - * @param u on va supprimer cet utilisateur dans la liste - */ - public Boolean verifierUnicite(String pseudo) { - for(Utilisateur elem: this.actifUsers) - { - if (pseudo.equals( elem.getPseudo() ) ) { - return false ; - } - } - return true; - } - - /** - * Méthode affichant la liste des utilisateurs actifs - * - */ - public String afficherListeUtilisateurs() { - System.out.println ("Liste des utilisateurs actifs : "); - String Utilisateur = "" ; - for(Utilisateur elem: this.actifUsers) - { - System.out.println (elem.toString()); - Utilisateur += (elem + "\n"); - } - return Utilisateur; - } -} diff --git a/Implementation/src/Controller/MessageHorodate.java b/Implementation/src/Controller/MessageHorodate.java deleted file mode 100644 index 1d86472..0000000 --- a/Implementation/src/Controller/MessageHorodate.java +++ /dev/null @@ -1,142 +0,0 @@ -package src.Controller; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -/** -*

-* 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 networkInterfaces = NetworkInterface - .getNetworkInterfaces(); - while (networkInterfaces.hasMoreElements()) { - NetworkInterface ni = (NetworkInterface) networkInterfaces - .nextElement(); - Enumeration nias = ni.getInetAddresses(); - while(nias.hasMoreElements()) { - InetAddress ia= (InetAddress) nias.nextElement(); - if (!ia.isLinkLocalAddress() - && !ia.isLoopbackAddress() - && ia instanceof Inet4Address) { - return ia; - } - } - } - } catch (Exception e) { - System.out.println("unable to get current IP " + e.getMessage()); - } - return null; - } - /** - *

- * 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 listAllBroadcastAddresses() throws SocketException { - List broadcastList = new ArrayList<>(); - Enumeration interfaces - = NetworkInterface.getNetworkInterfaces(); - while (interfaces.hasMoreElements()) { - NetworkInterface networkInterface = interfaces.nextElement(); - - if (networkInterface.isLoopback() || !networkInterface.isUp()) { - continue; - } - - networkInterface.getInterfaceAddresses().stream() - .map(a -> a.getBroadcast()) - .filter(Objects::nonNull) - .forEach(broadcastList::add); - } - return broadcastList; - } - -} - - - -/** -*

-* 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 vector = new Vector(); - for(String elem : utilisateurs.split("\n")) { - vector.add(elem); - } - // Créer une liste déroulante - JComboBox cb = new JComboBox(vector); - cb.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent event) { - Object selected = cb.getSelectedItem(); - new View_Clavardage(app, selected.toString()); - - } - }); - JPanel panel1 = new JPanel(new GridLayout(2,1)); - panel1.add(home); - panel1.add(cb); - frame.getContentPane().removeAll(); - frame.getContentPane().add(panel1,BorderLayout.CENTER); - frame.setVisible(true); - } }); - - //****************************************************************************************************************** - //**************************************** Actions lorsque l'on clique sur Pseudo ********************************** - //****************************************************************************************************************** - pseudo.addActionListener( new ActionListener(){ - public void actionPerformed(ActionEvent event) { - 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")); - home.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent event) { - frame.dispose(); - new View_Menu(app); - } }); - //Ajout d'un bouton Valider - JButton Valider = new JButton("Valider"); - frame.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) { - JOptionPane.showMessageDialog(frame, "Modification pseudo Reussi"); - frame.dispose(); - new View_Menu(app); - } - else { - JOptionPane.showMessageDialog(frame, "Echec Modification pseudo "); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - }); - JPanel panel1 = new JPanel(new GridLayout(4,1)); - panel1.add(home); - panel1.add(Text); - panel1.add(pseudofield); - panel1.add(Valider); - frame.getContentPane().removeAll(); - frame.getContentPane().add(panel1,BorderLayout.CENTER); - frame.setVisible(true); - }}); - //****************************************************************************************************************** - //**************************************** Actions lorsque l'on clique sur Deconnexion ***************************** - //****************************************************************************************************************** - deconnexion.addActionListener( new ActionListener(){ - public void actionPerformed(ActionEvent event) { - frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING)); - } }); - - } - -} - diff --git a/Implementation/src/View/jgoodies-forms-1.8.0-sources.jar b/Implementation/src/View/jgoodies-forms-1.8.0-sources.jar deleted file mode 100644 index b680434..0000000 Binary files a/Implementation/src/View/jgoodies-forms-1.8.0-sources.jar and /dev/null differ diff --git a/Implementation/src/View/jgoodies-forms-1.8.0.jar b/Implementation/src/View/jgoodies-forms-1.8.0.jar deleted file mode 100644 index 5e4585f..0000000 Binary files a/Implementation/src/View/jgoodies-forms-1.8.0.jar and /dev/null differ diff --git a/Implementation/src/images/Home.png b/Implementation/src/images/Home.png deleted file mode 100644 index b0c3484..0000000 Binary files a/Implementation/src/images/Home.png and /dev/null differ diff --git a/Implementation/src/images/Logo.png b/Implementation/src/images/Logo.png deleted file mode 100644 index 4c03097..0000000 Binary files a/Implementation/src/images/Logo.png and /dev/null differ