diff --git a/src/GUI/ApplicationMain.java b/src/GUI/ApplicationMain.java index 9a912f67ecc72af48588caa62ae99f74759ba29c..f58583c786fdc49d256d02afc788c81f773f9f06 100644 --- a/src/GUI/ApplicationMain.java +++ b/src/GUI/ApplicationMain.java @@ -9,10 +9,10 @@ import java.awt.event.WindowEvent; import java.rmi.RemoteException; public class ApplicationMain extends JPanel { - Client client; - ChatScreen chatScreen; - PaintGUI paintGUI; - JFrame frame; + private Client client; + private ChatScreen chatScreen; + private PaintGUI paintGUI; + private JFrame frame; public ChatScreen getChatScreen() { return chatScreen; } @@ -28,37 +28,45 @@ public class ApplicationMain extends JPanel { this.paintGUI = new PaintGUI(client); } - public void createAndShowGUI() { + public void createAndShowGUI() + { frame = new JFrame("Application Main"); JFrame.setDefaultLookAndFeelDecorated(true); Container content = frame.getContentPane(); content.setLayout(new BorderLayout()); content.add(paintGUI.getGlobal(), BorderLayout.WEST); content.add(chatScreen.panel2, BorderLayout.EAST); - SwingUtilities.getRootPane(chatScreen.getSendButton()).setDefaultButton(chatScreen.getSendButton()); + chatScreen.setUserName(client.getUserName()); + SwingUtilities.getRootPane(chatScreen.getSendButton()).setDefaultButton(chatScreen.getSendButton()); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent arg0) { - int answer = JOptionPane.showConfirmDialog(null, + int reply = JOptionPane.showConfirmDialog(null, "Are you sure you want to quit the session?", "Shut down session", JOptionPane.YES_NO_OPTION); - System.out.println(answer); - if (answer == 0) + + if( reply == JOptionPane.YES_OPTION ) { - System.out.println("Quitting session"); try { client.getClientController().quit(client.getUserName()); } catch (RemoteException e) { - e.printStackTrace(); + StartScreen.showErrorMessage("Error in quitting the server"); + //e.printStackTrace(); } + System.exit(0); } + + if( reply == JOptionPane.NO_OPTION ) + { + //do nothing + } } }); @@ -69,5 +77,4 @@ public class ApplicationMain extends JPanel { frame.pack(); frame.setVisible(true); } - } diff --git a/src/GUI/ChatScreen.form b/src/GUI/ChatScreen.form index baeed115748181b31d550c0aacfc5dc6db17fe1e..d33374440b768c016d7fb477525ab8432cac3f01 100644 --- a/src/GUI/ChatScreen.form +++ b/src/GUI/ChatScreen.form @@ -67,7 +67,7 @@ <properties/> <border type="none" title="Manager's Tools"/> <children> - <component id="b7068" class="javax.swing.JComboBox" binding="userSelectComboBox"> + <component id="b7068" class="javax.swing.JComboBox" binding="kickUserComboBox"> <constraints> <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/> </constraints> diff --git a/src/GUI/ChatScreen.java b/src/GUI/ChatScreen.java index ead543eed4ae0c187f108bed0e33e5d2aa4f55ad..b36a1a53b732ce6027fb4fc3de3dec9c97b63ee4 100644 --- a/src/GUI/ChatScreen.java +++ b/src/GUI/ChatScreen.java @@ -14,11 +14,10 @@ public class ChatScreen { private JButton sendButton; - // private JPanel drawingPanel; private JPanel othersPanel; private JComboBox sendMessageToComboBox; private JTextArea chatDisplayBox; - private JComboBox userSelectComboBox; + private JComboBox kickUserComboBox; private JButton kickOutButton; private JButton promoteToManagerButton; private JTextField chatInputBox; @@ -33,29 +32,33 @@ public class ChatScreen { private JButton exitThisRoomButton; private JButton quitButton; private JFrame frame; + public Client getClient() { return client; } public Client client; - public ChatScreen(Client client) { this.client = client; + yourNameDisplay.setText(client.getUserName()); exitThisRoomButton.addActionListener(actionListener); + quitButton.addActionListener(actionListener); sendButton.addActionListener(actionListener); - yourNameDisplay.setText(client.getUserName()); -// drawingPanel = new PaintGUI(client); -// SwingUtilities.getRootPane(sendButton).setDefaultButton(sendButton); + kickOutButton.addActionListener(actionListener); + promoteToManagerButton.addActionListener(actionListener); + } + + public void setUserName(String userName) + { + this.yourNameDisplay.setText(userName); } - public JButton getSendButton() { return sendButton; } - public JTextArea getChatDisplayBox() { return chatDisplayBox; } @@ -65,10 +68,27 @@ public class ChatScreen { return sendMessageToComboBox; } -// public JPanel getDrawingPanel() { -// return drawingPanel; -// } + public JComboBox getKickUserComboBox() + { + return kickUserComboBox; + } + + public void setManagerToolsVisibility() { + try { + if (client.getClientController().getAdmin().equals(client.getUserName())){ + managersPanel.setVisible(true); + } + else { + managersPanel.setVisible(false); + } + } catch (RemoteException e) { + e.printStackTrace(); + } + } + public void exitChatScreen() { + System.exit(0); + } ActionListener actionListener = new ActionListener() { @@ -106,13 +126,44 @@ public class ChatScreen { { System.out.println("Exit room button pressed"); clientController.quit(client.getUserName()); - System.exit(0); + exitChatScreen(); } catch (RemoteException ex) { ex.printStackTrace(); } } + else if (e.getSource() == kickOutButton) + { + + IClientController clientController = client.getClientController(); + String toUser = kickUserComboBox.getSelectedItem().toString(); + + try { + System.out.println("Kick out button pressed"); + clientController.kickUser(client.getUserName(), toUser); + } + catch (RemoteException ex) { + + ex.printStackTrace(); + } + + } + else if (e.getSource() == promoteToManagerButton) + { + + IClientController clientController = client.getClientController(); + String toUser = kickUserComboBox.getSelectedItem().toString(); + + try { + System.out.println("Promote to manager button pressed"); + clientController.assignAdmin(client.getUserName(), toUser); + } + catch (RemoteException ex) { + ex.printStackTrace(); + } + + } } }; diff --git a/src/GUI/StartScreen.java b/src/GUI/StartScreen.java index 77556623ec82c8efc4ec20a6da9f98566d176490..10ae2adbd8c2b4b5a47b8974c2eec8ab072b57be 100644 --- a/src/GUI/StartScreen.java +++ b/src/GUI/StartScreen.java @@ -33,32 +33,42 @@ public class StartScreen { { if (e.getSource() == joinButton) { - client.setServerAddress(textField2.getText()); - client.setUsername(textField1.getText()); + String serverAddress = textField2.getText(); + String userName = textField1.getText(); - if( client.connect() ) + int connectionStatus = client.connect(userName, serverAddress); + + if( connectionStatus == 1 ) { frame.setVisible(false); frame.dispose(); - //client.doSomething(); - new ChatScreen(client); + client.startApplication(); + } + else if( connectionStatus == 2 ) + { + showErrorMessage("Duplicate username: Please enter a new username"); + } + else if( connectionStatus == 3 ) + { + showErrorMessage("Cannot connect to server: Please check the server address"); } else { - showErrorMessage("Could not connect to server..."); + showErrorMessage("Unknown Connection Status"); } } } }; - private void showErrorMessage(String message) + public static void showErrorMessage(String message) { JOptionPane.showMessageDialog(null, - message, "Error", JOptionPane.PLAIN_MESSAGE); + message, "Error", JOptionPane.ERROR_MESSAGE); } - public void go(){ + public void go() + { joinButton.addActionListener(actionListener); frame = new JFrame("StartScreen"); frame.setContentPane(panel1); diff --git a/src/client/Client.java b/src/client/Client.java index cd93feb311820062fe3e3922f4f6af564063425f..5eed15f56e0382d5755970a297a77061654b344c 100644 --- a/src/client/Client.java +++ b/src/client/Client.java @@ -14,6 +14,9 @@ import java.rmi.registry.Registry; public class Client { + private final String DEFAULT_USERNAME = "Anonymous"; + private final String DEFAULT_SERVER_ADDRESS = "localhost"; + private String userName; private String serverAddress; @@ -27,17 +30,40 @@ public class Client private DrawingUpdate drawingUpdate; private StartScreen startScreen; - private ChatScreen chatScreen; private PaintGUI paintGUI; - public ApplicationMain getApplicationMain() { return applicationMain; } + + public String getUserName() + { + return this.userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getServerAddress() + { + return serverAddress; + } + + public void setServerAddress(String serverAddress) + { + this.serverAddress = serverAddress; + } private ApplicationMain applicationMain; - public PaintGUI getPaintGUI() { return paintGUI; } + public ApplicationMain getApplicationMain() { return applicationMain; } + public PaintGUI getPaintGUI() { + return paintGUI; + } - public ChatScreen getChatScreen() { return chatScreen; } + public ChatScreen getChatScreen() { + return getApplicationMain().getChatScreen(); + } public IChatController getChatController() { @@ -51,20 +77,6 @@ public class Client public IDrawingController getDrawingController() { return drawingController; } - public void setUsername(String userName) - { - this.userName = userName; - } - - public String getUserName() - { - return this.userName; - } - - public void setServerAddress(String serverAddress) - { - this.serverAddress = serverAddress; - } public Client(String username) throws RemoteException { @@ -72,11 +84,8 @@ public class Client this.clientUpdate = new ClientUpdate(this); this.chatUpdate = new ChatUpdate(this); this.drawingUpdate = new DrawingUpdate(this); -// this.startScreen = new StartScreen(this); -// this.chatScreen = new ChatScreen(this); -// this.paintGUI = new PaintGUI(this); + this.startScreen = new StartScreen(this); this.applicationMain = new ApplicationMain(this); - } public static void main(String[] args) @@ -84,38 +93,72 @@ public class Client try { Client client = new Client(args[0]); - client.connect(); -// client.getApplicationMain().getPaintGUI().getDrawingArea().setImage(client.drawingController.getCurrentImage()); - client.getApplicationMain().createAndShowGUI(); + client.showStartScreen(); } catch (Exception e) { - e.printStackTrace(); + StartScreen.showErrorMessage("Error starting up client"); } } - public boolean connect() + + public void showStartScreen() { + startScreen.go(); + } + + + public void startApplication() + { + applicationMain.createAndShowGUI(); + applicationMain.getChatScreen().setManagerToolsVisibility(); + } + + // return = 1 -> connected successfully + // return = 2 -> duplicate username + // return = 3 -> error in locating the server + public int connect(String userName, String serverAddress) + { + if( !userName.trim().isEmpty() ) + { + setUserName(userName); + } + userName = getUserName(); + + if( serverAddress.trim().isEmpty() ) + { + serverAddress = DEFAULT_SERVER_ADDRESS; + setServerAddress(serverAddress); + } + setServerAddress(serverAddress); + try { + System.out.println("Server address:" + serverAddress); registryServer = LocateRegistry.getRegistry(serverAddress); chatController = (IChatController) registryServer.lookup("ChatController"); clientController = (IClientController) registryServer.lookup("ClientController"); drawingController = (IDrawingController) registryServer.lookup("DrawingController"); - if (clientController.join(userName, this.chatUpdate, this.clientUpdate, this.drawingUpdate)) + System.out.println("User name:" + userName); + if( clientController.join(userName, this.chatUpdate, this.clientUpdate, this.drawingUpdate) ) { System.out.println("Connected to server"); - return true; + return 1; + } + else + { + return 2; } } catch (Exception e) { - e.printStackTrace(); - } + //e.printStackTrace(); - return false; + return 3; + } } + } \ No newline at end of file diff --git a/src/client/ClientUpdate.java b/src/client/ClientUpdate.java index aefdaf5e3e63106ee06a92b045f89c0f08b5a630..9fdef79bf4438c8af406c61911df11a72583d383 100644 --- a/src/client/ClientUpdate.java +++ b/src/client/ClientUpdate.java @@ -18,7 +18,6 @@ public class ClientUpdate extends UnicastRemoteObject implements IClientUpdate, this.client = client; } - @Override public boolean notifyClient(String fromClient, String newUsername) throws RemoteException { client.getApplicationMain().getChatScreen().getSendMessageToComboBox().addItem(newUsername); @@ -26,25 +25,70 @@ public class ClientUpdate extends UnicastRemoteObject implements IClientUpdate, return true; } + // for debuggins purposes + private void printUserList(String[] users) + { + System.out.print("Currently connected users: "); + for( String s : users ) + { + System.out.print(s + " "); + } + System.out.println(); + } + @Override public boolean updateUserList(String[] users) throws RemoteException { - //client.setConnectedUsers(users); + printUserList(users); + System.out.println("TEST1"); JComboBox userBox = client.getApplicationMain().getChatScreen().getSendMessageToComboBox(); + JComboBox kickUserBox = client.getChatScreen().getKickUserComboBox(); + System.out.println("TEST2"); userBox.removeAllItems(); + kickUserBox.removeAllItems(); + System.out.println("TEST3"); userBox.addItem("All"); + System.out.println("TEST4"); for( String s : users ) { if( !s.equals(client.getUserName()) ) { userBox.addItem(s); } + + if( !s.equals(client.getClientController().getAdmin()) ) + { + kickUserBox.addItem(s); + } + } return true; } + + @Override + public void terminateChat() throws RemoteException { + client.getChatScreen().exitChatScreen(); + } + + @Override + public void setVisibility() { + client.getChatScreen().setManagerToolsVisibility(); + } + + @Override + public void notifyManagerActions(String toClient, Action action) throws RemoteException { + switch (action) { + case KICKOUT: + client.getChatScreen().getChatDisplayBox().append(toClient + " has been kicked out by the manager.\n"); + break; + case ASSIGNADMIN: + client.getChatScreen().getChatDisplayBox().append(toClient + " is the new manager.\n"); + break; + } + } } diff --git a/src/client/DrawingUpdate.java b/src/client/DrawingUpdate.java index 7dbee07e4b97c93d89f59196245e1e8254664c02..abc1fa4b035108e5e32989a3fea31bdfe600a6fd 100644 --- a/src/client/DrawingUpdate.java +++ b/src/client/DrawingUpdate.java @@ -4,10 +4,6 @@ import GUI.DrawingArea; import remote.IDrawingUpdate; import java.awt.*; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Line2D; -import java.awt.geom.Rectangle2D; -import java.awt.geom.RectangularShape; import java.io.Serializable; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; diff --git a/src/remote/IClientController.java b/src/remote/IClientController.java index bde0a0f500ed01f94c2485ba8de0bdea378d05d9..349297d37ca18e26184c87e1d7754b5299718340 100644 --- a/src/remote/IClientController.java +++ b/src/remote/IClientController.java @@ -5,11 +5,17 @@ import java.rmi.RemoteException; public interface IClientController extends Remote { + enum Action {KICKOUT, ASSIGNADMIN}; + boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing) throws RemoteException; void quit(String username) throws RemoteException; - boolean assignAdmin(String username) throws RemoteException; + boolean assignAdmin(String oldAdmin, String newAdmin) throws RemoteException; boolean kickUser(String username, String who) throws RemoteException; + + boolean broadcastManagerMessage(String toClient, Action action) throws RemoteException; + + String getAdmin() throws RemoteException; } diff --git a/src/remote/IClientUpdate.java b/src/remote/IClientUpdate.java index c1337f90f560c6b527bd067d7d5d2cf0d85ee234..1d4dea6c68a9e1957ee31e94319807e95d08f5cb 100644 --- a/src/remote/IClientUpdate.java +++ b/src/remote/IClientUpdate.java @@ -6,7 +6,10 @@ import java.rmi.RemoteException; public interface IClientUpdate extends Remote, Serializable { - boolean notifyClient(String fromClient, String newUsername) throws RemoteException; - + enum Action {KICKOUT, ASSIGNADMIN}; boolean updateUserList(String[] users) throws RemoteException; + void terminateChat() throws RemoteException; + void notifyManagerActions(String toClient, Action action) throws RemoteException; + void setVisibility() throws RemoteException; + } diff --git a/src/server/ChatController.java b/src/server/ChatController.java index c667f7972a278d45903f71210ece4ff966c18a2f..a2a38a03e75bb952ed298a7f8050029cb38b0324 100644 --- a/src/server/ChatController.java +++ b/src/server/ChatController.java @@ -6,17 +6,14 @@ import remote.IChatUpdate; import java.io.Serializable; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; -import java.util.ArrayList; public class ChatController extends UnicastRemoteObject implements IChatController, Serializable { private Server server; - private ArrayList<String> messages; public ChatController(Server server) throws RemoteException { this.server = server; - this.messages = new ArrayList<>(); } @Override @@ -24,12 +21,9 @@ public class ChatController extends UnicastRemoteObject implements IChatControll { System.out.print("Broadcasting message to everyone..."); - IChatUpdate client; - for( User u : server.users ) { - client = u.getIChatUpdate(); - client.notifyChat(fromClient, message, false); + u.getIChatUpdate().notifyChat(fromClient, message, false); } System.out.print("...DONE\n"); diff --git a/src/server/ClientController.java b/src/server/ClientController.java index 5e7638f48e3e3307b6929a968b425e40722575a2..dfdb350ab7698554b76cf1eed74f27fc168d0107 100644 --- a/src/server/ClientController.java +++ b/src/server/ClientController.java @@ -22,22 +22,30 @@ public class ClientController extends UnicastRemoteObject implements IClientCont @Override public boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing) throws RemoteException { - server.chatController.broadcastMessageUserLogin(username); + if( getUserIndex(username) < 0 ) + { + // user with same username is not connected + server.chatController.broadcastMessageUserLogin(username); - User newUser = new User(username, clientChat, clientUpdate, clientDrawing); + User newUser = new User(username, clientChat, clientUpdate, clientDrawing); - server.users.add(newUser); + server.users.add(newUser); - if(server.users.size() == 1) - { - server.users.get(0).setAdmin(true); - } + if(server.users.size() == 1) + { + newUser.setAdmin(true); + } - System.out.println(username + " registered successfully"); + System.out.println(username + " registered successfully"); - broadcastUserList(); + broadcastUserList(); - return true; + return true; + } + else + { + return false; + } } @Override @@ -53,16 +61,33 @@ public class ClientController extends UnicastRemoteObject implements IClientCont broadcastUserList(); } + + printUserList(); + } + + // for debuggins purposes + private void printUserList() + { + System.out.print("Currently connected users: "); + for( User u : server.users ) + { + System.out.print(u.getUserName()); + } + System.out.println(); } @Override - public boolean assignAdmin(String username) throws RemoteException + public boolean assignAdmin(String oldAdmin, String newAdmin) throws RemoteException { - int adminIndex = getUserIndex(username); + int oldAdminIndex = getUserIndex(oldAdmin); + int newAdminIndex = getUserIndex(newAdmin); - if( adminIndex >= 0 ) + if( newAdminIndex >= 0 && server.users.get(oldAdminIndex).isAdmin()) { - server.users.get(adminIndex).setAdmin(true); + server.users.get(oldAdminIndex).setAdmin(false); + server.users.get(newAdminIndex).setAdmin(true); + broadcastUserList(); + broadcastManagerMessage(newAdmin, Action.ASSIGNADMIN); return true; } @@ -71,17 +96,25 @@ public class ClientController extends UnicastRemoteObject implements IClientCont } @Override - public boolean kickUser(String username, String who) throws RemoteException + public boolean kickUser(String manager, String kickedUser) throws RemoteException { - int userIndex = getUserIndex(who); + int userIndex = getUserIndex(kickedUser); - int adminIndex = getUserIndex(username); + int adminIndex = getUserIndex(manager); - if ( adminIndex > 0 && userIndex > 0 && server.users.get(adminIndex).isAdmin() ) + if ( adminIndex >= 0 && userIndex >= 0 && server.users.get(adminIndex).isAdmin() ) { - server.users.remove(userIndex); - broadcastUserList(); + try { + server.users.get(userIndex).getIClientUpdate().terminateChat(); + } + finally { + System.out.print(server.users); + server.users.remove(userIndex); + System.out.print(server.users); + broadcastUserList(); + broadcastManagerMessage(kickedUser, Action.KICKOUT); + } return true; } @@ -105,18 +138,68 @@ public class ClientController extends UnicastRemoteObject implements IClientCont return index; } - private void broadcastUserList() throws RemoteException + public void broadcastUserList() throws RemoteException { - String[] connectedUsers = new String[server.users.size()]; + String[] connectedUsers = new String[server.users.size()]; for( int i = 0; i<server.users.size(); i++ ) { connectedUsers[i] = server.users.get(i).getUserName(); } + printUserList(); + for( User u : server.users ) { + System.out.print(u.getUserName() + " being notified"); u.getIClientUpdate().updateUserList(connectedUsers); + System.out.println("...DONE"); + } + } + + @Override + public String getAdmin() throws RemoteException + { + String adminName = ""; + for( User u : server.users ) + { + if (u.isAdmin()) { + adminName = u.getUserName(); + } } + return adminName; + } + + @Override + public boolean broadcastManagerMessage(String toClient, Action action) throws RemoteException { + System.out.print("Broadcasting message to everyone..."); + IClientUpdate client; + + switch (action){ + case KICKOUT: + for( User u : server.users ) + { + client = u.getIClientUpdate(); + client.notifyManagerActions(toClient, remote.IClientUpdate.Action.KICKOUT); + } + + System.out.print("...DONE\n"); + System.out.println(toClient + " has been kicked out the room."); + break; + + case ASSIGNADMIN: + for( User u : server.users ) + { + client = u.getIClientUpdate(); + client.notifyManagerActions(toClient, remote.IClientUpdate.Action.ASSIGNADMIN); + client.setVisibility(); + } + + System.out.print("...DONE\n"); + System.out.println(toClient + " is the new manager."); + break; + } + + return true; } }