Browse Source

Added gradle project

EyeXion 9 months ago
commit
cb34f82d45
33 changed files with 1129 additions and 0 deletions
  1. 25
    0
      README.md
  2. 23
    0
      build.gradle
  3. BIN
      build/classes/java/main/Main.class
  4. BIN
      build/classes/java/main/app/insa/clav/Core/Controller.class
  5. BIN
      build/classes/java/main/app/insa/clav/Core/Model.class
  6. BIN
      build/classes/java/main/app/insa/clav/Core/Test.class
  7. BIN
      build/classes/java/main/app/insa/clav/Core/Utilisateurs.class
  8. BIN
      build/classes/java/main/app/insa/clav/Main.class
  9. BIN
      build/classes/java/main/app/insa/clav/Messages/Message.class
  10. BIN
      build/classes/java/main/app/insa/clav/Messages/MessagePseudo.class
  11. BIN
      build/classes/java/main/app/insa/clav/UI/UserInterface.class
  12. BIN
      build/classes/java/main/app/insa/clav/Utils/TimerTaskResponseWait.class
  13. BIN
      build/classes/java/main/app/insa/clav/reseau/UDPInput.class
  14. BIN
      build/classes/java/main/app/insa/clav/reseau/UDPOutput.class
  15. BIN
      build/classes/java/main/sample/Main.class
  16. 8
    0
      build/resources/main/fxml/sample.fxml
  17. BIN
      gradle/wrapper/gradle-wrapper.jar
  18. 5
    0
      gradle/wrapper/gradle-wrapper.properties
  19. 185
    0
      gradlew
  20. 104
    0
      gradlew.bat
  21. 2
    0
      settings.gradle
  22. 50
    0
      src/main/java/app/insa/clav/Core/Controller.java
  23. 209
    0
      src/main/java/app/insa/clav/Core/Model.java
  24. 24
    0
      src/main/java/app/insa/clav/Core/Test.java
  25. 68
    0
      src/main/java/app/insa/clav/Core/Utilisateurs.java
  26. 25
    0
      src/main/java/app/insa/clav/Main.java
  27. 68
    0
      src/main/java/app/insa/clav/Messages/Message.java
  28. 63
    0
      src/main/java/app/insa/clav/Messages/MessagePseudo.java
  29. 31
    0
      src/main/java/app/insa/clav/UI/UserInterface.java
  30. 29
    0
      src/main/java/app/insa/clav/Utils/TimerTaskResponseWait.java
  31. 131
    0
      src/main/java/app/insa/clav/reseau/UDPInput.java
  32. 71
    0
      src/main/java/app/insa/clav/reseau/UDPOutput.java
  33. 8
    0
      src/main/resources/fxml/sample.fxml

+ 25
- 0
README.md View File

@@ -0,0 +1,25 @@
1
+#Projet Clavardage TALI Elies et FAURE Paul
2
+
3
+##Conception 
4
+
5
+Faite sur Modelio, il suffit d'importer le fichier zip contenu dans Conception/ dans Modelio.
6
+Notre conception est pour le moment pas très bonne car nous avions mal compris le CDC. Nous allons donc la changer au fur et à mesure des TP
7
+
8
+##Notes pour nous même
9
+
10
+###Fait (plus ou moins)
11
+
12
+- Classe Messages.Message (dont les message spécifiques vont hériter) ok.
13
+- Classe Messages.MessagePseudo de type 1 (demande validation)
14
+- Classes reseau.UDPInput et reseau.UDPOutput ok
15
+- Tests avec 3 machines sur localhost avec 3 ports différents ok
16
+- Quand on reçoit un msgPseudo, on répond avec un messagePseudo d'un autre type (type 2 ou 3)
17
+- Quand on recoit un Messages.MessagePseudo de n'importe quel type, on met à jour sa table des utilisateurs connectés si le pseudo n'est pas utilisé
18
+- Si pseudo déjà utilisé, on envoie un messagePseudo (type 3)
19
+- MVC ok (avec controlleur et vue qui sont simulés et qui sont pas hyper utiles bvu qu'on a pas de vue réelle)
20
+
21
+###A faire
22
+
23
+- Quand on reçoit un messagPseudo de type 1, on vérifie toute la table des utilisateurs connectés.
24
+- Envoyer à intervalle régulier des messages qui disent qu'on est bien connecté
25
+- Commencer une petite interface graphique pour demander un pseudo et afficher les utilisateurs connectés

+ 23
- 0
build.gradle View File

@@ -0,0 +1,23 @@
1
+plugins {
2
+    id 'java'
3
+    id 'application'
4
+    id 'org.openjfx.javafxplugin' version '0.0.9'}
5
+
6
+group 'app.insa.clav'
7
+version '1.0'
8
+
9
+repositories {
10
+    mavenCentral()
11
+}
12
+
13
+javafx {
14
+    version = "11.0.2"
15
+    modules = [ 'javafx.controls', 'javafx.fxml' ]
16
+}
17
+
18
+
19
+dependencies {
20
+    testCompile group: 'junit', name: 'junit', version: '4.12'
21
+}
22
+
23
+mainClassName = 'app.insa.clav.Main'

BIN
build/classes/java/main/Main.class View File


BIN
build/classes/java/main/app/insa/clav/Core/Controller.class View File


BIN
build/classes/java/main/app/insa/clav/Core/Model.class View File


BIN
build/classes/java/main/app/insa/clav/Core/Test.class View File


BIN
build/classes/java/main/app/insa/clav/Core/Utilisateurs.class View File


BIN
build/classes/java/main/app/insa/clav/Main.class View File


BIN
build/classes/java/main/app/insa/clav/Messages/Message.class View File


BIN
build/classes/java/main/app/insa/clav/Messages/MessagePseudo.class View File


BIN
build/classes/java/main/app/insa/clav/UI/UserInterface.class View File


BIN
build/classes/java/main/app/insa/clav/Utils/TimerTaskResponseWait.class View File


BIN
build/classes/java/main/app/insa/clav/reseau/UDPInput.class View File


BIN
build/classes/java/main/app/insa/clav/reseau/UDPOutput.class View File


BIN
build/classes/java/main/sample/Main.class View File


+ 8
- 0
build/resources/main/fxml/sample.fxml View File

@@ -0,0 +1,8 @@
1
+<?import javafx.geometry.Insets?>
2
+<?import javafx.scene.layout.GridPane?>
3
+
4
+<?import javafx.scene.control.Button?>
5
+<?import javafx.scene.control.Label?>
6
+<GridPane
7
+        xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
8
+</GridPane>

BIN
gradle/wrapper/gradle-wrapper.jar View File


+ 5
- 0
gradle/wrapper/gradle-wrapper.properties View File

@@ -0,0 +1,5 @@
1
+distributionBase=GRADLE_USER_HOME
2
+distributionPath=wrapper/dists
3
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip
4
+zipStoreBase=GRADLE_USER_HOME
5
+zipStorePath=wrapper/dists

+ 185
- 0
gradlew View File

@@ -0,0 +1,185 @@
1
+#!/usr/bin/env sh
2
+
3
+#
4
+# Copyright 2015 the original author or authors.
5
+#
6
+# Licensed under the Apache License, Version 2.0 (the "License");
7
+# you may not use this file except in compliance with the License.
8
+# You may obtain a copy of the License at
9
+#
10
+#      https://www.apache.org/licenses/LICENSE-2.0
11
+#
12
+# Unless required by applicable law or agreed to in writing, software
13
+# distributed under the License is distributed on an "AS IS" BASIS,
14
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+# See the License for the specific language governing permissions and
16
+# limitations under the License.
17
+#
18
+
19
+##############################################################################
20
+##
21
+##  Gradle start up script for UN*X
22
+##
23
+##############################################################################
24
+
25
+# Attempt to set APP_HOME
26
+# Resolve links: $0 may be a link
27
+PRG="$0"
28
+# Need this for relative symlinks.
29
+while [ -h "$PRG" ] ; do
30
+    ls=`ls -ld "$PRG"`
31
+    link=`expr "$ls" : '.*-> \(.*\)$'`
32
+    if expr "$link" : '/.*' > /dev/null; then
33
+        PRG="$link"
34
+    else
35
+        PRG=`dirname "$PRG"`"/$link"
36
+    fi
37
+done
38
+SAVED="`pwd`"
39
+cd "`dirname \"$PRG\"`/" >/dev/null
40
+APP_HOME="`pwd -P`"
41
+cd "$SAVED" >/dev/null
42
+
43
+APP_NAME="Gradle"
44
+APP_BASE_NAME=`basename "$0"`
45
+
46
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48
+
49
+# Use the maximum available, or set MAX_FD != -1 to use that value.
50
+MAX_FD="maximum"
51
+
52
+warn () {
53
+    echo "$*"
54
+}
55
+
56
+die () {
57
+    echo
58
+    echo "$*"
59
+    echo
60
+    exit 1
61
+}
62
+
63
+# OS specific support (must be 'true' or 'false').
64
+cygwin=false
65
+msys=false
66
+darwin=false
67
+nonstop=false
68
+case "`uname`" in
69
+  CYGWIN* )
70
+    cygwin=true
71
+    ;;
72
+  Darwin* )
73
+    darwin=true
74
+    ;;
75
+  MINGW* )
76
+    msys=true
77
+    ;;
78
+  NONSTOP* )
79
+    nonstop=true
80
+    ;;
81
+esac
82
+
83
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84
+
85
+
86
+# Determine the Java command to use to start the JVM.
87
+if [ -n "$JAVA_HOME" ] ; then
88
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89
+        # IBM's JDK on AIX uses strange locations for the executables
90
+        JAVACMD="$JAVA_HOME/jre/sh/java"
91
+    else
92
+        JAVACMD="$JAVA_HOME/bin/java"
93
+    fi
94
+    if [ ! -x "$JAVACMD" ] ; then
95
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96
+
97
+Please set the JAVA_HOME variable in your environment to match the
98
+location of your Java installation."
99
+    fi
100
+else
101
+    JAVACMD="java"
102
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103
+
104
+Please set the JAVA_HOME variable in your environment to match the
105
+location of your Java installation."
106
+fi
107
+
108
+# Increase the maximum file descriptors if we can.
109
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110
+    MAX_FD_LIMIT=`ulimit -H -n`
111
+    if [ $? -eq 0 ] ; then
112
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113
+            MAX_FD="$MAX_FD_LIMIT"
114
+        fi
115
+        ulimit -n $MAX_FD
116
+        if [ $? -ne 0 ] ; then
117
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
118
+        fi
119
+    else
120
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121
+    fi
122
+fi
123
+
124
+# For Darwin, add options to specify how the application appears in the dock
125
+if $darwin; then
126
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127
+fi
128
+
129
+# For Cygwin or MSYS, switch paths to Windows format before running java
130
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133
+    
134
+    JAVACMD=`cygpath --unix "$JAVACMD"`
135
+
136
+    # We build the pattern for arguments to be converted via cygpath
137
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138
+    SEP=""
139
+    for dir in $ROOTDIRSRAW ; do
140
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
141
+        SEP="|"
142
+    done
143
+    OURCYGPATTERN="(^($ROOTDIRS))"
144
+    # Add a user-defined pattern to the cygpath arguments
145
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147
+    fi
148
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
149
+    i=0
150
+    for arg in "$@" ; do
151
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
153
+
154
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
155
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156
+        else
157
+            eval `echo args$i`="\"$arg\""
158
+        fi
159
+        i=`expr $i + 1`
160
+    done
161
+    case $i in
162
+        0) set -- ;;
163
+        1) set -- "$args0" ;;
164
+        2) set -- "$args0" "$args1" ;;
165
+        3) set -- "$args0" "$args1" "$args2" ;;
166
+        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167
+        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168
+        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169
+        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170
+        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171
+        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172
+    esac
173
+fi
174
+
175
+# Escape application args
176
+save () {
177
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178
+    echo " "
179
+}
180
+APP_ARGS=`save "$@"`
181
+
182
+# Collect all arguments for the java command, following the shell quoting and substitution rules
183
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184
+
185
+exec "$JAVACMD" "$@"

+ 104
- 0
gradlew.bat View File

@@ -0,0 +1,104 @@
1
+@rem
2
+@rem Copyright 2015 the original author or authors.
3
+@rem
4
+@rem Licensed under the Apache License, Version 2.0 (the "License");
5
+@rem you may not use this file except in compliance with the License.
6
+@rem You may obtain a copy of the License at
7
+@rem
8
+@rem      https://www.apache.org/licenses/LICENSE-2.0
9
+@rem
10
+@rem Unless required by applicable law or agreed to in writing, software
11
+@rem distributed under the License is distributed on an "AS IS" BASIS,
12
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+@rem See the License for the specific language governing permissions and
14
+@rem limitations under the License.
15
+@rem
16
+
17
+@if "%DEBUG%" == "" @echo off
18
+@rem ##########################################################################
19
+@rem
20
+@rem  Gradle startup script for Windows
21
+@rem
22
+@rem ##########################################################################
23
+
24
+@rem Set local scope for the variables with windows NT shell
25
+if "%OS%"=="Windows_NT" setlocal
26
+
27
+set DIRNAME=%~dp0
28
+if "%DIRNAME%" == "" set DIRNAME=.
29
+set APP_BASE_NAME=%~n0
30
+set APP_HOME=%DIRNAME%
31
+
32
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
33
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34
+
35
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37
+
38
+@rem Find java.exe
39
+if defined JAVA_HOME goto findJavaFromJavaHome
40
+
41
+set JAVA_EXE=java.exe
42
+%JAVA_EXE% -version >NUL 2>&1
43
+if "%ERRORLEVEL%" == "0" goto init
44
+
45
+echo.
46
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47
+echo.
48
+echo Please set the JAVA_HOME variable in your environment to match the
49
+echo location of your Java installation.
50
+
51
+goto fail
52
+
53
+:findJavaFromJavaHome
54
+set JAVA_HOME=%JAVA_HOME:"=%
55
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56
+
57
+if exist "%JAVA_EXE%" goto init
58
+
59
+echo.
60
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61
+echo.
62
+echo Please set the JAVA_HOME variable in your environment to match the
63
+echo location of your Java installation.
64
+
65
+goto fail
66
+
67
+:init
68
+@rem Get command-line arguments, handling Windows variants
69
+
70
+if not "%OS%" == "Windows_NT" goto win9xME_args
71
+
72
+:win9xME_args
73
+@rem Slurp the command line arguments.
74
+set CMD_LINE_ARGS=
75
+set _SKIP=2
76
+
77
+:win9xME_args_slurp
78
+if "x%~1" == "x" goto execute
79
+
80
+set CMD_LINE_ARGS=%*
81
+
82
+:execute
83
+@rem Setup the command line
84
+
85
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
86
+
87
+
88
+@rem Execute Gradle
89
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
90
+
91
+:end
92
+@rem End local scope for the variables with windows NT shell
93
+if "%ERRORLEVEL%"=="0" goto mainEnd
94
+
95
+:fail
96
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
97
+rem the _cmd.exe /c_ return code!
98
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
99
+exit /b 1
100
+
101
+:mainEnd
102
+if "%OS%"=="Windows_NT" endlocal
103
+
104
+:omega

+ 2
- 0
settings.gradle View File

@@ -0,0 +1,2 @@
1
+rootProject.name = 'Clavardage'
2
+

+ 50
- 0
src/main/java/app/insa/clav/Core/Controller.java View File

@@ -0,0 +1,50 @@
1
+package app.insa.clav.Core;
2
+
3
+import app.insa.clav.UI.UserInterface;
4
+
5
+/**
6
+ * Controleur du modèle MVC. Interface entre le modèle (Application) et l'UI.
7
+ * Un controleur pour chaque fenêtre (main window ou fenetre de clavardage)
8
+ */
9
+public class Controller {
10
+
11
+    /**
12
+     * Application. UNE SEULE INSTANCE DANS TOUT LE PROGRAMME (faire un singleton ?)
13
+     */
14
+    private Model model;
15
+    /**
16
+     * Fenetre liée à ce controleur
17
+     */
18
+    private UserInterface ui;
19
+
20
+    /**
21
+     * Contructeur. Il crée lui même l'UI (plus tard on mettra quel type de fenetre en argument)
22
+     * @param model
23
+     *             Reference vers l'application (le modèle)
24
+     */
25
+    public Controller(Model model){
26
+        this.model = model;
27
+        this.ui = new UserInterface();
28
+    }
29
+
30
+
31
+    public Controller(){}
32
+
33
+    /**
34
+     * Méthode appellée par le vue (appui boutton) pour enclencher le changement de pseudo
35
+     * @param pseudo
36
+     *              Pseudo rentré par l'utilisateur
37
+     */
38
+    public void choosePseudo(String pseudo){
39
+       model.choosePseudo(pseudo);
40
+    }
41
+
42
+    /**
43
+     * Sert pour les tests et simuler l'UI
44
+     * @param payload
45
+     */
46
+    public void printMessageReceived(String payload){
47
+        this.ui.printMessagePseudo(payload);
48
+    }
49
+
50
+}

+ 209
- 0
src/main/java/app/insa/clav/Core/Model.java View File

@@ -0,0 +1,209 @@
1
+package app.insa.clav.Core;
2
+
3
+import app.insa.clav.Messages.Message;
4
+import app.insa.clav.Messages.MessagePseudo;
5
+import app.insa.clav.Utils.TimerTaskResponseWait;
6
+import app.insa.clav.reseau.UDPInput;
7
+import app.insa.clav.reseau.UDPOutput;
8
+
9
+import java.beans.PropertyChangeEvent;
10
+import java.beans.PropertyChangeListener;
11
+import java.beans.PropertyChangeSupport;
12
+import java.io.IOException;
13
+import java.util.ArrayList;
14
+import java.net.*;
15
+import java.util.Timer;
16
+//Toutes les interactions avec l'utilisateur (pour tester)
17
+
18
+/**
19
+ * Notre application principale. Une seule instance. représente le modèle du MVC
20
+ */
21
+public class Model implements PropertyChangeListener{
22
+
23
+    /**
24
+     * Liste des utilisateurs connectés.
25
+     */
26
+    private ArrayList<Utilisateurs> userList;
27
+    /**
28
+     * Timer qui permet de planifier des éxécutions dans le temps
29
+     */
30
+    private Timer tim;
31
+
32
+    /**
33
+     * Notre interface UDP pour envoyer des messages
34
+     */
35
+    private UDPOutput UDPOut;
36
+    /**
37
+     * Interface UDP qui notifie quand un message est envoyé (observable)
38
+     */
39
+    private UDPInput UDPIn;
40
+    /**
41
+     * Infos sur notre utilisateur local
42
+     */
43
+    private Utilisateurs user;
44
+    /**
45
+     * Sert à stocker le pseudo de base quand on veut change de pseudo. Si la demande de pseudo est refusée, on revient à ce pseudo
46
+     */
47
+    private String ancienPseudo = "";
48
+
49
+    /**
50
+     * Observable, pour envoyer des notifications aux controleurs
51
+     */
52
+    private PropertyChangeSupport support;
53
+
54
+    /**
55
+     * Constructeur
56
+     * @param id
57
+     *           Id de l'utilisateur (unique dans toutes les machines)
58
+     * @param inputPort
59
+     *                  Port d'input UDP
60
+     * @param outputPort
61
+     *                  Port d'Output UDP
62
+     */
63
+/*
64
+ID 1 -> Listening on 6000, sending on 5000
65
+ID 2 -> Listening on 6001, sending on 5001
66
+ID 2 -> Listening on 6002, sending on 5002
67
+*/
68
+    public Model(int id, int inputPort, int outputPort){
69
+        try {
70
+            this.user = new Utilisateurs("NA", InetAddress.getLocalHost(), id, inputPort);
71
+            this.UDPOut = new UDPOutput(InetAddress.getLocalHost(), outputPort);
72
+            this.UDPIn = new UDPInput(user.getInetAddress(),inputPort);
73
+            this.tim= new Timer();
74
+            this.support = new PropertyChangeSupport(this);
75
+        }
76
+        catch (IOException e){
77
+            System.out.println("IOException dans la creation de l'utilisateur local");
78
+            e.printStackTrace();
79
+        }
80
+        this.userList = new ArrayList<Utilisateurs>();
81
+    }
82
+
83
+    /**
84
+     * Ouvre le thread d'écoute en UDP et ajoute l'application en observateur de ce thread
85
+     */
86
+    public void openInputUDP(){
87
+        UDPIn.start();
88
+        this.UDPIn.addPropertyChangeListener(this);
89
+    }
90
+
91
+    /**
92
+     * Ajout un listener avec un nom de propriété.
93
+     *
94
+     * Liste des propriete :
95
+     *
96
+     *  "pseudoRefused" -> Demande de nouveau pseudo refusée
97
+     *  "userListUpdated" -> La liste des utilisateurs connectés à changé
98
+     *  "pseudoAccepted" -> nouveau pseudo accepte
99
+     *
100
+     *
101
+     * @param pcl
102
+     *             Listener du controller qui a appelé la methode
103
+     * @param propertyName
104
+     */
105
+    public void addPropertyChangeListener(PropertyChangeListener pcl, String propertyName){
106
+        this.support.addPropertyChangeListener(propertyName, pcl);
107
+    }
108
+
109
+    /**
110
+     * Envoi un messagePseudo de type 1 aux 3 machines de test
111
+     */
112
+    public void sendPseudoBroadcast(){
113
+        try {
114
+            if (user.getId() == 1 || user.getId() == 2) {
115
+                MessagePseudo msg = new MessagePseudo(1, this.user.getInetAddress(), this.user.getPort(), InetAddress.getLocalHost(), 6002, this.user.getPseudo(),this.user.getId());
116
+                UDPOut.sendMsg(msg);
117
+            }
118
+            if (user.getId() == 2 || user.getId() == 3) {
119
+                MessagePseudo msg = new MessagePseudo(1, this.user.getInetAddress(), this.user.getPort(),  InetAddress.getLocalHost(), 6000, this.user.getPseudo(),this.user.getId());
120
+                UDPOut.sendMsg(msg);
121
+            }
122
+            if (user.getId() == 1 || user.getId() == 3) {
123
+                MessagePseudo msg = new MessagePseudo(1, this.user.getInetAddress(), this.user.getPort(),  InetAddress.getLocalHost(), 6001,this.user.getPseudo(),this.user.getId());
124
+                UDPOut.sendMsg(msg);
125
+            }
126
+        }
127
+        catch (UnknownHostException e){
128
+            System.out.println(("exception Trouver host dans sendPseudoBroadcast"));
129
+            e.printStackTrace();
130
+        }
131
+    }
132
+
133
+    /**
134
+     * Méthode appelée par le controleur quand la vue envoie un signal d'appuis bouton changer Pseudo
135
+     * @param pseudo
136
+     *              Pseudo rentré par l'utilisateur
137
+     * @return
138
+     */
139
+    public boolean choosePseudo(String pseudo){
140
+        this.ancienPseudo = this.user.getPseudo();
141
+        this.user.setPseudo(pseudo);
142
+        this.UDPIn.setFilterValue(2,true);
143
+        this.UDPIn.setFilterValue(3,true);
144
+        this.sendPseudoBroadcast();
145
+        this.tim.schedule(new TimerTaskResponseWait(this.UDPIn),1000);
146
+        return true;
147
+    }
148
+
149
+    /**
150
+     * Handler de notification (Obsevateur) pour le thread UDP.
151
+     * @param evt
152
+     *             Evenement qui est envoyé avec la notification
153
+     */
154
+    public void propertyChange(PropertyChangeEvent evt){
155
+        switch (evt.getPropertyName()){
156
+            case "UDPInput":
157
+                Message msgReceived = UDPIn.getMessageReceived();
158
+                this.messageHandler(msgReceived);
159
+        }
160
+    }
161
+
162
+    /**
163
+     * Permet de faire les actions adéquates selon le type de message reçu. Appelé dans propertyChange
164
+     * @param msg
165
+     *          message à analyser
166
+     */
167
+    public void messageHandler(Message msg){
168
+        switch (msg.typeMessage){
169
+            case 1 :
170
+                MessagePseudo msgP1 = (MessagePseudo) msg;
171
+                this.handleType1Message(msgP1);
172
+                break;
173
+            case 2 :
174
+                MessagePseudo msgP2 = (MessagePseudo) msg;
175
+                Utilisateurs newUser2 = new Utilisateurs(msgP2.pseudo,msgP2.srcIP,msgP2.id,msgP2.srcResponsePort);
176
+                if (!this.userList.contains(newUser2)) {
177
+                    this.userList.add(newUser2);
178
+                }
179
+                break;
180
+            case 3 :
181
+                MessagePseudo msgP3 = (MessagePseudo) msg;
182
+                Utilisateurs newUser3 = new Utilisateurs(msgP3.pseudo,msgP3.srcIP,msgP3.id,msgP3.srcResponsePort);
183
+                if (!this.userList.contains(newUser3)) {
184
+                    this.userList.add(newUser3);
185
+                }
186
+                this.support.firePropertyChange("pseudoRefused",this.user.getPseudo(),this.ancienPseudo);
187
+                this.user.setPseudo(this.ancienPseudo);
188
+                break;
189
+            default :
190
+                System.out.println("Message de type inconnu");
191
+        }
192
+    }
193
+
194
+    /**
195
+     * Méthode appelée dans messageHandler pour répondre à un message de type 1
196
+     * @param msg
197
+     *          Message à analyser
198
+     */
199
+    private void handleType1Message(MessagePseudo msg){
200
+        MessagePseudo msgResponse;
201
+        if (this.user.getPseudo().equals(msg.pseudo)){
202
+            msgResponse = new MessagePseudo(3, this.user.getInetAddress(), this.user.getPort(),  msg.srcIP, msg.srcResponsePort,this.user.getPseudo(),this.user.getId());
203
+        }
204
+        else{
205
+            msgResponse = new MessagePseudo(2, this.user.getInetAddress(), this.user.getPort(),  msg.srcIP, msg.srcResponsePort,this.user.getPseudo(),this.user.getId());
206
+        }
207
+        this.UDPOut.sendMsg(msgResponse);
208
+    }
209
+}

+ 24
- 0
src/main/java/app/insa/clav/Core/Test.java View File

@@ -0,0 +1,24 @@
1
+package app.insa.clav.Core;//main pour les tests
2
+
3
+import java.util.Scanner;
4
+
5
+public class Test {
6
+
7
+    public static void main(String[] arg){
8
+        //String ipAdress = arg[0];
9
+        int id = Integer.parseInt(arg[0]);
10
+        int inputPort = Integer.parseInt(arg[1]);
11
+        int outPutPort = Integer.parseInt(arg[2]);
12
+
13
+        Model model = new Model(id,inputPort, outPutPort);
14
+        model.openInputUDP();
15
+        Controller mainCtrl = new Controller(model);
16
+
17
+        while (true){
18
+            Scanner myScan = new Scanner(System.in);
19
+            System.out.println("Entrez un pseudo svp : ");
20
+            String pseudo = myScan.nextLine();
21
+            //model.ctrl.choosePseudo(pseudo);
22
+        }
23
+    }
24
+}

+ 68
- 0
src/main/java/app/insa/clav/Core/Utilisateurs.java View File

@@ -0,0 +1,68 @@
1
+package app.insa.clav.Core;
2
+
3
+import java.util.Date;
4
+import java.net.*;
5
+
6
+
7
+//Classe qui permet d'identifier un utilisateur
8
+
9
+public class Utilisateurs {
10
+    private String pseudo;
11
+    private InetAddress inetAddress;
12
+    private int id;
13
+    private int port;
14
+
15
+    public Date getLatestUpdate() {
16
+        return latestUpdate;
17
+    }
18
+
19
+    public void setLatestUpdate(Date latestUpdate) {
20
+        this.latestUpdate = latestUpdate;
21
+    }
22
+
23
+    private Date latestUpdate;
24
+
25
+    public Utilisateurs(String pseudo, InetAddress inetAddress, int id, int port) {
26
+        this.pseudo = pseudo;
27
+        this.inetAddress = inetAddress;
28
+        this.id = id;
29
+        this.port = port;
30
+    }
31
+
32
+    public void setPseudo(String pseudo) {
33
+        this.pseudo = pseudo;
34
+    }
35
+
36
+    public void setInetAddress(InetAddress inetAddress) {
37
+        this.inetAddress = inetAddress;
38
+    }
39
+
40
+    public void setId(int id) {
41
+        this.id = id;
42
+    }
43
+
44
+    public void setPort(int port) {
45
+        this.port = port;
46
+    }
47
+
48
+    public String getPseudo() {
49
+        return pseudo;
50
+    }
51
+
52
+    public InetAddress getInetAddress() {
53
+        return inetAddress;
54
+    }
55
+
56
+    public int getId() {
57
+        return id;
58
+    }
59
+
60
+    public int getPort() {
61
+        return port;
62
+    }
63
+
64
+    public String toString(){
65
+        return Integer.toString(this.id) + "|" + this.pseudo + "|" + this.inetAddress.toString() + "|" + Integer.toString(this.port);
66
+    }
67
+
68
+}

+ 25
- 0
src/main/java/app/insa/clav/Main.java View File

@@ -0,0 +1,25 @@
1
+package app.insa.clav;
2
+
3
+import javafx.application.Application;
4
+import javafx.fxml.FXMLLoader;
5
+import javafx.scene.Parent;
6
+import javafx.scene.Scene;
7
+import javafx.stage.Stage;
8
+
9
+public class Main extends Application {
10
+
11
+    @Override
12
+    public void start(Stage primaryStage) throws Exception{
13
+        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/sample.fxml"));
14
+        fxmlLoader.setController(ctrl); //mettre object controlleur ici
15
+        Parent root =fxmlLoader.load();
16
+        primaryStage.setTitle("Hello World");
17
+        primaryStage.setScene(new Scene(root, 300, 275));
18
+        primaryStage.show();
19
+    }
20
+
21
+
22
+    public static void main(String[] args) {
23
+        launch(args);
24
+    }
25
+}

+ 68
- 0
src/main/java/app/insa/clav/Messages/Message.java View File

@@ -0,0 +1,68 @@
1
+package app.insa.clav.Messages;
2
+
3
+import java.io.Serializable;
4
+import java.net.InetAddress;
5
+
6
+//Classe de base de tout les messages. Les payloads seront précisés dans les classes filles
7
+
8
+/* typeMessage Number :
9
+    1 ---> Messages.MessagePseudo envoi en 1er
10
+    2 ---> Messages.MessagePseudo réponse à type 1 pseudo ok
11
+    3 ---> Messages.MessagePseudo réponse à type 1 pseudo pas ok
12
+    4 ---> Messages.MessagePseudo si après type 1 aucun type 2 pour un delai, envoi confirmation pseudo
13
+ */
14
+
15
+/**
16
+ * Message de base, classe mère dont les message plus spécifiques héritent.
17
+ */
18
+public class Message implements Serializable {
19
+
20
+    //private static final long serialVersionUID = 7526472295622776147L;
21
+
22
+    /**
23
+     * Type de message. </br>
24
+     * 1 -> Demande de validation de pseudo (MessagePseudo) </br>
25
+     * 2 -> Réponse validation pseudo ok (MessagePseudo) </br>
26
+     * 3 -> Réponse validation pseudo pas ok (MessagePseudo)
27
+     */
28
+    public int typeMessage;
29
+    public InetAddress srcIP;
30
+    public int srcResponsePort; //Seulement besoin car on teste en localHost
31
+    public InetAddress destIP;
32
+    public int destPort;
33
+
34
+    /**
35
+     * Constructeur d'un message depuis un autre
36
+     * @param msg
37
+     */
38
+    public Message(Message msg){
39
+        this.typeMessage = msg.typeMessage;
40
+        this.srcIP = msg.srcIP;
41
+        this.srcResponsePort = msg.srcResponsePort;
42
+        this.destIP = msg.destIP;
43
+        this.destPort = msg.destPort;
44
+    }
45
+
46
+    /**
47
+     * Construit un message depuis les infos en paramètre
48
+     * @param typeMessage
49
+     *                  Type du message.
50
+     *                  Voir autres messages pour précisions
51
+     *
52
+     * @param srcIP
53
+     *              IP depuis laquelle le msg à été envoyé
54
+     * @param srcResponsePort
55
+     *              Port à utiliser pour répondre à ce message
56
+     * @param destIP
57
+     *              Ip de la machine destinataire
58
+     * @param destPort
59
+     *              Port de la machine destinataire
60
+     */
61
+    public Message(int typeMessage,InetAddress srcIP, int srcResponsePort,InetAddress destIP,int destPort){
62
+        this.typeMessage = typeMessage;
63
+        this.srcIP = srcIP;
64
+        this.srcResponsePort = srcResponsePort;
65
+        this.destIP = destIP;
66
+        this.destPort = destPort;
67
+    }
68
+}

+ 63
- 0
src/main/java/app/insa/clav/Messages/MessagePseudo.java View File

@@ -0,0 +1,63 @@
1
+package app.insa.clav.Messages;
2
+
3
+import java.net.InetAddress;
4
+
5
+//Messages.Message qui permet d'envoyer un pseudo. typeMessage = 1
6
+
7
+
8
+/**
9
+ * Classe de message pour envoyer des truc concernant les Pseudo/ les utilisateurs connéctés
10
+ */
11
+public class MessagePseudo extends Message {
12
+
13
+    /**
14
+     * Pseudo soit en demande de validation (type 1) ou alors pseudo effectif de la source du message
15
+     */
16
+    public String pseudo;
17
+    /**
18
+     * id de l'utilidateur source du message
19
+     */
20
+    public int id;
21
+
22
+    /**
23
+     * Créé un message à partir des info.
24
+     * @see Message
25
+     * @param typeMessage
26
+     * @param srcIP
27
+     * @param srcPort
28
+     * @param destIP
29
+     * @param destPort
30
+     * @param pseudo
31
+     * @param id
32
+     */
33
+    public MessagePseudo(int typeMessage, InetAddress srcIP, int srcPort, InetAddress destIP, int destPort, String pseudo, int id) {
34
+        super(typeMessage, srcIP, srcPort, destIP, destPort);
35
+        this.pseudo = pseudo;
36
+        this.id = id;
37
+    }
38
+
39
+    /**
40
+     * Crée un message à partir d'un message de base
41
+     * @see Message
42
+     * @param msg
43
+     * @param id
44
+     * @param pseudo
45
+     */
46
+    //Create Messages.MessagePseudo from Messages.Message
47
+    public MessagePseudo(Message msg, int id, String pseudo){
48
+        super(msg);
49
+        this.pseudo = pseudo;
50
+        this.id = id;
51
+    }
52
+
53
+    /**
54
+     * permet de renvoyer un string représtant ce message (surout pour les tests)
55
+     * @param id
56
+     * @param pseudo
57
+     * @return
58
+     */
59
+    //Returns payload for a pseudo message
60
+    public static String pseudoPayload(int id, String pseudo){
61
+        return Integer.toString(id) + "|" + pseudo;
62
+    }
63
+}

+ 31
- 0
src/main/java/app/insa/clav/UI/UserInterface.java View File

@@ -0,0 +1,31 @@
1
+package app.insa.clav.UI;
2
+
3
+import app.insa.clav.Core.Controller;
4
+
5
+/**
6
+ * UI (test pour l'instant)
7
+ */
8
+public class UserInterface {
9
+
10
+    /**
11
+     * Controlleur lié à cette fenetre
12
+     */
13
+    private Controller ctrl;
14
+
15
+    /**
16
+     * @param pseudo
17
+     *              Fonction liée au boutton d'envoi de pseudo (par forcement utile,
18
+     *              on peut lier directement la fonction du controleur au bouton en vrai)
19
+     */
20
+    public void pressButtonChangePseudo(String pseudo){
21
+        this.ctrl.choosePseudo(pseudo);
22
+    }
23
+
24
+    /** Pour les tests. Print un message.
25
+     * @param payload
26
+     */
27
+    public void printMessagePseudo(String payload){
28
+        System.out.println(payload);
29
+    }
30
+
31
+}

+ 29
- 0
src/main/java/app/insa/clav/Utils/TimerTaskResponseWait.java View File

@@ -0,0 +1,29 @@
1
+package app.insa.clav.Utils;
2
+
3
+import app.insa.clav.reseau.UDPInput;
4
+
5
+import java.util.TimerTask;
6
+
7
+/**
8
+ * Classe de task qui est utilisée pour attendre 1 seconde après l'envo d'un message de type 1
9
+ * Après une seconde, on desactive les filtres de type 2 et 3 pour ne plus prendre en compte ces messages.
10
+ */
11
+public class TimerTaskResponseWait extends TimerTask {
12
+
13
+    /**
14
+     * Instance de UDPInput (meme que l'Application)
15
+     */
16
+    public UDPInput udpIn;
17
+
18
+    public TimerTaskResponseWait(UDPInput udpIn){
19
+        this.udpIn = udpIn;
20
+    }
21
+
22
+    /**
23
+     * Quand la seconde s'est écoulée, on met les filtres à faux pour ne plus prendre en compte les messages de type 2 et 3
24
+     */
25
+    public void run(){
26
+        udpIn.setFilterValue(2,false);
27
+        udpIn.setFilterValue(2,false);
28
+    }
29
+}

+ 131
- 0
src/main/java/app/insa/clav/reseau/UDPInput.java View File

@@ -0,0 +1,131 @@
1
+package app.insa.clav.reseau;
2
+
3
+import app.insa.clav.Messages.Message;
4
+
5
+import java.beans.PropertyChangeListener;
6
+import java.beans.PropertyChangeSupport;
7
+import java.io.ByteArrayInputStream;
8
+import java.io.IOException;
9
+import java.io.ObjectInputStream;
10
+import java.net.*;
11
+import java.util.ArrayList;
12
+
13
+
14
+/**
15
+ * Classe qui permet d'écouter des messages en UDP. Fonctionne dans un thread à part
16
+ */
17
+public class UDPInput extends Thread{
18
+
19
+    /**
20
+     * Socket par lequel on va recevoir les paquets
21
+     */
22
+    private DatagramSocket socket;
23
+    /**
24
+     * Buffer dans lequel on met les messages reçus si ils passent le filter
25
+     */
26
+    private ArrayList<Message> msgReceivedBuffer;
27
+    /**
28
+     * Permet d'implémenter le DP Observateur. Cette classe est l'obeservable.
29
+     * Cet attribut permet de notifier les observateurs (ici le modèle, soit l'Application)
30
+     */
31
+    private PropertyChangeSupport support;
32
+    /**
33
+     * Filtre qui permet de filtrer les messages entrants. L'index est en correspondance avec le type de message.
34
+     * i.e. filter[1] pour message de type 1. Si filter à vrai, message va dans le buffer et on notifie l'application
35
+     */
36
+    private boolean[] filter;
37
+
38
+    //Créer un attribut filtre que l'application pourra modifier. Selon le filtre, des notifications seront envoyées à l'application ou non
39
+
40
+
41
+    /**
42
+     * Constructeur
43
+     * @param localAddress
44
+     *                  Adresse IP locale
45
+     * @param localPort
46
+     *                  Numéro de port de la machine locale sur lequel on écoute (le même sur toutes les machines en théorie)
47
+     */
48
+    public UDPInput(InetAddress localAddress, int localPort){
49
+        try {
50
+            this.socket = new DatagramSocket(localPort,localAddress);
51
+            this.filter = new boolean[5];
52
+            this.filter[1] = true;
53
+            this.filter[2] = false;
54
+            this.filter[3] = false;
55
+            this.filter[4] = true;
56
+            this.socket.setBroadcast(true);
57
+            this.msgReceivedBuffer = new ArrayList<Message>();
58
+            this.support = new PropertyChangeSupport(this);
59
+        }
60
+        catch (SocketException e){
61
+            System.out.println("Exception creation SocketDatagrammeConfiguration");
62
+            e.printStackTrace();
63
+        }
64
+    }
65
+
66
+    /**
67
+     * Ajoute un observateur à qui on va envoyer les notifications de réception de messages
68
+     * @param pcl
69
+     *              Représente un classe qui implémente, PropertyChangeListener, donc un observateur
70
+     */
71
+    public void addPropertyChangeListener(PropertyChangeListener pcl){
72
+        //On va mettre name à "App" pour l'application
73
+        this.support.addPropertyChangeListener("UDPInput",pcl);
74
+    }
75
+
76
+    /**
77
+     * Renvoi le message le plus ancien du buffer et le supprime du buffer
78
+     * @return Le message le plus ancien du buffer
79
+     */
80
+    public Message getMessageReceived(){
81
+        return this.msgReceivedBuffer.remove(0);
82
+    }
83
+
84
+
85
+    /**
86
+     * Change les valeurs du filtre
87
+     * @param index
88
+     *              Numéro du type de message à filtrer
89
+     * @param value
90
+     *              Vrai ou faux selon si on veut laisser passer le message ou non (vrai -> message passe)
91
+     */
92
+    public void setFilterValue(int index, boolean value){
93
+        this.filter[index] = value;
94
+    }
95
+
96
+    /**
97
+     * Ecoute en permanance le socket UDP et si un message reçu passe le filtre, on notifie les observateurs
98
+     */
99
+    @Override
100
+    public void run() {
101
+        byte[] buffer = new byte[9000];
102
+        while(true){
103
+            DatagramPacket inputPacket = new DatagramPacket(buffer,buffer.length);
104
+            try
105
+            {
106
+                this.socket.receive(inputPacket);
107
+            }
108
+            catch (IOException e){
109
+                System.out.println("IOException reception paquet UDP");
110
+                e.printStackTrace();
111
+            }
112
+            ByteArrayInputStream byteInStream = new ByteArrayInputStream(inputPacket.getData());
113
+            try {
114
+                ObjectInputStream objectInStream = new ObjectInputStream(byteInStream);
115
+                Message msg = (Message) objectInStream.readObject();
116
+                if (this.filter[msg.typeMessage]){
117
+                    this.msgReceivedBuffer.add(msg);
118
+                    this.support.firePropertyChange("UDPInput",this.msgReceivedBuffer.size() -1, this.msgReceivedBuffer.size());
119
+                }
120
+            }
121
+            catch (IOException e){
122
+                System.out.println("IOException déserialization paquet UDP");
123
+                e.printStackTrace();
124
+            }
125
+            catch (ClassNotFoundException e){
126
+                System.out.println("IOException déserialization paquet UDP");
127
+                e.printStackTrace();
128
+            }
129
+        }
130
+    }
131
+}

+ 71
- 0
src/main/java/app/insa/clav/reseau/UDPOutput.java View File

@@ -0,0 +1,71 @@
1
+package app.insa.clav.reseau;
2
+
3
+import app.insa.clav.Messages.Message;
4
+
5
+import java.io.ByteArrayOutputStream;
6
+import java.io.IOException;
7
+import java.io.ObjectOutputStream;
8
+import java.net.*;
9
+
10
+
11
+/**
12
+ * Classe qui permet d'envoyer des messages en UDP
13
+ */
14
+public class UDPOutput{
15
+
16
+    /**
17
+     * Socket UDP par lequel on envoie les messages
18
+     * En théorie peut être le même que celui d en Input ou sur différent port.
19
+     */
20
+    private DatagramSocket socket;
21
+
22
+    /**
23
+     * Constructeur
24
+     * @param localAddress
25
+     *                  IP locale
26
+     * @param outputPort
27
+     *                  Port du socket output
28
+     */
29
+    public UDPOutput(InetAddress localAddress, int outputPort){
30
+        try {
31
+            this.socket = new DatagramSocket(outputPort, localAddress);
32
+            this.socket.setBroadcast(true);
33
+        }
34
+        catch (SocketException e){
35
+            System.out.println("Exception creation SocketDatagrammeConfiguration");
36
+            e.printStackTrace();
37
+        }
38
+    }
39
+
40
+    /**
41
+     * Envoie le message en paramètre (le message contient toutes les informations de routage
42
+     * @param msg
43
+     *          Message à envoyer
44
+     */
45
+    public void sendMsg(Message msg){
46
+        try {
47
+            //Envoi du pseudo sur le reseau local à l'adresse IP dest sur le port dest
48
+            byte[] buffer = "".getBytes();
49
+            ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
50
+            try {
51
+                ObjectOutputStream objectOutStream = new ObjectOutputStream(byteOutStream);
52
+                objectOutStream.writeObject(msg);
53
+                objectOutStream.close();
54
+                buffer = byteOutStream.toByteArray();
55
+            } catch (IOException e1) {
56
+                System.out.println("Exception serialisation de l'objet envoi message");
57
+            }
58
+            //InetAddress broadcastAdress = InetAddress.getByAddress("255.255.255.255".getBytes());
59
+            DatagramPacket packet = new DatagramPacket(buffer,buffer.length,msg.destIP,msg.destPort);
60
+            this.socket.send(packet);
61
+        }
62
+        catch (UnknownHostException e){
63
+            System.out.println("Unknown host dans broadcast address");
64
+            e.printStackTrace();
65
+        }
66
+        catch (IOException e){
67
+            System.out.println("IOException send pseudo");
68
+            e.printStackTrace();
69
+        }
70
+    }
71
+}

+ 8
- 0
src/main/resources/fxml/sample.fxml View File

@@ -0,0 +1,8 @@
1
+<?import javafx.geometry.Insets?>
2
+<?import javafx.scene.layout.GridPane?>
3
+
4
+<?import javafx.scene.control.Button?>
5
+<?import javafx.scene.control.Label?>
6
+<GridPane
7
+        xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
8
+</GridPane>

Loading…
Cancel
Save