From 8794238d8933425c4f1b65f0221113791c7e5a79 Mon Sep 17 00:00:00 2001 From: Nabzzz Date: Sat, 26 Dec 2020 14:34:27 +0100 Subject: [PATCH 01/17] Nouvelle Interface graphique --- Implementation/.classpath | 10 - Implementation/.gitignore | 38 +- Implementation/.project | 17 - .../.settings/org.eclipse.jdt.core.prefs | 10 - Implementation/chatapp/.idea/.gitignore | 3 + .../chatapp/.idea/artifacts/chatapp.xml | 6 + Implementation/chatapp/.idea/compiler.xml | 6 + Implementation/chatapp/.idea/gradle.xml | 17 + .../chatapp/.idea/jarRepositories.xml | 20 + .../chatapp/.idea/libraries/lib.xml | 13 + Implementation/chatapp/.idea/misc.xml | 7 + Implementation/chatapp/.idea/modules.xml | 8 + .../chatapp/.idea/modules/chatapp.iml | 8 + Implementation/chatapp/build.gradle | 42 ++ .../main/fenetres/ConnexionScreen.fxml | 53 +++ .../main/fenetres/View_ChangementPseudo.fxml | 72 ++++ .../main/fenetres/View_Clavardage.fxml | 92 +++++ .../main/fenetres/View_Demarrer_Session.fxml | 62 +++ .../resources/main/fenetres/View_Menu.fxml | 54 +++ .../main/fenetres/View_Utilisateurs.fxml | 53 +++ .../compileJava/source-classes-mapping.txt | 42 ++ .../chatapp/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + Implementation/chatapp/gradlew | 185 +++++++++ Implementation/chatapp/gradlew.bat | 89 +++++ Implementation/chatapp/settings.gradle | 2 + .../main/java/chatapp/Controller/ChatApp.java | 309 +++++++++++++++ .../src/main/java/chatapp/Launcher.java | 7 + .../chatapp/src/main/java/chatapp/Main.java | 31 ++ .../main/java/chatapp/Model/Historique.java | 63 +++ .../java/chatapp/Model/ListUtilisateurs.java | 130 +++++++ .../java/chatapp/Model/MessageHorodate.java | 143 +++++++ .../main/java/chatapp/Model/Utilisateur.java | 78 ++++ .../chatapp/Protocol/RunnerEcouteTCP.java | 67 ++++ .../chatapp/Protocol/RunnerEcouteUDP.java | 16 + .../chatapp/Protocol/SessionClavardage.java | 183 +++++++++ .../java/chatapp/Protocol/TCPEchange.java | 322 ++++++++++++++++ .../java/chatapp/Protocol/UDPEchange.java | 360 ++++++++++++++++++ .../java/chatapp/View/ChangementPseudo.java | 87 +++++ .../main/java/chatapp/View/Clavardage.java | 97 +++++ .../java/chatapp/View/ConnexionScreen.java | 64 ++++ .../java/chatapp/View/DemarrerSession.java | 67 ++++ .../java/chatapp/View/FenetreSession.java | 41 ++ .../src/main/java/chatapp/View/View_Menu.java | 89 +++++ .../java/chatapp/View/View_Utilisateurs.java | 54 +++ .../resources/fenetres/ConnexionScreen.fxml | 53 +++ .../fenetres/View_ChangementPseudo.fxml | 72 ++++ .../resources/fenetres/View_Clavardage.fxml | 92 +++++ .../fenetres/View_Demarrer_Session.fxml | 62 +++ .../main/resources/fenetres/View_Menu.fxml | 54 +++ .../resources/fenetres/View_Utilisateurs.fxml | 53 +++ Implementation/src/Controller/ChatApp.java | 240 ------------ Implementation/src/Controller/Historique.java | 63 --- .../src/Controller/ListUtilisateurs.java | 114 ------ .../src/Controller/MessageHorodate.java | 142 ------- .../src/Controller/Modification_Pseudo.java | 51 --- .../src/Controller/Utilisateur.java | 77 ---- .../src/Protocoles/RunnerEcouteTCP.java | 16 - .../src/Protocoles/RunnerEcouteUDP.java | 16 - Implementation/src/Protocoles/TCPEchange.java | 320 ---------------- Implementation/src/Protocoles/UDPEchange.java | 358 ----------------- Implementation/src/View/View_Accueil.java | 133 ------- Implementation/src/View/View_Clavardage.java | 167 -------- Implementation/src/View/View_Menu.java | 256 ------------- .../src/View/jgoodies-forms-1.8.0-sources.jar | Bin 174177 -> 0 bytes .../src/View/jgoodies-forms-1.8.0.jar | Bin 131608 -> 0 bytes Implementation/src/images/Home.png | Bin 6845 -> 0 bytes Implementation/src/images/Logo.png | Bin 36313 -> 0 bytes 68 files changed, 3470 insertions(+), 1991 deletions(-) delete mode 100644 Implementation/.classpath delete mode 100644 Implementation/.project delete mode 100644 Implementation/.settings/org.eclipse.jdt.core.prefs create mode 100644 Implementation/chatapp/.idea/.gitignore create mode 100644 Implementation/chatapp/.idea/artifacts/chatapp.xml create mode 100644 Implementation/chatapp/.idea/compiler.xml create mode 100644 Implementation/chatapp/.idea/gradle.xml create mode 100644 Implementation/chatapp/.idea/jarRepositories.xml create mode 100644 Implementation/chatapp/.idea/libraries/lib.xml create mode 100644 Implementation/chatapp/.idea/misc.xml create mode 100644 Implementation/chatapp/.idea/modules.xml create mode 100644 Implementation/chatapp/.idea/modules/chatapp.iml create mode 100644 Implementation/chatapp/build.gradle create mode 100644 Implementation/chatapp/build/resources/main/fenetres/ConnexionScreen.fxml create mode 100644 Implementation/chatapp/build/resources/main/fenetres/View_ChangementPseudo.fxml create mode 100644 Implementation/chatapp/build/resources/main/fenetres/View_Clavardage.fxml create mode 100644 Implementation/chatapp/build/resources/main/fenetres/View_Demarrer_Session.fxml create mode 100644 Implementation/chatapp/build/resources/main/fenetres/View_Menu.fxml create mode 100644 Implementation/chatapp/build/resources/main/fenetres/View_Utilisateurs.fxml create mode 100644 Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt create mode 100644 Implementation/chatapp/gradle/wrapper/gradle-wrapper.jar create mode 100644 Implementation/chatapp/gradle/wrapper/gradle-wrapper.properties create mode 100644 Implementation/chatapp/gradlew create mode 100644 Implementation/chatapp/gradlew.bat create mode 100644 Implementation/chatapp/settings.gradle create mode 100644 Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/Launcher.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/Main.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/Model/Historique.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/Model/ListUtilisateurs.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/Model/MessageHorodate.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/Model/Utilisateur.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteTCP.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/Protocol/RunnerEcouteUDP.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/Protocol/TCPEchange.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/Protocol/UDPEchange.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/View/ConnexionScreen.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/View/DemarrerSession.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/View/FenetreSession.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/View/View_Menu.java create mode 100644 Implementation/chatapp/src/main/java/chatapp/View/View_Utilisateurs.java create mode 100644 Implementation/chatapp/src/main/resources/fenetres/ConnexionScreen.fxml create mode 100644 Implementation/chatapp/src/main/resources/fenetres/View_ChangementPseudo.fxml create mode 100644 Implementation/chatapp/src/main/resources/fenetres/View_Clavardage.fxml create mode 100644 Implementation/chatapp/src/main/resources/fenetres/View_Demarrer_Session.fxml create mode 100644 Implementation/chatapp/src/main/resources/fenetres/View_Menu.fxml create mode 100644 Implementation/chatapp/src/main/resources/fenetres/View_Utilisateurs.fxml delete mode 100644 Implementation/src/Controller/ChatApp.java delete mode 100644 Implementation/src/Controller/Historique.java delete mode 100644 Implementation/src/Controller/ListUtilisateurs.java delete mode 100644 Implementation/src/Controller/MessageHorodate.java delete mode 100644 Implementation/src/Controller/Modification_Pseudo.java delete mode 100644 Implementation/src/Controller/Utilisateur.java delete mode 100644 Implementation/src/Protocoles/RunnerEcouteTCP.java delete mode 100644 Implementation/src/Protocoles/RunnerEcouteUDP.java delete mode 100644 Implementation/src/Protocoles/TCPEchange.java delete mode 100644 Implementation/src/Protocoles/UDPEchange.java delete mode 100644 Implementation/src/View/View_Accueil.java delete mode 100644 Implementation/src/View/View_Clavardage.java delete mode 100644 Implementation/src/View/View_Menu.java delete mode 100644 Implementation/src/View/jgoodies-forms-1.8.0-sources.jar delete mode 100644 Implementation/src/View/jgoodies-forms-1.8.0.jar delete mode 100644 Implementation/src/images/Home.png delete mode 100644 Implementation/src/images/Logo.png 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 0000000000000000000000000000000000000000..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f GIT binary patch literal 59203 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

K7UpUK$>l@ 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 E2O(~oYXATM literal 0 HcmV?d00001 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 b680434d567a5c03ce6d5a8729f90008c064ac39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174177 zcma&MW0WXelcrs^ZR?b6*D2e!ZQHhO+qTV9wr%q}-Tlq<)9-p`*5t3um2vNgwfB#_ z@{W*`1O`C?fPjDiSTbOg2l&T@^7md^SV@3JTtgO@YN+4}`=X&;<4xX>BR`-+_%n--BG$nTD#@FgQoOow;?0I8n z2`|X_Gur08<*eWB=Vzza=j~k>Q2BGTwXS?ua-CTo58iI!@ehEkq0WGfj_5RZR^NhD zAqTDT=K)a7?ge@xd2iwC^#_COjp^qBb{v`yZ+%Q^#8-9NCT$PBQBnR!=I~IfRAuzT zF4aMeO@=RburxnA>(}UuVU}Mx&RK~?CTET4^TYK0ESZ%;`}^rPVpeuw&IjQmXvs;1Y9;v~`TD()mdtIJInsVIoA&-7FP&3wSe$XO9DF zF2_0}FU(L{A>8NyYIIK=N9|}^tpH@BG&`&ce9cP+P_Z{TUz|P$ywJlb3~2*nCq%T& z6~ajZbAJBijJ8CM6P&|G+E(?j-c4f5ZqSJ-1z#l;>jMiOo}P0?xnpW#f`SpFTTD*& z2t(f?#R<4%<0#8RUP^%Nc|fS`CZ*@k>-a4oR#d0qkbEgd=$KpdGVbEAcP@dIJ7nfk z9NHNWOK2V4$F%0uX$hW)Tr55eK7WCOaozSe(#5YuGkUZdQLWLhY9mI+eNQVOd?&^E zwMe#J(DJA0)hJ19zW&Gg7_Rf7y;TsXQ_L(Sj2FEl_tp`+Nx6$;=~?h7dm&D5A*Ifl z8@%e9CnjF%jVzP>s_lTqVl9!^b(5sV_}3*FL$x~P>Un8y<%nwpj%Ux1d4Al~+3EqR zueYQ^hr*^OR`BB4+_X6rQF#AsWfr@#VC9yLU+O

EDEz7*@gM><%S)J8j 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

  • `jTS`P^@>ok};G#-uwE}t31l*ZMJQRQZT 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 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 5e4585fd01fda214d76162e465940784bbbd3185..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131608 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 diff --git a/Implementation/src/images/Home.png b/Implementation/src/images/Home.png deleted file mode 100644 index b0c3484f178597bd17a547166b34e1a066d1664b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6845 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

    +51WI?0 zWC;>7SUV;kg}`cn&cI&^xg$BECNF=$OHI(x(V5LG3A$3Wk~I6AjYU#YKCEk1%rZzn zZ_(Vv5xo;*(XLR{9`HIFm!*PeLX9DqJp>6UDUM$rV|8^Cn@%FF#Uuow;yBY?mqr5 z(~54pzc7f4+!lx4osNnQyt5klxG|ozG2F`?g9xhH$ zdgXn#CEg;m3+y&hX;}7aPR)iz%v2dE{BeU&LI|*oAM1{;9k~# z+pKM`lN&X--o7PyY)?web}+X5m7f7q>p=gr^aEEZ!v~F!<(&~X?+T9VF#-tfg=zf$ zD*y%MjKgKXoJ5Fz_#SjRlGH8TKNtwT$~!HQDuVe z8$W_aMd*g=q@#&|F{O>4EPTgdFhlxiaaZPq0fH`ZI{4xzcT0fCP|^L6$%|?H?hZ*1 zZOQ{)F{m*Xg<6+IT_}hjELplSSJ`y6x6%t@!{s zR?E$2hTM{q6m}zdU~5PI%UAEfjvH106tJ^?PjM*?eeWnePG{VdsKQjt9U?jzn#a+j zmxJCDMVP>>B}c&V%2p$KpFI}lJ# zPEHc7xzp0p2Fl(PDx|nszpfrSJ)2Zv!ES3QuWwe>+?-i#l@UFBv#9qm2Eq@leBB@| zYyyfZT2g5Yt{i1P4wE#pv8v}g(@gX~{m5U31T(n!w*LeO8ZYPnuRZhwwX-#50sC(k zYYN0zc>En=k8KWLA7_$&ZjRFH!`1?u>z!8yEzNj*thY>C-*R{0+dIHvrunnXa$mg> zntA+u`to}PoLP5emkU{5>;EfrBXU-)A#i0~-}w!`&K5T=U9jVOxWG1e3UC%KL54|y z?^vdG1Q(N?;DgxS`hP#uf4x}Tzant4Ti)r4Hye*<0FTE%ayhZ$RZyVgTO0Ax-m1Rx z74Pov-#^RbPvBbX--ZS0dslpTzyH71xl4O2=WGw2YNL7o+f4z!Z6;g#oh>rXi>NjM z#~|AoTAB-QaZLlVfm01FGk|{UkY?xyb}2YCfz8b6w@8#)WFPiu^Y_TnIYxdqC=fU?TsnZX3^+CcgTe~DWM4fu#pwj From c4eccf38a97401ec0ae04cce52e731b04b9e26ba Mon Sep 17 00:00:00 2001 From: Nabzzz Date: Sat, 26 Dec 2020 23:14:00 +0100 Subject: [PATCH 02/17] Nouvelle interface graphique --- .../chatapp/.idea/modules/chatapp.iml | 4 + Implementation/chatapp/.idea/vcs.xml | 6 + .../compileJava/source-classes-mapping.txt | 11 +- .../main/java/chatapp/Controller/ChatApp.java | 65 +--- .../src/main/java/chatapp/Model/DataBase.java | 234 +++++++++++++ .../main/java/chatapp/Model/Historique.java | 63 ---- .../java/chatapp/Protocol/TCPEchange.java | 322 ------------------ .../main/java/chatapp/View/Clavardage.java | 11 + 8 files changed, 269 insertions(+), 447 deletions(-) create mode 100644 Implementation/chatapp/.idea/vcs.xml create mode 100644 Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java delete mode 100644 Implementation/chatapp/src/main/java/chatapp/Model/Historique.java delete mode 100644 Implementation/chatapp/src/main/java/chatapp/Protocol/TCPEchange.java diff --git a/Implementation/chatapp/.idea/modules/chatapp.iml b/Implementation/chatapp/.idea/modules/chatapp.iml index fd15dcb..73cec4e 100644 --- a/Implementation/chatapp/.idea/modules/chatapp.iml +++ b/Implementation/chatapp/.idea/modules/chatapp.iml @@ -2,6 +2,10 @@ + + + + diff --git a/Implementation/chatapp/.idea/vcs.xml b/Implementation/chatapp/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/Implementation/chatapp/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt index a074e7b..7298c1b 100644 --- a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt +++ b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt @@ -1,13 +1,15 @@ +chatapp/Launcher.java + chatapp.Launcher 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/Model/MessageHorodate.java + chatapp.Model.MessageHorodate +chatapp/Model/DataBase.java + chatapp.Model.DataBase chatapp/Protocol/RunnerEcouteTCP.java chatapp.Protocol.RunnerEcouteTCP chatapp/View/FenetreSession.java @@ -30,6 +32,7 @@ chatapp/Main.java chatapp.Main chatapp/View/Clavardage.java chatapp.View.Clavardage + chatapp.View.Clavardage$1 chatapp/Protocol/SessionClavardage.java chatapp.Protocol.SessionClavardage chatapp/View/ConnexionScreen.java diff --git a/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java index 227305a..7252438 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java +++ b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java @@ -1,9 +1,6 @@ package chatapp.Controller; -import chatapp.Model.Historique; -import chatapp.Model.ListUtilisateurs; -import chatapp.Model.MessageHorodate; -import chatapp.Model.Utilisateur; +import chatapp.Model.*; import chatapp.Protocol.*; import javafx.application.Application; import javafx.application.Platform; @@ -22,9 +19,7 @@ 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; @@ -36,7 +31,7 @@ public class ChatApp implements PropertyChangeListener { private static ChatApp chatapp = null; private RunnerEcouteTCP runnerEcouteTCP; private RunnerEcouteUDP runnerEcouteUDP; - + private DataBase db; /** * Constructeur de l'application de chat @@ -51,8 +46,9 @@ public class ChatApp implements PropertyChangeListener { ip = UDPEchange.getCurrentIp(); this.me = new Utilisateur(pseudo,port,ip); this.actifUsers.addList(getMe()); - this.mapHistorique = new HashMap() ; + this.main = main; + //this.db= DataBase.getInstance(); } public static synchronized ChatApp getInstance(String pseudo, Integer port, Application main){ @@ -66,14 +62,7 @@ public class ChatApp implements PropertyChangeListener { 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); @@ -81,18 +70,6 @@ public class ChatApp implements PropertyChangeListener { 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 @@ -230,29 +207,8 @@ public class ChatApp implements PropertyChangeListener { 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) ; @@ -285,13 +241,6 @@ public class ChatApp implements PropertyChangeListener { }*/ - public boolean isHistoriqueAvailable() { - return historiqueAvailable; - } - - public void setHistoriqueAvailable(boolean historiqueAvailable) { - this.historiqueAvailable = historiqueAvailable; - } @Override public void propertyChange(PropertyChangeEvent evt) { diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java new file mode 100644 index 0000000..ef01281 --- /dev/null +++ b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java @@ -0,0 +1,234 @@ +package chatapp.Model; +import java.io.IOException; +import java.sql.*; +import java.util.Date; +import java.sql.DriverManager; + +public class DataBase { + private String DBurl = "jdbc:mysql://srv-bdens.insa-toulouse.fr:3306" ; + private Connection connection = null; + private String login = "tp_servlet_006"; + private String pswd = "baePh9ei"; + + + /*Format de la table Utilisateurs + +--------+-------------+---------+---------------------+ + | ID | Pseudo | Actif | Date d'inscription | + +--------+-------------+---------+---------------------+ + Id correspond à l'addresse IP + Pseudo : Dernier Pseudo utilisé pour cette adresse IP, va etre remplacé par le pseudo actuel avec majPseudo + Date d'inscription comme son nom l'indique le jour de l'inscription de cette utilisateur + Actif est un boolean indicant si l'utilisateur est actif + + Chaque communication entres utilisateurs sera stocké dans une table de la forme + +------------------+-----------+---------------+---------------+ + | Destinataire | Source | Message | Date d'envoi | + +--------+---------------------+---------------+---------------+ + Destinataire -> Id du destinataire du message + Source -> Id de celui qui envoie le message + Message -> Msg envoye + Date d'envoie -> Date a laquelle Source a envoye le message a destinataire + */ + + private static DataBase instance = null; // Singleton + + public DataBase() { + try { + // Besoin d'installer le driver JDBC entre java IDE et le system DBMS pour faire un pont entre les deux + Class.forName("com.mysql.cj.jdbc.Driver"); + System.out.println("Driver Installe"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + System.out.println("Echec installation Driver"); + } + + try { + // Etablir une connexion , forme : (url, "myLogin", "myPassword"); + this.connection = DriverManager.getConnection("jdbc:mysql://localhost:8889/POO_AL_NM?allowPublicKeyRetrieval=true&useSSL=false", "root", "root"); + //this.connection = DriverManager.getConnection(this.DBurl,login,pswd); + System.out.println("Connexion Etablie"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec d'etablissement de la connexion"); + } + } + + public static DataBase getInstance() { + synchronized (DataBase.class) { + DataBase DB = instance; + if (DB == null) { + DB = new DataBase(); + } + return DB; + } + } + + /* + * Methode permettant de creer une table pour stocker les messages entre deux utilisateurs + * @param ID1 Id du premier utilisateur + * @param ID2 Id du second utilisateur + */ + public void CreationTableHistorique(String ID1 , String ID2) { + // Pour eviter d'avoir les tables en double + String petit; + String grand; + int comparaison = ID1.compareTo(ID2); + if (comparaison < 0) { + petit = ID1; + grand = ID2 ; + } + else { + petit = ID2; + grand = ID1 ; + } + String nomTable = "Chat_" + petit + "_" + grand ; + String Requete = "CREATE TABLE IF NOT EXISTS`" + nomTable +"` (\n" + "`Destinataire` varchar(100) NOT NULL,\n" + " `Source` varchar(100) NOT NULL,\n" + " `Envoi` timestamp NOT NULL,\n" + " `Message` text NOT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ;"; + System.out.println(Requete); + PreparedStatement Ps = null ; + //Statement est utilisé pour envoyer une requete SQL à la base de donnee + try { + Ps = connection.prepareStatement(Requete); + System.out.println("Statement cree"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec creation Statement"); + } + + //Execute la donnée SQL statement passe en parametre + try { + Ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println(" Echec executeUpdate "); + } + } + + /* + * Methode permettant de mettre a jour le pseudo d'un utilisateur en fonction de son ID dans la base de donnee + * @param ID Id de l'utilisateur qui vient de changer de pseudo + * @param Pseudo Nouveau Pseudo de l'utilisateur + */ + public void majPseudo( String ID , String Pseudo) { + String requete= "UPDATE `Utilisateurs` SET `Pseudo`=? WHERE id=?"; + PreparedStatement Ps = null ; + //Statement est utilisé pour envoyer une requete SQL à la base de donnee + try { + Ps = connection.prepareStatement(requete); + Ps.setString(1, Pseudo); + Ps.setString(2, ID); + System.out.println("Statement cree"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec creation Statement"); + } + //Execute la donnée SQL statement passe en parametre + try { + Ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println(" Echec executeUpdate "); + } + } + + + + /* + * Methode permettant de mettre a jour le pseudo d'un utilisateur en fonction de son ID dans la base de donnee + * @param IDdest Id de l'utilisateur Destinataire du message + * @param IDdest Id de celui qui envoi le message + * @param Msg Message envoye entre les deux utilisateurs + */ + public void ajoutHistorique(String IDdest , String IDsrc, String Msg) { + String petit; + String grand; + int comparaison = IDdest.compareTo(IDsrc); + if (comparaison < 0) { + petit = IDdest; + grand = IDsrc ; + } + else { + petit = IDsrc; + grand = IDdest ; + } + String nomTable = "Chat_" + petit + "_" + grand ; + String requete= "INSERT INTO `"+ nomTable +"`(`Destinataire`, `Source`, `Message`) VALUES ( ? , ? , ?)"; + PreparedStatement Ps = null ; + //Statement est utilisé pour envoyer une requete SQL à la base de donnee + try { + Ps = connection.prepareStatement(requete); + Ps.setString(1, IDdest); + Ps.setString(2, IDsrc); + Ps.setString(3, Msg); + System.out.println("Statement cree"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec creation Statement"); + } + + //Execute la donnée SQL statement passe en parametre + try { + Ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println(" Echec executeUpdate "); + } + } + + + /* + * Methode permettant de mettre a jour le pseudo d'un utilisateur en fonction de son ID dans la base de donnee + * @param ID Id de l'utilisateur qui vient de se connecter pour la premiere fois + * @param Pseudo pseudo actuelle de l'utilisateur + */ + public void ajoutUtilisateurs(String ID , String Pseudo ) { + String requete= "INSERT INTO `Utilisateurs` (`ID`, `Pseudo`, `Actif`) VALUES ( ? , ? , '1')"; + PreparedStatement Ps = null ; + //Statement est utilisé pour envoyer une requete SQL à la base de donnee + try { + Ps = connection.prepareStatement(requete); + Ps.setString(1, ID); + Ps.setString(2, Pseudo); + System.out.println("Statement cree"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec creation Statement"); + } + + //Execute la donnée SQL statement passe en parametre + try { + Ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println(" Echec executeUpdate "); + } + } + + /* + * Methode permettant de mettre a jour les utilisateurs actuellement actif + * @param ID Id de l'utilisateur qui vient de se connecter ou deconnecter + * @param connecte Boolean true si il est connecte , false sinon + */ + public void majUtilisateursActifs(Boolean Connecte, String Id) { + String requete= "UPDATE `Utilisateurs` SET `Actif`=? WHERE id=?"; + PreparedStatement Ps = null ; + Integer Actif = Connecte ? 1 : 0; + //Statement est utilisé pour envoyer une requete SQL à la base de donnee + try { + Ps = connection.prepareStatement(requete); + Ps.setInt(1, Actif); + Ps.setString(2, Id); + System.out.println("Statement cree"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec creation Statement"); + } + //Execute la donnée SQL statement passe en parametre + try { + Ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println(" Echec executeUpdate "); + } + } + +} diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/Historique.java b/Implementation/chatapp/src/main/java/chatapp/Model/Historique.java deleted file mode 100644 index 97cfbd6..0000000 --- a/Implementation/chatapp/src/main/java/chatapp/Model/Historique.java +++ /dev/null @@ -1,63 +0,0 @@ -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 - * 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/View/Clavardage.java b/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java index ac34cdc..c02623f 100644 --- a/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java +++ b/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java @@ -10,6 +10,7 @@ import chatapp.Controller.ChatApp; import chatapp.Model.MessageHorodate; import chatapp.Model.Utilisateur; import chatapp.Protocol.SessionClavardage; +import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; @@ -17,6 +18,7 @@ import javafx.scene.control.Button; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.text.Text; +import javafx.stage.Stage; public class Clavardage implements Initializable, PropertyChangeListener { @@ -83,6 +85,15 @@ public class Clavardage implements Initializable, PropertyChangeListener { msg+=": "+msgh.getMessage(); ChatText.appendText(msg); break; + case "FinDeLaSession" : + this.session.arretSession(); + Platform.runLater(new Runnable() { + @Override + public void run() { + Stage stage = (Stage) AEnvoyer.getScene().getWindow(); + stage.close(); + } + }); } } From 42ae14a012821cc0dbda1766d8d8c15785f8b2e5 Mon Sep 17 00:00:00 2001 From: alartigu Date: Sun, 27 Dec 2020 10:35:26 +0400 Subject: [PATCH 03/17] structure nouvelle fonction --- .../tmp/compileJava/source-classes-mapping.txt | 16 ++++++++-------- .../main/java/chatapp/Controller/ChatApp.java | 2 +- .../src/main/java/chatapp/Model/DataBase.java | 17 +++++++++++++++++ 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt index 7298c1b..6428c35 100644 --- a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt +++ b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt @@ -8,15 +8,15 @@ chatapp/Model/Historique.java chatapp.Model.Historique chatapp/Model/MessageHorodate.java chatapp.Model.MessageHorodate -chatapp/Model/DataBase.java - chatapp.Model.DataBase +chatapp/View/View_Menu.java + chatapp.View.View_Menu 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/DemarrerSession.java + chatapp.View.DemarrerSession chatapp/View/ChangementPseudo.java chatapp.View.ChangementPseudo chatapp/Protocol/RunnerEcouteUDP.java @@ -39,7 +39,7 @@ 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 +chatapp/Controller/ChatApp.java + chatapp.Controller.ChatApp +chatapp/Model/DataBase.java + chatapp.Model.DataBase diff --git a/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java index 7252438..108bd62 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java +++ b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java @@ -48,7 +48,7 @@ public class ChatApp implements PropertyChangeListener { this.actifUsers.addList(getMe()); this.main = main; - //this.db= DataBase.getInstance(); + this.db= DataBase.getInstance(); } public static synchronized ChatApp getInstance(String pseudo, Integer port, Application main){ diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java index ef01281..92f384c 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java +++ b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java @@ -181,6 +181,12 @@ public class DataBase { * @param Pseudo pseudo actuelle de l'utilisateur */ public void ajoutUtilisateurs(String ID , String Pseudo ) { + // Verification que l'utilisateur n'existe pas + + + + + String requete= "INSERT INTO `Utilisateurs` (`ID`, `Pseudo`, `Actif`) VALUES ( ? , ? , '1')"; PreparedStatement Ps = null ; //Statement est utilisé pour envoyer une requete SQL à la base de donnee @@ -231,4 +237,15 @@ public class DataBase { } } + /* + * Methode permettant de recuperer les 20 derniers messages envoyés entre 2 utilisateurs + * @param ID Utilisateur associé a ChatApp + * @param destinataire Celui avec qui correspond ID + * @return Les 20 derniers Messages + */ + public String recup20Msg(String ID, String IDdestinataire) { + String Msg = "" ; + return Msg ; + } + } From 22143615ba26e30e006860379b29f15755d67b38 Mon Sep 17 00:00:00 2001 From: alartigu Date: Sun, 27 Dec 2020 11:00:47 +0400 Subject: [PATCH 04/17] Impossible de se connecter a BDD --- .../src/main/java/chatapp/Model/DataBase.java | 150 +++++++++++++++--- 1 file changed, 124 insertions(+), 26 deletions(-) diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java index 92f384c..d068243 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java +++ b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java @@ -176,36 +176,58 @@ public class DataBase { /* - * Methode permettant de mettre a jour le pseudo d'un utilisateur en fonction de son ID dans la base de donnee - * @param ID Id de l'utilisateur qui vient de se connecter pour la premiere fois + * Methode permettant d'ajouter un utilisateur dans la base de donnée si celui-ci n'existe pas deja + * @param ID Id de l'utilisateur que l'on veut rajouter * @param Pseudo pseudo actuelle de l'utilisateur */ public void ajoutUtilisateurs(String ID , String Pseudo ) { // Verification que l'utilisateur n'existe pas - - - - - - String requete= "INSERT INTO `Utilisateurs` (`ID`, `Pseudo`, `Actif`) VALUES ( ? , ? , '1')"; - PreparedStatement Ps = null ; - //Statement est utilisé pour envoyer une requete SQL à la base de donnee + String existe= "SELECT Pseudo FROM Customers WHERE ID = " + ID; + Statement stmt = null; + ResultSet rs = null ; try { - Ps = connection.prepareStatement(requete); - Ps.setString(1, ID); - Ps.setString(2, Pseudo); - System.out.println("Statement cree"); - } catch (SQLException e) { - e.printStackTrace(); - System.out.println("Echec creation Statement"); + stmt = this.connection.createStatement(); + } catch (SQLException throwables) { + throwables.printStackTrace(); } - - //Execute la donnée SQL statement passe en parametre try { - Ps.executeUpdate(); - } catch (SQLException e) { - e.printStackTrace(); - System.out.println(" Echec executeUpdate "); + rs = stmt.executeQuery(existe); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + String P = "" ; + try { + P = rs.getString("Pseudo"); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + if( !P.equals("") ) { + // L'utilisateur existe deja + if (!P.equals(Pseudo)){ + this.majPseudo(ID,Pseudo); // On met a jour le nouveau pseudo + } + } + else { + String requete = "INSERT INTO `Utilisateurs` (`ID`, `Pseudo`, `Actif`) VALUES ( ? , ? , '1')"; + PreparedStatement Ps = null; + //Statement est utilisé pour envoyer une requete SQL à la base de donnee + try { + Ps = connection.prepareStatement(requete); + Ps.setString(1, ID); + Ps.setString(2, Pseudo); + System.out.println("Statement cree"); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Echec creation Statement"); + } + + //Execute la donnée SQL statement passe en parametre + try { + Ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + System.out.println(" Echec executeUpdate "); + } } } @@ -238,14 +260,90 @@ public class DataBase { } /* - * Methode permettant de recuperer les 20 derniers messages envoyés entre 2 utilisateurs + * Methode permettant de recuperer les N derniers messages envoyés entre 2 utilisateurs * @param ID Utilisateur associé a ChatApp * @param destinataire Celui avec qui correspond ID - * @return Les 20 derniers Messages + * @return Les N derniers Messages */ - public String recup20Msg(String ID, String IDdestinataire) { + public String recupNMsg(String ID, String IDdestinataire, int N) { String Msg = "" ; + String petit; + String grand; + int comparaison = ID.compareTo(IDdestinataire); + if (comparaison < 0) { + petit = ID; + grand = IDdestinataire; + } + else { + petit = ID; + grand = IDdestinataire ; + } + String nomTable = "Chat_" + petit + "_" + grand ; + String requete= "SELECT * FROM nomTable"; + Statement stmt = null; + ResultSet rs = null ; + try { + stmt = this.connection.createStatement(); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + try { + rs = stmt.executeQuery(requete); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + + for(int i = 0 ; i < N; i++){ + try { + if( rs.next()){ + String IDSource = rs.getString("Source"); + String Envoi = rs.getTimestamp("Envoi").toString(); + String Message = rs.getString("Message"); + if (IDSource.equals(ID)){ + Msg += ( "Moi (" + Envoi + ") : " + Message ) ; + } + else { + String PseudoSource = getPseudo(IDSource) ; + Msg += ( PseudoSource + "(" + Envoi + ") : " + Message ); + } + + } + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + } + return Msg ; } + /* + * Methode permettant de recuperer le pseudo actuel d'un utilisateur en fonction de son ID + * @param ID Id de l'utilsateur dont on veut connaitre le pseudo + * @return Pseudo + */ + private String getPseudo(String idSource) { + String Pseudo = "" ; + String requete= "SELECT * FROM `Utilisateurs` WHERE ID = " + idSource; + Statement stmt = null; + ResultSet rs = null ; + try { + stmt = this.connection.createStatement(); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + try { + rs = stmt.executeQuery(requete); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + try { + if (! rs.getString("Pseudo").equals(null) ){ + Pseudo = rs.getString("Pseudo") ; + } + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + return Pseudo ; + } + } From ed2780f422f325df8ae829e00d140ef02bcd8db3 Mon Sep 17 00:00:00 2001 From: alartigu Date: Sun, 27 Dec 2020 12:18:35 +0400 Subject: [PATCH 05/17] Bouton entrer poour page de connexion et clavardage --- Implementation/chatapp/.idea/chatapp.iml | 9 ++++ .../libraries/mysql_connector_java_8_0_22.xml | 9 ++++ .../chatapp/.idea/modules/chatapp.iml | 2 + .../compileJava/source-classes-mapping.txt | 54 +++++++++---------- .../src/main/java/chatapp/Model/DataBase.java | 4 +- .../java/chatapp/View/ChangementPseudo.java | 2 +- .../main/java/chatapp/View/Clavardage.java | 2 + .../java/chatapp/View/ConnexionScreen.java | 1 + 8 files changed, 49 insertions(+), 34 deletions(-) create mode 100644 Implementation/chatapp/.idea/chatapp.iml create mode 100644 Implementation/chatapp/.idea/libraries/mysql_connector_java_8_0_22.xml diff --git a/Implementation/chatapp/.idea/chatapp.iml b/Implementation/chatapp/.idea/chatapp.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/Implementation/chatapp/.idea/chatapp.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Implementation/chatapp/.idea/libraries/mysql_connector_java_8_0_22.xml b/Implementation/chatapp/.idea/libraries/mysql_connector_java_8_0_22.xml new file mode 100644 index 0000000..8a0367c --- /dev/null +++ b/Implementation/chatapp/.idea/libraries/mysql_connector_java_8_0_22.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Implementation/chatapp/.idea/modules/chatapp.iml b/Implementation/chatapp/.idea/modules/chatapp.iml index 73cec4e..612440a 100644 --- a/Implementation/chatapp/.idea/modules/chatapp.iml +++ b/Implementation/chatapp/.idea/modules/chatapp.iml @@ -8,5 +8,7 @@ + + \ No newline at end of file diff --git a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt index 6428c35..d62e2f3 100644 --- a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt +++ b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt @@ -1,45 +1,39 @@ +chatapp/Protocol/RunnerEcouteTCP.java + chatapp.Protocol.RunnerEcouteTCP +chatapp/View/DemarrerSession.java + chatapp.View.DemarrerSession +chatapp/Controller/ChatApp.java + chatapp.Controller.ChatApp +chatapp/Model/DataBase.java + chatapp.Model.DataBase +chatapp/Model/Utilisateur.java + chatapp.Model.Utilisateur +chatapp/Protocol/RunnerEcouteUDP.java + chatapp.Protocol.RunnerEcouteUDP chatapp/Launcher.java chatapp.Launcher chatapp/Model/ListUtilisateurs.java chatapp.Model.ListUtilisateurs -chatapp/Model/Utilisateur.java - chatapp.Model.Utilisateur -chatapp/Model/Historique.java - chatapp.Model.Historique -chatapp/Model/MessageHorodate.java - chatapp.Model.MessageHorodate -chatapp/View/View_Menu.java - chatapp.View.View_Menu -chatapp/Protocol/RunnerEcouteTCP.java - chatapp.Protocol.RunnerEcouteTCP -chatapp/View/FenetreSession.java - chatapp.View.FenetreSession - chatapp.View.FenetreSession$1 -chatapp/View/DemarrerSession.java - chatapp.View.DemarrerSession -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/Model/MessageHorodate.java + chatapp.Model.MessageHorodate chatapp/Main.java chatapp.Main -chatapp/View/Clavardage.java - chatapp.View.Clavardage - chatapp.View.Clavardage$1 +chatapp/View/View_Menu.java + chatapp.View.View_Menu chatapp/Protocol/SessionClavardage.java chatapp.Protocol.SessionClavardage chatapp/View/ConnexionScreen.java chatapp.View.ConnexionScreen chatapp/View/View_Utilisateurs.java chatapp.View.View_Utilisateurs -chatapp/Controller/ChatApp.java - chatapp.Controller.ChatApp -chatapp/Model/DataBase.java - chatapp.Model.DataBase +chatapp/View/ChangementPseudo.java + chatapp.View.ChangementPseudo +chatapp/View/FenetreSession.java + chatapp.View.FenetreSession + chatapp.View.FenetreSession$1 +chatapp/View/Clavardage.java + chatapp.View.Clavardage + chatapp.View.Clavardage$1 diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java index d068243..28b182e 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java +++ b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java @@ -1,8 +1,6 @@ package chatapp.Model; -import java.io.IOException; + import java.sql.*; -import java.util.Date; -import java.sql.DriverManager; public class DataBase { private String DBurl = "jdbc:mysql://srv-bdens.insa-toulouse.fr:3306" ; diff --git a/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java b/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java index 51ccf41..a2f8d27 100644 --- a/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java +++ b/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java @@ -82,6 +82,6 @@ public class ChangementPseudo { void initialize() { chatApp = ChatApp.getInstance(); pseudonyme1.setText(chatApp.getMe().getPseudo()); - + this.validationButton.setDefaultButton(true); } } \ 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 index c02623f..1992220 100644 --- a/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java +++ b/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java @@ -104,5 +104,7 @@ public class Clavardage implements Initializable, PropertyChangeListener { @Override public void initialize(URL location, ResourceBundle resources) { + EnvoyerButton.setDefaultButton(true); + this.ChatText.setEditable(false); } } \ 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 index a8043bb..708ec8a 100644 --- a/Implementation/chatapp/src/main/java/chatapp/View/ConnexionScreen.java +++ b/Implementation/chatapp/src/main/java/chatapp/View/ConnexionScreen.java @@ -30,6 +30,7 @@ public class ConnexionScreen { @FXML // This method is called by the FXMLLoader when initialization is complete void initialize() { + connexionButton.setDefaultButton(true); } From 2d4b5498249abd604c85a5bfa7d646a395ba4f94 Mon Sep 17 00:00:00 2001 From: moukhlis Date: Sun, 27 Dec 2020 11:25:20 +0100 Subject: [PATCH 06/17] Implementation de la bdd --- .../chatapp/.idea/modules/chatapp.iml | 2 - Implementation/chatapp/build.gradle | 1 + .../compileJava/source-classes-mapping.txt | 48 +++++++++---------- .../main/java/chatapp/Controller/ChatApp.java | 2 + .../src/main/java/chatapp/Model/DataBase.java | 2 +- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/Implementation/chatapp/.idea/modules/chatapp.iml b/Implementation/chatapp/.idea/modules/chatapp.iml index 612440a..73cec4e 100644 --- a/Implementation/chatapp/.idea/modules/chatapp.iml +++ b/Implementation/chatapp/.idea/modules/chatapp.iml @@ -8,7 +8,5 @@ - - \ No newline at end of file diff --git a/Implementation/chatapp/build.gradle b/Implementation/chatapp/build.gradle index 3fe60d2..c76d1ef 100644 --- a/Implementation/chatapp/build.gradle +++ b/Implementation/chatapp/build.gradle @@ -23,6 +23,7 @@ javafx { dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' + compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.22' runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:win" runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:linux" runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:mac" diff --git a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt index d62e2f3..72f3b56 100644 --- a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt +++ b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt @@ -1,39 +1,39 @@ -chatapp/Protocol/RunnerEcouteTCP.java - chatapp.Protocol.RunnerEcouteTCP -chatapp/View/DemarrerSession.java - chatapp.View.DemarrerSession -chatapp/Controller/ChatApp.java - chatapp.Controller.ChatApp -chatapp/Model/DataBase.java - chatapp.Model.DataBase +chatapp/Model/MessageHorodate.java + chatapp.Model.MessageHorodate chatapp/Model/Utilisateur.java chatapp.Model.Utilisateur -chatapp/Protocol/RunnerEcouteUDP.java - chatapp.Protocol.RunnerEcouteUDP -chatapp/Launcher.java - chatapp.Launcher chatapp/Model/ListUtilisateurs.java chatapp.Model.ListUtilisateurs +chatapp/Launcher.java + chatapp.Launcher +chatapp/Model/DataBase.java + chatapp.Model.DataBase +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/UDPEchange.java chatapp.Protocol.RunnerUDP chatapp.Protocol.UDPEchange -chatapp/Model/MessageHorodate.java - chatapp.Model.MessageHorodate chatapp/Main.java chatapp.Main -chatapp/View/View_Menu.java - chatapp.View.View_Menu +chatapp/View/Clavardage.java + chatapp.View.Clavardage + chatapp.View.Clavardage$1 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/ChangementPseudo.java - chatapp.View.ChangementPseudo -chatapp/View/FenetreSession.java - chatapp.View.FenetreSession - chatapp.View.FenetreSession$1 -chatapp/View/Clavardage.java - chatapp.View.Clavardage - chatapp.View.Clavardage$1 +chatapp/View/View_Menu.java + chatapp.View.View_Menu +chatapp/View/DemarrerSession.java + chatapp.View.DemarrerSession diff --git a/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java index 108bd62..2fb53b5 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java +++ b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java @@ -148,6 +148,8 @@ public class ChatApp implements PropertyChangeListener { } if (UDPEchange.getConnecte()) { System.out.println("Connexion reussie"); + //db.ajoutUtilisateurs(this.me.getId(),this.me.getPseudo()); + db.majPseudo("MacYAYA",this.me.getPseudo()); return true; } else diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java index 28b182e..9148834 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java +++ b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java @@ -42,7 +42,7 @@ public class DataBase { try { // Etablir une connexion , forme : (url, "myLogin", "myPassword"); - this.connection = DriverManager.getConnection("jdbc:mysql://localhost:8889/POO_AL_NM?allowPublicKeyRetrieval=true&useSSL=false", "root", "root"); + this.connection = DriverManager.getConnection("jdbc:mysql://localhost/POO_AL_NM?allowPublicKeyRetrieval=true&useSSL=false", "root", "1234"); //this.connection = DriverManager.getConnection(this.DBurl,login,pswd); System.out.println("Connexion Etablie"); } catch (SQLException e) { From 7f1fb4a9295f00890e22cefea95786f373ff7e8d Mon Sep 17 00:00:00 2001 From: moukhlis Date: Sun, 27 Dec 2020 16:13:16 +0100 Subject: [PATCH 07/17] Implementation de la bdd --- .../build/tmp/compileJava/source-classes-mapping.txt | 12 ++++++------ .../src/main/java/chatapp/Controller/ChatApp.java | 7 +++++++ .../src/main/java/chatapp/Model/DataBase.java | 4 ++-- .../java/chatapp/Protocol/SessionClavardage.java | 6 ++++++ 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt index 72f3b56..af49828 100644 --- a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt +++ b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt @@ -1,11 +1,11 @@ -chatapp/Model/MessageHorodate.java - chatapp.Model.MessageHorodate -chatapp/Model/Utilisateur.java - chatapp.Model.Utilisateur -chatapp/Model/ListUtilisateurs.java - chatapp.Model.ListUtilisateurs chatapp/Launcher.java chatapp.Launcher +chatapp/Model/ListUtilisateurs.java + chatapp.Model.ListUtilisateurs +chatapp/Model/Utilisateur.java + chatapp.Model.Utilisateur +chatapp/Model/MessageHorodate.java + chatapp.Model.MessageHorodate chatapp/Model/DataBase.java chatapp.Model.DataBase chatapp/Protocol/RunnerEcouteTCP.java diff --git a/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java index 2fb53b5..0814c4a 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java +++ b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java @@ -98,6 +98,7 @@ public class ChatApp implements PropertyChangeListener { //-------Change son propre nom d'utilisateur-------// this.getActifUsers().modifierList(this.getMe().getPseudo(), nouveau); this.getMe().setPseudo(nouveau); + db.majPseudo("MacYAYA",nouveau); System.out.println("Changement pseudo accepte, nouvelle liste des utilisateurs actifs:"); this.getActifUsers().afficherListeUtilisateurs(); return true; @@ -150,6 +151,10 @@ public class ChatApp implements PropertyChangeListener { System.out.println("Connexion reussie"); //db.ajoutUtilisateurs(this.me.getId(),this.me.getPseudo()); db.majPseudo("MacYAYA",this.me.getPseudo()); + db.majUtilisateursActifs(true,"MACYAYA"); + //db.ajoutUtilisateurs(this.me.getId(),this.me.getPseudo()); + //db.CreationTableHistorique("MACE","MACF"); + //db.ajoutHistorique("MACE","MACF","Prout"); return true; } else @@ -183,6 +188,7 @@ public class ChatApp implements PropertyChangeListener { // Message que l'on envoie à tous les utilisateurs actifs String broadcastMessage = "Deconnexion\n" + this.getMe().toString() ; UDPEchange.EnvoiBroadcast(broadcastMessage); + db.majUtilisateursActifs(false,"MACYAYA"); try { main.stop(); @@ -257,4 +263,5 @@ public class ChatApp implements PropertyChangeListener { public Application getMain() { return main; } + public DataBase getDb(){return this.db;} } diff --git a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java index 9148834..46a9930 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java +++ b/Implementation/chatapp/src/main/java/chatapp/Model/DataBase.java @@ -80,7 +80,7 @@ public class DataBase { grand = ID1 ; } String nomTable = "Chat_" + petit + "_" + grand ; - String Requete = "CREATE TABLE IF NOT EXISTS`" + nomTable +"` (\n" + "`Destinataire` varchar(100) NOT NULL,\n" + " `Source` varchar(100) NOT NULL,\n" + " `Envoi` timestamp NOT NULL,\n" + " `Message` text NOT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ;"; + String Requete = "CREATE TABLE IF NOT EXISTS`" + nomTable +"` (\n" + "`Destinataire` varchar(100) NOT NULL,\n" + " `Source` varchar(100) NOT NULL,\n" + " `Envoi` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n" + " `Message` text NOT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ;"; System.out.println(Requete); PreparedStatement Ps = null ; //Statement est utilisé pour envoyer une requete SQL à la base de donnee @@ -180,7 +180,7 @@ public class DataBase { */ public void ajoutUtilisateurs(String ID , String Pseudo ) { // Verification que l'utilisateur n'existe pas - String existe= "SELECT Pseudo FROM Customers WHERE ID = " + ID; + String existe= "SELECT Pseudo FROM Utilisateurs WHERE ID = " + ID +","; Statement stmt = null; ResultSet rs = null ; try { diff --git a/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java b/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java index f2551c5..37c7fd6 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java @@ -11,6 +11,7 @@ import java.net.Socket; import java.util.ArrayList; import chatapp.Controller.ChatApp; +import chatapp.Model.DataBase; import chatapp.Model.MessageHorodate; import chatapp.Model.Utilisateur; import chatapp.View.FenetreSession; @@ -23,6 +24,7 @@ public class SessionClavardage extends Thread { private ObjectOutputStream out; private ObjectInputStream in; private PropertyChangeSupport pcs; + private DataBase db; 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) { @@ -37,6 +39,7 @@ public class SessionClavardage extends Thread { } this.derniersMsg = new ArrayList(); this.SessionID = 2; + this.db=DataBase.getInstance(); Platform.runLater( () -> new FenetreSession(this) @@ -59,6 +62,7 @@ public class SessionClavardage extends Thread { } this.derniersMsg = new ArrayList(); this.pcs = new PropertyChangeSupport(this); + //db.CreationTableHistorique("Doudou","Marvel"); this.start(); Platform.runLater( () -> new FenetreSession(this) @@ -90,6 +94,7 @@ public class SessionClavardage extends Thread { MessageHorodate msgh = new MessageHorodate(getU2(),getApp().getMe(),msg,1); try { getOut().writeObject(msgh.toString()); + app.getDb().ajoutHistorique(app.getMe().getId(), u2.getId(),msg); } catch (IOException e) { e.printStackTrace(); } @@ -106,6 +111,7 @@ public class SessionClavardage extends Thread { String plaintext = null; MessageHorodate msg = null; System.out.println("Session demarre"); + app.getDb().CreationTableHistorique(app.getMe().getId(), u2.getId()); while(true) { try { plaintext = (String) getIn().readObject(); From 5d3daf66aa42eb8d2923b8c90a16c3c185d4d805 Mon Sep 17 00:00:00 2001 From: moukhlis Date: Sun, 27 Dec 2020 22:33:36 +0100 Subject: [PATCH 08/17] Implementation de la bdd --- .../tmp/compileJava/source-classes-mapping.txt | 8 ++++---- .../main/java/chatapp/Controller/ChatApp.java | 9 ++++++++- .../chatapp/src/main/java/chatapp/Main.java | 17 +++++++++++++++-- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt index af49828..f3acad7 100644 --- a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt +++ b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt @@ -1,13 +1,13 @@ -chatapp/Launcher.java - chatapp.Launcher +chatapp/Model/DataBase.java + chatapp.Model.DataBase chatapp/Model/ListUtilisateurs.java chatapp.Model.ListUtilisateurs chatapp/Model/Utilisateur.java chatapp.Model.Utilisateur chatapp/Model/MessageHorodate.java chatapp.Model.MessageHorodate -chatapp/Model/DataBase.java - chatapp.Model.DataBase +chatapp/Launcher.java + chatapp.Launcher chatapp/Protocol/RunnerEcouteTCP.java chatapp.Protocol.RunnerEcouteTCP chatapp/View/FenetreSession.java diff --git a/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java index 0814c4a..db689fb 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java +++ b/Implementation/chatapp/src/main/java/chatapp/Controller/ChatApp.java @@ -31,8 +31,13 @@ public class ChatApp implements PropertyChangeListener { private static ChatApp chatapp = null; private RunnerEcouteTCP runnerEcouteTCP; private RunnerEcouteUDP runnerEcouteUDP; + private boolean connecte; private DataBase db; + public boolean isConnecte() { + return connecte; + } + /** * Constructeur de l'application de chat * @@ -49,6 +54,7 @@ public class ChatApp implements PropertyChangeListener { this.main = main; this.db= DataBase.getInstance(); + this.connecte=false; } public static synchronized ChatApp getInstance(String pseudo, Integer port, Application main){ @@ -149,6 +155,7 @@ public class ChatApp implements PropertyChangeListener { } if (UDPEchange.getConnecte()) { System.out.println("Connexion reussie"); + this.connecte=true; //db.ajoutUtilisateurs(this.me.getId(),this.me.getPseudo()); db.majPseudo("MacYAYA",this.me.getPseudo()); db.majUtilisateursActifs(true,"MACYAYA"); @@ -189,7 +196,7 @@ public class ChatApp implements PropertyChangeListener { String broadcastMessage = "Deconnexion\n" + this.getMe().toString() ; UDPEchange.EnvoiBroadcast(broadcastMessage); db.majUtilisateursActifs(false,"MACYAYA"); - + this.connecte=false; try { main.stop(); } catch (Exception e) { diff --git a/Implementation/chatapp/src/main/java/chatapp/Main.java b/Implementation/chatapp/src/main/java/chatapp/Main.java index f745c9c..1570063 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Main.java +++ b/Implementation/chatapp/src/main/java/chatapp/Main.java @@ -2,16 +2,17 @@ package chatapp; import chatapp.Controller.ChatApp; import javafx.application.Application; +import javafx.application.Platform; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.stage.Stage; public class Main extends Application { - + ChatApp chatapp; @Override public void start(Stage primaryStage) throws Exception { - ChatApp chatapp = ChatApp.getInstance("Null",1234,this); + this.chatapp = ChatApp.getInstance("Null",1234,this); FXMLLoader fichier = new FXMLLoader(getClass().getResource("/fenetres/ConnexionScreen.fxml")); Scene scene1 = new Scene(fichier.load(),600,400); primaryStage.setScene(scene1); @@ -25,6 +26,18 @@ public class Main extends Application { } + @Override + public void stop() throws Exception { + if(chatapp.isConnecte()){ + chatapp.deconnexion(); + } + else { + super.stop(); + Platform.exit(); + System.exit(0); + } + } + public static void main(String[] args) { launch(args); } From 338e52671e96c585176fb30703edea512c751f0b Mon Sep 17 00:00:00 2001 From: Nabzzz Date: Mon, 28 Dec 2020 00:00:49 +0100 Subject: [PATCH 09/17] Nouvelle interface graphique --- Implementation/chatapp/build.gradle | 1 + .../compileJava/source-classes-mapping.txt | 8 ++--- .../chatapp/src/main/java/chatapp/Main.java | 2 ++ .../chatapp/Protocol/SessionClavardage.java | 2 +- .../java/chatapp/View/ChangementPseudo.java | 2 ++ .../main/java/chatapp/View/Clavardage.java | 30 +++++++++---------- .../resources/fenetres/View_Clavardage.fxml | 22 +++++++------- 7 files changed, 34 insertions(+), 33 deletions(-) diff --git a/Implementation/chatapp/build.gradle b/Implementation/chatapp/build.gradle index c76d1ef..040b2e0 100644 --- a/Implementation/chatapp/build.gradle +++ b/Implementation/chatapp/build.gradle @@ -22,6 +22,7 @@ javafx { dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' + compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.22' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.22' runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:win" diff --git a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt index f3acad7..6bf5cd7 100644 --- a/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt +++ b/Implementation/chatapp/build/tmp/compileJava/source-classes-mapping.txt @@ -15,8 +15,8 @@ chatapp/View/FenetreSession.java chatapp.View.FenetreSession$1 chatapp/Controller/ChatApp.java chatapp.Controller.ChatApp -chatapp/View/ChangementPseudo.java - chatapp.View.ChangementPseudo +chatapp/View/DemarrerSession.java + chatapp.View.DemarrerSession chatapp/Protocol/RunnerEcouteUDP.java chatapp.Protocol.RunnerEcouteUDP chatapp/Protocol/UDPEchange.java @@ -35,5 +35,5 @@ 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 +chatapp/View/ChangementPseudo.java + chatapp.View.ChangementPseudo diff --git a/Implementation/chatapp/src/main/java/chatapp/Main.java b/Implementation/chatapp/src/main/java/chatapp/Main.java index 1570063..40933b0 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Main.java +++ b/Implementation/chatapp/src/main/java/chatapp/Main.java @@ -7,6 +7,8 @@ import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.stage.Stage; +import java.io.IOException; + public class Main extends Application { ChatApp chatapp; diff --git a/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java b/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java index 37c7fd6..fc655cc 100644 --- a/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java +++ b/Implementation/chatapp/src/main/java/chatapp/Protocol/SessionClavardage.java @@ -62,7 +62,7 @@ public class SessionClavardage extends Thread { } this.derniersMsg = new ArrayList(); this.pcs = new PropertyChangeSupport(this); - //db.CreationTableHistorique("Doudou","Marvel"); + db.CreationTableHistorique("Doudou","Marvel"); this.start(); Platform.runLater( () -> new FenetreSession(this) diff --git a/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java b/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java index a2f8d27..41ab660 100644 --- a/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java +++ b/Implementation/chatapp/src/main/java/chatapp/View/ChangementPseudo.java @@ -45,6 +45,7 @@ public class ChangementPseudo { @FXML void retourMenu(ActionEvent event) { + System.out.println("Retour au menu principal"); Stage stage = (Stage) MenuButton.getScene().getWindow(); Parent root = null; try { @@ -83,5 +84,6 @@ public class ChangementPseudo { chatApp = ChatApp.getInstance(); pseudonyme1.setText(chatApp.getMe().getPseudo()); this.validationButton.setDefaultButton(true); + //System.out.println(this.validationButton.isDefaultButton()); } } \ No newline at end of file diff --git a/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java b/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java index 1992220..9facb7f 100644 --- a/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java +++ b/Implementation/chatapp/src/main/java/chatapp/View/Clavardage.java @@ -22,6 +22,7 @@ import javafx.stage.Stage; public class Clavardage implements Initializable, PropertyChangeListener { + public Button plusButton; @FXML // ResourceBundle that was given to the FXMLLoader private ResourceBundle resources; @@ -41,38 +42,32 @@ public class Clavardage implements Initializable, PropertyChangeListener { 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); + if(!msg.equals("")) { + 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()); } @@ -107,4 +102,7 @@ public class Clavardage implements Initializable, PropertyChangeListener { EnvoyerButton.setDefaultButton(true); this.ChatText.setEditable(false); } + + public void ajouterMessagesHistorique(ActionEvent actionEvent) { + } } \ No newline at end of file diff --git a/Implementation/chatapp/src/main/resources/fenetres/View_Clavardage.fxml b/Implementation/chatapp/src/main/resources/fenetres/View_Clavardage.fxml index 9e8975e..ebb0e85 100644 --- a/Implementation/chatapp/src/main/resources/fenetres/View_Clavardage.fxml +++ b/Implementation/chatapp/src/main/resources/fenetres/View_Clavardage.fxml @@ -51,25 +51,31 @@