From 7bd2f3ecb6d2e3ef7ce4792f661f4a6df705b15e Mon Sep 17 00:00:00 2001
From: Alexandre Gonzalvez
Date: Fri, 18 Dec 2020 18:25:41 +0100
Subject: [PATCH] v1 chat_local
---
.../Clavardage/src/controller/Controller.java | 220 ++++++++++--------
.../Clavardage/src/controller/Historique.java | 2 +-
.../controller/ListeningThreadTCPChat.java | 40 ++--
.../ListeningThreadTCPConnection.java | 5 +-
.../src/controller/ListeningThreadUDP.java | 5 +-
.../Clavardage/src/model/LocalUser.java | 4 +-
Application/Clavardage/src/model/Message.java | 24 +-
.../Clavardage/src/model/Msg_Text.java | 4 +-
.../Clavardage/src/view/Interface.java | 120 ++++++----
9 files changed, 245 insertions(+), 179 deletions(-)
diff --git a/Application/Clavardage/src/controller/Controller.java b/Application/Clavardage/src/controller/Controller.java
index e70b9e0..1998196 100644
--- a/Application/Clavardage/src/controller/Controller.java
+++ b/Application/Clavardage/src/controller/Controller.java
@@ -28,17 +28,22 @@ import view.Interface;
public class Controller {
/*** CONSTANTES ***/
- final static int portUDPlistening_remoteUsr2 = 31002; // TO REMOVE when we use broadcast
- final static int portUDPlistening_remoteUsr3 = 31003; // TO REMOVE when we use broadcast
-
- public Boolean interfaceRunning;
+ int NB_SECOND_WAITING_RESPONSE_BROADCAST = 2;
+
+ // TO REMOVE when we use broadcast
+ final static int portUDPlistening_usr1 = 31001;
+ final static int portUDPlistening_remoteUsr2 = 31002;
+ final static int portUDPlistening_remoteUsr3 = 31003;
+ final static int [] tabBroadcast = {portUDPlistening_usr1,portUDPlistening_remoteUsr2,portUDPlistening_remoteUsr3};
+
+ public Boolean interfaceRunning = false;
/*** ATTRIBUTS ***/
protected LocalUser myUser;
protected Interface view;
private ListeningThreadUDP udp_connect_thread;
private ListeningThreadTCPConnection tcp_connect_thread;
private Historique histoire;
- private Chat activeChat;
+ protected Chat activeChat;
/**
* Constructor of Controller
@@ -82,7 +87,8 @@ public class Controller {
notify_remote_users();
-
+ interfaceRunning =true;
+ view=Interface.createAndShowGUI(this);
}
/**
@@ -110,13 +116,32 @@ public class Controller {
catch(UnknownHostException e) {
JOptionPane.showMessageDialog(null ,"Could not find local address!");
}
+
this.myUser = new LocalUser(pseudo,addIP,portUDPsend,portUDPlistening,portTCP);
+ try {
+ if(this.validatePseudo(pseudo)) {
+
+
+ this.udp_connect_thread = new ListeningThreadUDP("UDP Listening thread",this);
+ this.udp_connect_thread.start();
+
+ this.tcp_connect_thread = new ListeningThreadTCPConnection("TCP main Listening thread",this);
+ this.tcp_connect_thread.start();
+
+ interfaceRunning =true;
+ view=Interface.createAndShowGUI(this);
+ }
+ else {
+ System.out.println("Unavailable "+pseudo);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+
+
- this.udp_connect_thread = new ListeningThreadUDP("UDP Listening thread",this);
- this.udp_connect_thread.start();
- this.tcp_connect_thread = new ListeningThreadTCPConnection("TCP main Listening thread",this);
- this.tcp_connect_thread.start();
notify_remote_users();
}
@@ -188,11 +213,11 @@ public class Controller {
public void changePseudo() throws IOException {
String oldPseudo = this.myUser.getPseudo(); //Saves the old one for comparison
- String tmpPseudo = view.PseudotextField.getText(); // Read user input
+ String tmpPseudo = view.ChangePseudotextField.getText(); // Read user input
if(!(this.validatePseudo(tmpPseudo)) || tmpPseudo.equals(oldPseudo)) {
view.Pseudolabel.setText("Already exists, enter another nickname. Your current username is: " + oldPseudo); // Read user input
- tmpPseudo = view.PseudotextField.getText(); // Read user input
+ tmpPseudo = view.ChangePseudotextField.getText(); // Read user input
}
else {
this.myUser.setPseudo(tmpPseudo);
@@ -221,46 +246,45 @@ public class Controller {
// Call broadcast
InetAddress broadcastIP = InetAddress.getLocalHost(); // change to broadcast
- //System.out.println(broadcastIP);
+ //System.out.println(this.myUser.getPortUDPsend());
DatagramSocket dgramSocket = new DatagramSocket(this.myUser.getPortUDPsend(),this.myUser.getAddIP());
byte[] buffer = new byte[256];
// Création du message à envoyer
- String toSend = this.myUser.getAddIP()+":"+this.myUser.getPortUDPsend()+":test";
+ String toSend = this.myUser.getAddIP()+":"+this.myUser.getPortUDPsend()+":info";
- // Send to remote user 1
- DatagramPacket outPacket= new DatagramPacket(toSend.getBytes(), toSend.length(),broadcastIP, portUDPlistening_remoteUsr2);
- dgramSocket.send(outPacket);
-
- // Send to remote user 2
- outPacket= new DatagramPacket(toSend.getBytes(), toSend.length(),broadcastIP, portUDPlistening_remoteUsr3);
- dgramSocket.send(outPacket);
-
- // Initialisation des variables de la boucle
- Boolean valid = true;
+ // Send to other active user (simulation of broadcast)
+ DatagramPacket outPacket = null;
+ int tabBroadcastSize = tabBroadcast.length;
+ for(int i=0;i
* En utilisant le port UDP d'envoi, on envoie en broadcast les informations nous concernant
*
*/
public void notify_remote_users() {
- // Création du socket d'envoi d'information
DatagramSocket dgramSocket= null;
try {
dgramSocket= new DatagramSocket(this.myUser.getPortUDPsend(),this.myUser.getAddIP());
} catch (IOException e) {
e.printStackTrace();
}
-
- // Construction du message à envoyer
- String toSend = this.myUser.getAddIP().toString()+":"+this.myUser.getPortTCP()+":"+this.myUser.getPseudo()+":test";
+ // Send to other active user (simulation of broadcast)
+ String toSend = this.myUser.getAddIP().toString()+":"+this.myUser.getPortTCP()+":"+this.myUser.getPseudo()+":notify";
DatagramPacket outPacket =null;
-
- // Send information to usr2
- if(this.myUser.getPortUDPlistening()!=portUDPlistening_remoteUsr2) {
- outPacket = new DatagramPacket(toSend.getBytes(), toSend.length(),this.myUser.getAddIP(), portUDPlistening_remoteUsr2);
- try {
- dgramSocket.send(outPacket);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
-
- // Send information to usr3
- if(this.myUser.getPortUDPlistening()!=portUDPlistening_remoteUsr3) {
-
- outPacket= new DatagramPacket(toSend.getBytes(), toSend.length(),this.myUser.getAddIP(), portUDPlistening_remoteUsr3);
- try {
- dgramSocket.send(outPacket);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
+ int tabBroadcastSize = tabBroadcast.length;
+ for(int i=0;i "+rm.getPseudo()+" : "+input);
+ Msg_Text message = new Msg_Text(rm,input);
+ c.addMessage(message);
+ if(controller.activeChat==c) {
+ controller.view.notifyNewMessage("("+message.getDate()+")\n"+c.getRemoteUser().getPseudo()+" : "+input);
+ }
+ }
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
}
else {
System.out.println("("+this.controller.myUser.getPseudo()+") Remote User unidentifiable => CLOSING CONNECTION");
}
- /*** listening tcp message from rm until session is close ***/
-
- try {
- System.out.println("("+this.controller.myUser.getPseudo()+") WAIT FOR NEW MESSAGE FROM "+rm.getPseudo());
-
- while (!(input=in.readLine()).equals("end")/* && c.getActive()*/) {
- System.out.println("("+this.controller.myUser.getPseudo()+") recoit => "+rm.getPseudo()+" : "+input);
- c.addMessage(new Msg_Text(rm.getAddIP(),input));
- // TODO Prévenir l'interface de la réception d'un nouveau message
- controller.view.notifyNewMessage();
-
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
+
diff --git a/Application/Clavardage/src/controller/ListeningThreadTCPConnection.java b/Application/Clavardage/src/controller/ListeningThreadTCPConnection.java
index 614b3c4..31833a4 100644
--- a/Application/Clavardage/src/controller/ListeningThreadTCPConnection.java
+++ b/Application/Clavardage/src/controller/ListeningThreadTCPConnection.java
@@ -1,7 +1,5 @@
package controller;
-import model.LocalUser;
-
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
@@ -51,9 +49,8 @@ public class ListeningThreadTCPConnection extends ListeningThread{
System.out.println("("+this.controller.myUser.getPseudo()+") Server is not listening on port "+this.controller.myUser.getPortTCP());
e.printStackTrace();
}
- // TODO changer le true
while(true) {
- System.out.println("("+this.controller.myUser.getPseudo()+") WAITING FOR NEW CONNECTION");
+ System.out.println("("+this.controller.myUser.getPseudo()+") TCP Server waiting for new connection ...");
try {
this.accept(servSocket);
diff --git a/Application/Clavardage/src/controller/ListeningThreadUDP.java b/Application/Clavardage/src/controller/ListeningThreadUDP.java
index 808103e..12d51c3 100644
--- a/Application/Clavardage/src/controller/ListeningThreadUDP.java
+++ b/Application/Clavardage/src/controller/ListeningThreadUDP.java
@@ -86,7 +86,7 @@ public class ListeningThreadUDP extends ListeningThread{
else {
try {
// On récupère l'adresse IP et le port TCP de l'utilisateur distant et ajout à la liste de l'utilisateur utilisant ce thread
- this.controller.myUser.addRemoteUser(InetAddress.getByName(tabMsg[0].split("/")[1]),Integer.parseInt(tabMsg[1]),tabMsg[2]);
+ controller.myUser.addRemoteUser(InetAddress.getByName(tabMsg[0].split("/")[1]),Integer.parseInt(tabMsg[1]),tabMsg[2]);
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -94,6 +94,9 @@ public class ListeningThreadUDP extends ListeningThread{
// TODO Auto-generated catch block
e.printStackTrace();
}
+ if(controller.interfaceRunning) {
+ controller.view.updateActiveUsers();
+ }
}
diff --git a/Application/Clavardage/src/model/LocalUser.java b/Application/Clavardage/src/model/LocalUser.java
index e22672b..9230f63 100644
--- a/Application/Clavardage/src/model/LocalUser.java
+++ b/Application/Clavardage/src/model/LocalUser.java
@@ -69,11 +69,11 @@ public class LocalUser extends User{
RemoteUser tmpRemoteUser = new RemoteUser(remoteUserPseudo,remoteUserIP,remoteUserPortTCP);
int index = this.remoteUsersList.indexOf(tmpRemoteUser);
if(index!=-1) {
- System.out.println("("+this.pseudo+") - "+"MAJ, IP(port) of user : "+remoteUserPseudo+" => "+remoteUserIP+"("+remoteUserPortTCP+")");
+ System.out.println("("+this.pseudo+") "+"MAJ, IP(port) : "+remoteUserPseudo+" => "+remoteUserIP+"("+remoteUserPortTCP+")");
this.remoteUsersList.set(index,tmpRemoteUser);
}
else {
- System.out.println("("+this.pseudo+") - "+"Add new user IP(port) of user : "+remoteUserPseudo+" => "+remoteUserIP+"("+remoteUserPortTCP+")");
+ System.out.println("("+this.pseudo+") "+"Add new user IP(port) : "+remoteUserPseudo+" => "+remoteUserIP+"("+remoteUserPortTCP+")");
this.remoteUsersList.add(tmpRemoteUser);
}
}
diff --git a/Application/Clavardage/src/model/Message.java b/Application/Clavardage/src/model/Message.java
index c07ad47..7bf5a1a 100644
--- a/Application/Clavardage/src/model/Message.java
+++ b/Application/Clavardage/src/model/Message.java
@@ -8,9 +8,8 @@ import java.text.SimpleDateFormat;
public abstract class Message {
/*** ATTRIBUTS ***/
- private Date date;
- private InetAddress autorIP;
-
+ private String date;
+ private User autor;
/**
* Constructor of Message
* @parametres
@@ -20,25 +19,22 @@ public abstract class Message {
*
*
*/
- public Message(InetAddress autorIP) {
- this.autorIP = autorIP;
+ public Message(User autor) {
+ this.autor = autor;
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
- this.date = new Date();
+ this.date = dateFormat.format(new Date());
}
/*** GETTERS ***/
- public Date getDate() {
+ public String getDate() {
return date;
}
- public InetAddress getAutorIP() {
- return autorIP;
+ public User getAutor() {
+ return autor;
}
/*** SETTERS ***/
- public void setDate(Date date) {
- this.date = date;
- }
- public void setAutorIP(InetAddress autorIP) {
- this.autorIP = autorIP;
+ public void setAutorIP(User autor) {
+ this.autor = autor;
}
diff --git a/Application/Clavardage/src/model/Msg_Text.java b/Application/Clavardage/src/model/Msg_Text.java
index 954f400..7ec3750 100644
--- a/Application/Clavardage/src/model/Msg_Text.java
+++ b/Application/Clavardage/src/model/Msg_Text.java
@@ -7,8 +7,8 @@ public class Msg_Text extends Message{
/*** ATTRIBUT ***/
private String text;
- public Msg_Text(InetAddress autorIP,String text) {
- super(autorIP);
+ public Msg_Text(User autor,String text) {
+ super(autor);
this.text = text;
}
diff --git a/Application/Clavardage/src/view/Interface.java b/Application/Clavardage/src/view/Interface.java
index f439471..6ab128d 100644
--- a/Application/Clavardage/src/view/Interface.java
+++ b/Application/Clavardage/src/view/Interface.java
@@ -6,7 +6,6 @@ import java.awt.event.*;
import java.io.IOException;
import controller.Controller;
-import model.RemoteUser;
public class Interface extends JFrame implements ActionListener, WindowListener {
@@ -18,14 +17,15 @@ public class Interface extends JFrame implements ActionListener, WindowListener
public Controller controller;
public JLabel Pseudolabel;
- public JTextField PseudotextField;
+ public JLabel ChangePseudolabel;
+ public JTextField ChangePseudotextField;
public JTextArea MessagetextArea;
public JTextField MessagetextField;
public JScrollPane scrollpane;
public JButton RemoteUserButton;
- public JComboBox RemoteUserbox;
+ public JComboBox RemoteUserbox;
public JButton CloseConversationButton;
//Specifies the look and feel to use. Valid values:
@@ -47,53 +47,89 @@ public class Interface extends JFrame implements ActionListener, WindowListener
public Component createComponents() {
//Pseudo setup
- PseudotextField = new JTextField();
- PseudotextField.setColumns(10);
- PseudotextField.addActionListener(this);
- Pseudolabel = new JLabel("Your current username is: " + controller.getMyUser().getPseudo());
- Pseudolabel.setLabelFor(PseudotextField);
+ JPanel changePseudoPanel = new JPanel(new GridLayout(1, 0));
+ ChangePseudolabel = new JLabel("Change nickname : ");
+ changePseudoPanel.add(ChangePseudolabel);
+ ChangePseudotextField = new JTextField();
+ ChangePseudotextField.setColumns(10);
+ ChangePseudotextField.addActionListener(this);
+ changePseudoPanel.add(ChangePseudotextField);
+
+ Pseudolabel = new JLabel("Nickname : "+controller.getMyUser().getPseudo());
+ Pseudolabel.setLabelFor(ChangePseudotextField);
+
+
//Remote user list setup
- RemoteUserButton = new JButton("Click to get Remote User list");
+ RemoteUserButton = new JButton("Start session");
RemoteUserButton.addActionListener(this);
+
+
+ // Remote user list
//Converts the Userlist to a Pseudotab for treatment in actionPerformed
- String[] pseudotab = new String[controller.getMyUser().getRemoteUsersList().size()];
- for(int i=0; i < controller.getMyUser().getRemoteUsersList().size(); i++) {
- pseudotab[i] = "(" + Integer.toString(i) + "): " + controller.getMyUser().getRemoteUsersList().get(i).getPseudo();
- }
- RemoteUserbox = new JComboBox(pseudotab);
+ String[] pseudotab = controller.askUpdateActiveUsers();
+ RemoteUserbox = new JComboBox(pseudotab);
RemoteUserbox.setEditable(true);
RemoteUserbox.addActionListener(this);
RemoteUserbox.setVisible(false);
- CloseConversationButton = new JButton("Click to close active chat");
+
+ // Close session
+ CloseConversationButton = new JButton("Close session");
CloseConversationButton.addActionListener(this);
CloseConversationButton.setVisible(false);
+ JPanel userListsPanel = new JPanel(new GridLayout(1, 0));
+
+ userListsPanel.add(RemoteUserButton);
+ userListsPanel.add(RemoteUserbox);
+ userListsPanel.add(CloseConversationButton);
+
+
//Messages setup
MessagetextField = new JTextField();
MessagetextField.setColumns(10);
MessagetextField.addActionListener(this);
- MessagetextArea = new JTextArea("Message field: ");
+ MessagetextArea = new JTextArea("Chat");
scrollpane = new JScrollPane();
scrollpane.getViewport().add(MessagetextArea);
scrollpane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+ scrollpane.setPreferredSize(new Dimension(600,60));
MessagetextField.setVisible(false);
MessagetextArea.setVisible(false);
scrollpane.setVisible(false);
+ // Create a placeholder on JTextField
+ MessagetextField.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ if (MessagetextField.getText().equals("Your message")) {
+ MessagetextField.setText("");
+ MessagetextField.setForeground(Color.BLACK);
+ }
+ }
+ @Override
+ public void focusLost(FocusEvent e) {
+ if (MessagetextField.getText().isEmpty()) {
+ MessagetextField.setForeground(Color.GRAY);
+ MessagetextField.setText("Your message");
+ }
+ }
+ });
+
/*
* An easy way to put space between a top-level container
* and its contents is to put the contents in a JPanel
* that has an "empty" border.
*/
- JPanel pane = new JPanel(new GridLayout(0, 2));
- pane.add(Pseudolabel);
- pane.add(PseudotextField);
- pane.add(RemoteUserButton);
- pane.add(RemoteUserbox);
- pane.add(scrollpane);
- pane.add(MessagetextField);
- pane.add(CloseConversationButton);
+ JPanel header = new JPanel(new GridLayout(0, 1));
+ header.add(Pseudolabel);
+ header.add(changePseudoPanel);
+ header.add(userListsPanel);
+
+ JPanel pane = new JPanel(new BorderLayout());
+ pane.add(header,BorderLayout.NORTH);
+ pane.add(scrollpane,BorderLayout.CENTER);
+ pane.add(MessagetextField,BorderLayout.SOUTH);
pane.setBorder(BorderFactory.createEmptyBorder(
30, //top
30, //left
@@ -105,8 +141,8 @@ public class Interface extends JFrame implements ActionListener, WindowListener
}
public void actionPerformed(ActionEvent e) {
- if(e.getSource() == PseudotextField) { //Changing pseudo
- String Textinput = PseudotextField.getText();
+ if(e.getSource() == ChangePseudotextField) { //Changing pseudo
+ String Textinput = ChangePseudotextField.getText();
Pseudolabel.setText("Your current username is: " + Textinput);
try {
@@ -117,7 +153,7 @@ public class Interface extends JFrame implements ActionListener, WindowListener
}
}else if(e.getSource() == MessagetextField){ //Messages
String Textinput = MessagetextField.getText();
- MessagetextArea.setText(MessagetextArea.getText() + controller.getMyUser().getPseudo() + ": " + Textinput + "\n");
+ MessagetextArea.setText(MessagetextArea.getText() + "\n" + controller.getMyUser().getPseudo() + " : " + Textinput );
MessagetextField.setText("");
controller.askToSend(Textinput); // ask to send to controller
@@ -129,15 +165,16 @@ public class Interface extends JFrame implements ActionListener, WindowListener
scrollpane.setVisible(false);
MessagetextField.setVisible(false);
CloseConversationButton.setVisible(false);
- }else { // Choice in remote user list
+ }else if(e.getSource() == RemoteUserbox){ // Choice in remote user list
- JComboBox cb = (JComboBox)e.getSource(); //Casts obscurs pour récupérer le numéro du user dans la liste
- int selectedUsernb = Integer.parseInt(String.valueOf(((String) cb.getSelectedItem()).charAt(1)));
+ //JComboBox cb = (JComboBox)e.getSource(); //Casts obscurs pour récupérer le numéro du user dans la liste
+ int selectedUsernb = RemoteUserbox.getSelectedIndex();
+ //String.valueOf(((String) cb.getSelectedItem()).charAt(1)));
// start or switch chat => get history
String history = controller.askOpenSession(selectedUsernb);
// display it
- MessagetextArea.setText("Message:"+history);
+ MessagetextArea.setText(history);
MessagetextField.setVisible(true);
scrollpane.setVisible(true);
MessagetextArea.setVisible(true);
@@ -198,14 +235,15 @@ public class Interface extends JFrame implements ActionListener, WindowListener
Interface app = new Interface(controller);
Component contents = app.createComponents();
frame.getContentPane().add(contents, BorderLayout.CENTER);
+ frame.setPreferredSize(new Dimension(400,300));
//Ends all running background tasks upon closing the window
frame.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
- System.out.println("Window has been closed");
- app.controller.interfaceRunning = false;
- System.exit(0);
+ System.out.println("("+controller.getMyUser().getPseudo()+") Window has been closed");
+ controller.askForClose();
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
@@ -225,14 +263,14 @@ public class Interface extends JFrame implements ActionListener, WindowListener
public void windowClosing(WindowEvent e) {}
- public void notifyNewMessage() {
- String newMessage = controller.askNewMessage();
- //TOCHECK maybe better way to do it
- if(newMessage!="") {
- //TODO afficher le message
-
- }
+ public void notifyNewMessage(String msg) {
+ MessagetextArea.setText(MessagetextArea.getText() + "\n" + msg);
+ }
+
+ public void updateActiveUsers() {
+ DefaultComboBoxModel model = new DefaultComboBoxModel<>( controller.askUpdateActiveUsers() );
+ RemoteUserbox.setModel( model );
}
/*
public static void main(String[] args) throws IOException {