diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 0572b1f99553d976045df988b882a69b9480f69d..c9bef83d956785fec3a199e3aeaf85cc7fd85acc 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,7 +1,38 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> <component name="ChangeListManager"> +<<<<<<< HEAD <list default="true" id="688d774d-cfc7-4b0d-b00c-5ca931aba600" name="Default Changelist" comment="" /> +======= + <list default="true" id="688d774d-cfc7-4b0d-b00c-5ca931aba600" name="Default Changelist" comment=""> + <change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/ApplicationMain$1.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/ApplicationMain$1.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/ApplicationMain.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/ApplicationMain.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/ChatScreen$1.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/ChatScreen$1.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/ChatScreen.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/ChatScreen.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/DrawingArea$1.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/DrawingArea$1.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/DrawingArea$Mode.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/DrawingArea$Mode.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/DrawingArea.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/DrawingArea.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/PaintGUI$1.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/PaintGUI$1.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/PaintGUI.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/PaintGUI.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/StartScreen$1.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/StartScreen$1.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/StartScreen.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/GUI/StartScreen.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/client/Client.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/client/Client.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/client/ClientUpdate$1.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/client/ClientUpdate$1.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/client/ClientUpdate.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/client/ClientUpdate.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/client/DrawingUpdate.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/client/DrawingUpdate.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/remote/IDrawingController.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/remote/IDrawingController.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/remote/IDrawingUpdate.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/remote/IDrawingUpdate.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/server/ChatController.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/server/ChatController.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/server/ClientController$1.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/server/ClientController$1.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/server/ClientController.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/server/ClientController.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/out/production/infinitymonkeys/server/DrawingController.class" beforeDir="false" afterPath="$PROJECT_DIR$/out/production/infinitymonkeys/server/DrawingController.class" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/src/GUI/ApplicationMain.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/GUI/ApplicationMain.java" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/src/GUI/StartScreen.form" beforeDir="false" afterPath="$PROJECT_DIR$/src/GUI/StartScreen.form" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/src/GUI/StartScreen.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/GUI/StartScreen.java" afterDir="false" /> + </list> +>>>>>>> 4c8f776159855fde9cb2d4d4fddb9e800fee9122 <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> <option name="SHOW_DIALOG" value="false" /> <option name="HIGHLIGHT_CONFLICTS" value="true" /> @@ -62,7 +93,7 @@ </list> </option> </component> - <component name="RunManager" selected="Application.Client2"> + <component name="RunManager" selected="Application.Client1"> <configuration name="Client 3" type="Application" factoryName="Application"> <option name="MAIN_CLASS_NAME" value="client.Client" /> <module name="infinitymonkeys" /> @@ -113,10 +144,15 @@ <option name="presentableId" value="Default" /> <updated>1571631720382</updated> <workItem from="1571631723795" duration="17601000" /> +<<<<<<< HEAD <workItem from="1571654347656" duration="27259000" /> <workItem from="1571783604151" duration="19947000" /> <workItem from="1571812296671" duration="25759000" /> <workItem from="1571879738075" duration="12363000" /> +======= + <workItem from="1571654347656" duration="25114000" /> + <workItem from="1571786278739" duration="3319000" /> +>>>>>>> 4c8f776159855fde9cb2d4d4fddb9e800fee9122 </task> <task id="LOCAL-00001" summary="Changed the join method to send over a reference of the ClientUpdate Interface"> <created>1571646862883</created> @@ -158,6 +194,7 @@ <MESSAGE value="Changed the join method to send over a reference of the ClientUpdate Interface" /> <option name="LAST_COMMIT_MESSAGE" value="Changed the join method to send over a reference of the ClientUpdate Interface" /> </component> +<<<<<<< HEAD <component name="XDebuggerManager"> <breakpoint-manager> <breakpoints> @@ -178,5 +215,56 @@ </line-breakpoint> </breakpoints> </breakpoint-manager> +======= + <component name="simpleUML.UMLToolWindowPlugin"> + <General> + <option name="birdViewUpdateDelay" value="2000" /> + <option name="defaultFileLocation" value="file://$PROJECT_DIR$/.." /> + </General> + <Classdiagram> + <option name="diagramTitleFont" value="SansSerif,1,12" /> + <option name="diagramFont" value="SansSerif,0,10" /> + <option name="defaultFieldsExpanded" value="false" /> + <option name="defaultContructorsExpanded" value="false" /> + <option name="defaultMethodsExpanded" value="false" /> + <option name="showParameters" value="true" /> + <option name="showTooltip" value="true" /> + <option name="showReturnValues" value="true" /> + <option name="longModifier" value="true" /> + <option name="implementsBehaviour" value="1" /> + <option name="extendsBehaviour" value="1" /> + <option name="compartmentBehaviour" value="1" /> + <option name="interfaceBackgroundColor" value="-6494306" /> + <option name="abstractClassBackgroundColor" value="-1580132" /> + <option name="classBackgroundColor" value="-6508057" /> + <option name="diagramBackgroundColor" value="-1" /> + <option name="useAntialiasedConnectors" value="true" /> + <option name="quickSourceLinkColor" value="-16776961" /> + <option name="quickDiagramLinkColor" value="-8454144" /> + <option name="drawDecorations" value="false" /> + <option name="hideFieldList" value="" /> + <option name="showFieldList" value="" /> + <option name="hideConstructorList" value="" /> + <option name="showConstructorList" value="" /> + <option name="hideMethodList" value="" /> + <option name="showMethodList" value="" /> + <option name="minimumFigureSize" value="0,0" /> + </Classdiagram> + <Dependencydiagram> + <option name="diagramTitleFont" value="SansSerif,1,12" /> + <option name="diagramFont" value="SansSerif,0,10" /> + <option name="diagramBackgroundColor" value="-1" /> + <option name="useAntialiasedConnectors" value="true" /> + <option name="packageNameCompressionLevel" value="0" /> + </Dependencydiagram> + <Packagediagram> + <option name="diagramTitleFont" value="SansSerif,0,12" /> + <option name="diagramFont" value="SansSerif,0,10" /> + <option name="packageBackgroundColor" value="-4144960" /> + <option name="diagramBackgroundColor" value="-1" /> + <option name="useAntialiasedConnectors" value="true" /> + <option name="packageNameCompressionLevel" value="2" /> + </Packagediagram> +>>>>>>> 4c8f776159855fde9cb2d4d4fddb9e800fee9122 </component> </project> \ No newline at end of file diff --git a/src/GUI/ApplicationMain.java b/src/GUI/ApplicationMain.java index 7aec01f2fa8f9a57563a1ce43c946c33b8a52223..2e6823a7ddf65b173a760f480840065b8152a812 100644 --- a/src/GUI/ApplicationMain.java +++ b/src/GUI/ApplicationMain.java @@ -6,6 +6,7 @@ import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Random; @@ -57,8 +58,7 @@ 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(); @@ -68,32 +68,39 @@ public class ApplicationMain extends JPanel { chatScreen.setUserName(client.getUserName()); - try { - // Update canvas - ArrayList<Shape> shapeList = client.getDrawingController().getShapeList(); - ArrayList<Color> colorList = client.getDrawingController().getColorList(); - ArrayList<Integer> strokeSizeList = client.getDrawingController().getStrokeSizeList(); - - ArrayList<String> textList = client.getDrawingController().getTextList(); - ArrayList<Font> fontList = client.getDrawingController().getFontList(); - ArrayList<Point> textStartPointList = client.getDrawingController().getTextStartPointList(); +// try { +// // Update canvas +// ArrayList<Shape> shapeList = client.getDrawingController().getShapeList(); +// ArrayList<Color> colorList = client.getDrawingController().getColorList(); +// ArrayList<Integer> strokeSizeList = client.getDrawingController().getStrokeSizeList(); +// +// ArrayList<String> textList = client.getDrawingController().getTextList(); +// ArrayList<Font> fontList = client.getDrawingController().getFontList(); +// ArrayList<Point> textStartPointList = client.getDrawingController().getTextStartPointList(); - Graphics2D g2 = paintGUI.getDrawingArea().getG2(); +// Graphics2D g2 = paintGUI.getDrawingArea().getG2(); // for (int i = 0; i < textList.size(); i++) { // g2.setFont(fontList.get(i)); // g2.drawString(textList.get(i), textStartPointList.get(i).x, textStartPointList.get(i).y); // client.getApplicationMain().getPaintGUI().getDrawingArea().repaint(); // } - for (int i = 0; i < shapeList.size(); i++) { - g2.setStroke(new BasicStroke(strokeSizeList.get(i))); - g2.setColor(colorList.get(i)); - g2.draw(shapeList.get(i)); - paintGUI.getDrawingArea().repaint(); - } +// for (int i = 0; i < shapeList.size(); i++) { +// g2.setStroke(new BasicStroke(strokeSizeList.get(i))); +// g2.setColor(colorList.get(i)); +// g2.draw(shapeList.get(i)); +// paintGUI.getDrawingArea().repaint(); +// } +// } +// catch (RemoteException e) { +// e.printStackTrace(); +// } + + try { + client.getDrawingController().getImage(client.getUserName()); } - catch (RemoteException e) { - e.printStackTrace(); + catch (RemoteException err) { + err.printStackTrace(); } @@ -157,6 +164,7 @@ public class ApplicationMain extends JPanel { frame.setResizable(false); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); frame.pack(); + frame.setLocationRelativeTo(null); frame.setVisible(true); } diff --git a/src/GUI/ChatScreen.form b/src/GUI/ChatScreen.form index 93569264919847c10e94e94864226adb23ba7bf6..8628672c8b03ba53bb54ae10847a29458c98b80e 100644 --- a/src/GUI/ChatScreen.form +++ b/src/GUI/ChatScreen.form @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="GUI.ChatScreen"> - <grid id="27dc6" binding="panel2" layout-manager="GridLayoutManager" row-count="1" column-count="64" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="27dc6" binding="panel2" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <xy x="20" y="20" width="1627" height="1200"/> + <xy x="20" y="20" width="1200" height="1200"/> </constraints> <properties> <maximumSize width="-1" height="-1"/> @@ -12,172 +12,183 @@ </properties> <border type="none"/> <children> - <grid id="5d886" binding="chatPanel" layout-manager="GridLayoutManager" row-count="6" column-count="70" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="b37e3" binding="othersPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <grid row="0" column="0" row-span="1" col-span="63" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false"/> </constraints> <properties/> - <border type="none" title="Chat Area"/> + <border type="none"/> <children> - <component id="6a928" class="javax.swing.JLabel"> - <constraints> - <grid row="3" column="0" row-span="1" col-span="70" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="Your Message"/> - </properties> - </component> - <scrollpane id="ec60d"> + <grid id="bad73" binding="myAreaPanel" layout-manager="GridLayoutManager" row-count="11" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <grid row="0" column="1" row-span="1" col-span="68" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="7" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false"> + <preferred-size width="200" height="-1"/> + </grid> </constraints> <properties/> - <border type="none"/> + <border type="none" title="My Area"/> <children> - <component id="c55f3" class="javax.swing.JTextArea" binding="chatDisplayBox"> - <constraints/> + <component id="a35da" class="javax.swing.JLabel" binding="managersNameLabel"> + <constraints> + <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> <properties> - <editable value="false"/> - <lineWrap value="true"/> - <text value=""/> + <font size="14" style="1"/> + <text value="Manager's Name:"/> + </properties> + </component> + <vspacer id="38e19"> + <constraints> + <grid row="9" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> + </constraints> + </vspacer> + <component id="98bbe" class="javax.swing.JLabel" binding="yourNameLabel"> + <constraints> + <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <font size="14" style="1"/> + <text value="Your Name:"/> + </properties> + </component> + <component id="33d66" class="javax.swing.JLabel" binding="yourNameDisplay"> + <constraints> + <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <text value="Here goes User's Name"/> + </properties> + </component> + <grid id="4212" binding="managersPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <margin top="0" left="0" bottom="0" right="0"/> + <constraints> + <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + </constraints> + <properties/> + <border type="none" title="Manager's Tools"/> + <children> + <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> + <properties> + <model/> + </properties> + </component> + <vspacer id="aae38"> + <constraints> + <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> + </constraints> + </vspacer> + <component id="be5e9" class="javax.swing.JButton" binding="kickOutButton" default-binding="true"> + <constraints> + <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <text value="Kick Out"/> + </properties> + </component> + <component id="1336c" class="javax.swing.JButton" binding="promoteToManagerButton" default-binding="true"> + <constraints> + <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <text value="Promote to Manager"/> + </properties> + </component> + </children> + </grid> + <component id="51b56" class="javax.swing.JLabel" binding="managersNameDisplay"> + <constraints> + <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <text value="Here goes Admin's Name"/> + </properties> + </component> + <vspacer id="e9e96"> + <constraints> + <grid row="10" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> + </constraints> + </vspacer> + <component id="deaed" class="javax.swing.JButton" binding="exitThisRoomButton" default-binding="true"> + <constraints> + <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <text value="Exit This Room"/> </properties> </component> </children> - </scrollpane> - <component id="2b67f" class="javax.swing.JTextField" binding="chatInputBox"> + </grid> + <grid id="5d886" binding="chatPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <grid row="4" column="0" row-span="1" col-span="70" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> - <preferred-size width="150" height="-1"/> + <grid row="0" column="0" row-span="2" col-span="1" vsize-policy="7" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"> + <preferred-size width="300" height="-1"/> </grid> </constraints> <properties/> - </component> - <component id="df8f1" class="javax.swing.JLabel" binding="sendMessageToLabel"> - <constraints> - <grid row="1" column="0" row-span="1" col-span="70" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="Send Message To:"/> - </properties> - </component> - <component id="cc35d" class="javax.swing.JComboBox" binding="sendMessageToComboBox"> - <constraints> - <grid row="2" column="0" row-span="1" col-span="70" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/> - </constraints> - <properties/> - </component> - <component id="9e940" class="javax.swing.JButton" binding="sendButton"> - <constraints> - <grid row="5" column="22" row-span="1" col-span="21" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="Send"/> - </properties> - </component> - </children> - </grid> - <grid id="bad73" binding="myAreaPanel" layout-manager="GridLayoutManager" row-count="14" column-count="9" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> - <margin top="0" left="0" bottom="0" right="0"/> - <constraints> - <grid row="0" column="63" row-span="1" col-span="1" vsize-policy="7" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false"/> - </constraints> - <properties/> - <border type="none" title="My Area"/> - <children> - <component id="a35da" class="javax.swing.JLabel" binding="managersNameLabel"> - <constraints> - <grid row="3" column="0" row-span="1" col-span="9" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <font/> - <text value="Manager"/> - </properties> - </component> - <component id="98bbe" class="javax.swing.JLabel" binding="yourNameLabel"> - <constraints> - <grid row="1" column="0" row-span="1" col-span="9" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <font/> - <text value="Username"/> - </properties> - </component> - <component id="33d66" class="javax.swing.JLabel" binding="yourNameDisplay"> - <constraints> - <grid row="2" column="0" row-span="1" col-span="9" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <font style="1"/> - <text value="Here goes User's Name"/> - </properties> - </component> - <component id="51b56" class="javax.swing.JLabel" binding="managersNameDisplay"> - <constraints> - <grid row="4" column="0" row-span="1" col-span="9" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <font style="1"/> - <text value="Here goes Admin's Name"/> - </properties> - </component> - <vspacer id="e9e96"> - <constraints> - <grid row="13" column="0" row-span="1" col-span="9" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> - </constraints> - </vspacer> - <grid id="4212" binding="managersPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> - <margin top="0" left="0" bottom="0" right="0"/> - <constraints> - <grid row="7" column="0" row-span="6" col-span="9" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <enabled value="true"/> - </properties> - <border type="none" title="Manager's Tools"/> + <border type="none" title="Chat Area"/> <children> - <component id="b7068" class="javax.swing.JComboBox" binding="kickUserComboBox"> + <component id="6a928" class="javax.swing.JLabel"> <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"> - <preferred-size width="152" height="30"/> - </grid> + <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> - <enabled value="true"/> - <model/> + <text value="Your Message"/> </properties> </component> - <component id="be5e9" class="javax.swing.JButton" binding="kickOutButton" default-binding="true"> + <component id="9e940" class="javax.swing.JButton" binding="sendButton"> <constraints> - <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"> - <preferred-size width="152" height="30"/> - </grid> + <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/> </constraints> <properties> - <enabled value="true"/> - <text value="Kick Out"/> + <text value="Send"/> </properties> </component> - <component id="1336c" class="javax.swing.JButton" binding="promoteToManagerButton" default-binding="true"> + <scrollpane id="ec60d"> + <constraints> + <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + </constraints> + <properties/> + <border type="none"/> + <children> + <component id="c55f3" class="javax.swing.JTextArea" binding="chatDisplayBox"> + <constraints/> + <properties> + <editable value="false"/> + <lineWrap value="true"/> + </properties> + </component> + </children> + </scrollpane> + <component id="2b67f" class="javax.swing.JTextField" binding="chatInputBox"> <constraints> - <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"> - <preferred-size width="152" height="30"/> + <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> + <preferred-size width="150" height="-1"/> </grid> </constraints> + <properties/> + </component> + <component id="df8f1" class="javax.swing.JLabel" binding="sendMessageToLabel"> + <constraints> + <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> <properties> - <text value="Promote to Manager"/> + <text value="Send Message To:"/> </properties> </component> + <component id="cc35d" class="javax.swing.JComboBox" binding="sendMessageToComboBox"> + <constraints> + <grid row="2" 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> + <properties/> + </component> </children> </grid> - <component id="deaed" class="javax.swing.JButton" binding="exitThisRoomButton" default-binding="true"> - <constraints> - <grid row="0" column="0" row-span="1" col-span="9" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="Exit This Room"/> - </properties> - </component> </children> </grid> </children> diff --git a/src/GUI/DrawingArea.java b/src/GUI/DrawingArea.java index a5dfa87448243d06b8516b17802b3b51af883a64..c1f7a65306f82f3b6277cea4197b1e61cafe319e 100644 --- a/src/GUI/DrawingArea.java +++ b/src/GUI/DrawingArea.java @@ -52,16 +52,13 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis setBackground(Color.WHITE); // Set Background color setDoubleBuffered(false); // Non-buffered drawing image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB); - g2 = (Graphics2D) image.getGraphics(); - /// Antialiasing the graphic for smoothness /// - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); shapeColor = new Color(0, 0, 0); currentMode = Mode.FREEHAND; strokeSize = 3; lineStroke = new BasicStroke(strokeSize); eraserSize = 10; textSize = 60; - textString = "Enter text..."; + textString = "Text here."; drawing = null; addMouseListener(this); addMouseMotionListener(this); @@ -97,8 +94,6 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis public void clear() { image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB); - g2 = (Graphics2D) image.getGraphics(); - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); repaint(); } @@ -144,22 +139,6 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis } } -// public void saveFile() { -// try { -// ImageIO.write(image, "PNG", new File("Saved_White_Board.png")); -// } catch (IOException e) { -// e.printStackTrace(); -// } -// } - - public void saveAsFile(File file) { - try { - ImageIO.write(image, "PNG", file); - } catch (IOException e) { - e.printStackTrace(); - } - } - public void openFile(File file) { try { image = ImageIO.read(file); @@ -218,70 +197,6 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis eraserSize = size; } -// public void setColorAqua() { -// shapeColor = new Color(0,255, 255); -// } -// -// public void setColorBlack() { -// shapeColor = new Color(0, 0, 0); -// } -// -// public void setColorBlue() { -// shapeColor = new Color(0, 0, 255); -// } -// -// public void setColorFuchsia() { -// shapeColor = new Color(255, 0, 255); -// } -// -// public void setColorGray() { -// shapeColor = new Color(128, 128, 128); -// } -// -// public void setColorGreen() { -// shapeColor = new Color(0, 128, 0); -// } -// -// public void setColorLime() { -// shapeColor = new Color(0, 255, 0); -// } -// -// public void setColorMaroon() { -// shapeColor = new Color(128,0, 0); -// } -// -// public void setColorNavy() { -// shapeColor = new Color(0, 0, 128); -// } -// -// public void setColorOlive() { -// shapeColor = new Color(128, 128, 0); -// } -// -// public void setColorPurple() { -// shapeColor = new Color(128, 0, 128); -// } -// -// public void setColorRed() { -// shapeColor = new Color(255, 0, 0); -// } -// -// public void setColorSilver() { -// shapeColor = new Color(192, 192, 192); -// } -// -// public void setColorTeal() { -// shapeColor = new Color(0, 128, 128); -// } -// -// public void setColorWhite() { -// shapeColor = new Color(255, 255, 255); -// } -// -// public void setColorYellow() { -// shapeColor = new Color(255, 255, 0); -// } - @Override public void mouseClicked(MouseEvent e) { startPoint = e.getPoint(); @@ -298,12 +213,17 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis } catch (RemoteException ex) { ex.printStackTrace(); } + repaint(); + break; + default: break; } } @Override public void mousePressed(MouseEvent e) { + g2 = (Graphics2D) image.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); startPoint = previousPoint = e.getPoint(); /// Instantiate object based on current mode /// @@ -327,8 +247,8 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis drawing = new Rectangle2D.Double(); break; -// case TEXT: -// + case TEXT: + // g2.setFont(new Font("TimesRoman", Font.PLAIN, textSize)); // g2.drawString(textString, startPoint.x, startPoint.y); // try { @@ -336,6 +256,7 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis // } catch (RemoteException ex) { // ex.printStackTrace(); // } +// repaint(); // break; } } @@ -347,24 +268,18 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis case OVAL: case RECTANGLE: case CIRCLE: - - /// Abort drawing if 2D has no width or height /// - if (((RectangularShape) drawing).getWidth() == 0 || ((RectangularShape) drawing).getHeight() == 0) { - break; - } case FREEHAND: case LINE: - // Graphics2D g2 = (Graphics2D) image.getGraphics(); g2.setColor(shapeColor); - - /// Uncomment the line below to fill the shapes with color /// - // g2.fill(drawing); + // g2.fill(drawing); /// Uncomment the line to fill the shapes with color /// g2.setStroke(lineStroke); g2.draw(drawing); + break; + case TEXT: + case ERASE: + default: + break; } - - g2 = (Graphics2D) image.getGraphics(); - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setColor(shapeColor); /// This repaint is needed if we want to fill the drawing shape with color @@ -420,7 +335,7 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis /// Eraser is continuously drawing "small white circle" from current point to previous point /// case ERASE: - ((Ellipse2D) drawing).setFrame(currentPoint.getX(), currentPoint.getY(), 10, 10); + ((Ellipse2D) drawing).setFrame((currentPoint.getX() - (eraserSize / 2)), (currentPoint.getY() - (eraserSize / 2)), eraserSize, eraserSize); g2.setColor(Color.WHITE); g2.fill(drawing); g2.draw(drawing); @@ -449,7 +364,7 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis case TEXT: break; } - + g2.setStroke(lineStroke); repaint(); try { drawingController.broadcastDraggingDrawing(client.getUserName(), drawing, currentMode.toString(), shapeColor, strokeSize); diff --git a/src/GUI/MenuBar.java b/src/GUI/MenuBar.java deleted file mode 100644 index b466e4b9cbe917d1c2acd97dee35ef4d995acfd8..0000000000000000000000000000000000000000 --- a/src/GUI/MenuBar.java +++ /dev/null @@ -1,7 +0,0 @@ -package GUI; - -import javax.swing.*; - -public class MenuBar extends JMenuBar { - JButton clearBtn, newBtn, openBtn, saveBtn, saveAsBtn, closeBtn; -} diff --git a/src/GUI/PaintGUI.java b/src/GUI/PaintGUI.java index 0621a492813df01f10cc8e58bb1fbd89455cddcd..7f8e024d960bfaa3001f404bdae4ee55288b7ed0 100644 --- a/src/GUI/PaintGUI.java +++ b/src/GUI/PaintGUI.java @@ -1,6 +1,7 @@ package GUI; import client.Client; +import remote.IDrawingUpdate; import javax.imageio.ImageIO; import javax.swing.*; @@ -12,7 +13,10 @@ import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.IOException; +import java.rmi.RemoteException; public class PaintGUI extends JPanel { @@ -20,7 +24,7 @@ public class PaintGUI extends JPanel { DrawingArea drawingArea; String[] shapes = {"Freehand", "Line", "Circle", "Rectangle", "Oval", "Eraser", "Text"}; - String[] strokes = {"Small", "Medium", "Large"}; + String[] strokes = {"Thin", "Medium", "Thick"}; String[] eraserSizes = {"Small", "Medium", "Large"}; JFrame frame; JButton clearBtn, newBtn, openBtn, saveBtn, saveAsBtn; @@ -110,6 +114,7 @@ public class PaintGUI extends JPanel { textSize.setColumns(2); textSize.addFocusListener(focusListener); // textSize.setVisible(false); + setTextDetail(); /// Set up elements /// clearBtn = new JButton("Clear"); @@ -125,17 +130,17 @@ public class PaintGUI extends JPanel { /// Toolbox panel /// toolbox1.add(colorPaletteBtn); -// toolbox.add(setFontBtn); toolbox1.add(freehandBtn); toolbox1.add(lineBtn); toolbox1.add(circleBtn); toolbox1.add(rectBtn); toolbox1.add(ovalBtn); - toolbox1.add(eraserBtn); - toolbox1.add(textBtn); + toolbox1.add(strokeOptions); + toolbox2.add(textBtn); toolbox2.add(textInput); +// toolbox2.add(setFontBtn); toolbox2.add(textSize); - toolbox2.add(strokeOptions); + toolbox2.add(eraserBtn); toolbox2.add(eraserSizeOptions); toolbox2.add(clearBtn); @@ -165,7 +170,24 @@ public class PaintGUI extends JPanel { /// Clear button /// if (e.getSource() == clearBtn) { - drawingArea.clear(); + int reply = JOptionPane.showConfirmDialog(null, + "Are you sure you want to clear the canvas?", + "Canvas clearance", JOptionPane.YES_NO_OPTION); + + if( reply == JOptionPane.YES_OPTION ) + { + try + { + client.getDrawingController().broadcastClearCanvas(client.getUserName()); + } + catch (RemoteException err) + { + JOptionPane.showMessageDialog(null, + "Error in clearing the canvas", "Error", JOptionPane.ERROR_MESSAGE); + } + + drawingArea.clear(); + } /// Create new canvas /// } else if (e.getSource() == newBtn) { @@ -181,11 +203,32 @@ public class PaintGUI extends JPanel { file = new File(filePath); } + drawingArea.saveAsPNGFile(file); + + try + { + client.getDrawingController().broadcastClearCanvas(client.getUserName()); + } + catch (RemoteException err) + { + JOptionPane.showMessageDialog(null, + "Error in clearing the canvas", "Error", JOptionPane.ERROR_MESSAGE); + } + drawingArea.clear(); } else if (returnVal == JOptionPane.NO_OPTION) { + try + { + client.getDrawingController().broadcastClearCanvas(client.getUserName()); + } + catch (RemoteException err) + { + JOptionPane.showMessageDialog(null, + "Error in clearing the canvas", "Error", JOptionPane.ERROR_MESSAGE); + } drawingArea.clear(); } @@ -196,8 +239,37 @@ public class PaintGUI extends JPanel { if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fileChooser.getSelectedFile(); drawingArea.openFile(file); + + try + { + client.getDrawingController().broadcastClearCanvas(client.getUserName()); + } + catch (RemoteException err) + { + err.printStackTrace(); + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + javax.imageio.ImageIO.write(ImageIO.read(file), "png", baos); + baos.flush(); + baos.close(); + } + catch (IOException err) { + err.printStackTrace(); + } + + try { + if (client.getDrawingController().updateImage(baos.toByteArray())) { + client.getDrawingController().broadcastUpdateImage(client.getUserName()); + } + } catch (RemoteException ex) { + ex.printStackTrace(); + } } + + /// Save under project directory without filename (PNG file with default filename) /// } else if (e.getSource() == saveBtn) { @@ -261,13 +333,13 @@ public class PaintGUI extends JPanel { String strokeChosen = (String) strokeOptions.getSelectedItem(); switch (strokeChosen) { - case "Small": + case "Thin": drawingArea.setStroke(3); break; case "Medium": drawingArea.setStroke(6); break; - case "Large": + case "Thick": drawingArea.setStroke(10); break; } @@ -342,19 +414,4 @@ public class PaintGUI extends JPanel { drawingArea.setModeText(textString, size); } - - - -// public void showGUI() { -// frame = new JFrame("Shared Whiteboard System"); -// JFrame.setDefaultLookAndFeelDecorated(true); -// frame.setContentPane(global); -// -// frame.setSize(800, 600); -// frame.setLocationRelativeTo( null ); -// frame.setResizable(false); -// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); -// frame.setVisible(true); -// } - } \ No newline at end of file diff --git a/src/GUI/StartScreen.form b/src/GUI/StartScreen.form index f266275f5779005b91d96dc1a9134323e557dfdb..f348817e1243275dfd3dd145b7bc1983957c0624 100644 --- a/src/GUI/StartScreen.form +++ b/src/GUI/StartScreen.form @@ -11,10 +11,12 @@ <grid id="abaca" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"> + <preferred-size width="100" height="70"/> + </grid> </constraints> <properties/> - <border type="none"/> + <border type="none" title=" "/> <children> <hspacer id="53fe0"> <constraints> @@ -23,52 +25,37 @@ </hspacer> <component id="ebca9" class="javax.swing.JLabel"> <constraints> - <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> + <font name="Apple SD Gothic Neo" size="20"/> <text value="Distributed Whiteboard App"/> </properties> </component> - <component id="d60e2" class="javax.swing.JTextArea" binding="information"> + <component id="e3c91" class="javax.swing.JTextPane" binding="information"> <constraints> <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"> - <preferred-size width="150" height="50"/> + <preferred-size width="150" height="70"/> </grid> </constraints> <properties> <editable value="false"/> - <text value="Welcome, please provide server's IP to connect to and nameto be identified by in the Whiteboard's chat."/> + <text value="Please provide your username and password, as well as server's IP to start."/> </properties> </component> </children> </grid> - <grid id="790e1" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="790e1" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/> </constraints> <properties/> <border type="none"/> <children> - <component id="87b91" class="javax.swing.JLabel"> - <constraints> - <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="Your name:"/> - </properties> - </component> - <component id="e39f4" class="javax.swing.JTextField" binding="textField1" default-binding="true"> - <constraints> - <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> - <preferred-size width="150" height="-1"/> - </grid> - </constraints> - <properties/> - </component> <component id="ea0c1" class="javax.swing.JButton" binding="joinButton"> <constraints> - <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/> + <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/> </constraints> <properties> <text value="JOIN WHITEBOARD"/> @@ -76,30 +63,33 @@ </component> </children> </grid> - <grid id="6ef31" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="6ef31" layout-manager="GridLayoutManager" row-count="4" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/> </constraints> - <properties/> - <border type="none"/> + <properties> + <name value=""/> + <requestFocusEnabled value="false"/> + </properties> + <border type="none" title=" "/> <children> - <hspacer id="23c9f"> + <vspacer id="bb71b"> <constraints> - <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> + <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> </constraints> - </hspacer> + </vspacer> <component id="94078" class="javax.swing.JLabel"> <constraints> - <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> <text value="Server IP:"/> </properties> </component> - <component id="63209" class="javax.swing.JTextField" binding="textField2"> + <component id="63209" class="javax.swing.JTextField" binding="serverField"> <constraints> - <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> + <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> <preferred-size width="150" height="-1"/> </grid> </constraints> @@ -107,6 +97,40 @@ <text value=""/> </properties> </component> + <component id="87b91" class="javax.swing.JLabel"> + <constraints> + <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <text value="Username:"/> + </properties> + </component> + <component id="e39f4" class="javax.swing.JTextField" binding="usernameField"> + <constraints> + <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> + <preferred-size width="150" height="-1"/> + </grid> + </constraints> + <properties/> + </component> + <component id="62e48" class="javax.swing.JLabel"> + <constraints> + <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <text value="Password:"/> + </properties> + </component> + <component id="51d9f" class="javax.swing.JPasswordField" binding="passwordField"> + <constraints> + <grid row="1" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> + <preferred-size width="150" height="-1"/> + </grid> + </constraints> + <properties> + <columns value="20"/> + </properties> + </component> </children> </grid> </children> diff --git a/src/GUI/StartScreen.java b/src/GUI/StartScreen.java index 8b09ec33810041f2efc6da4477713c1d61c21d46..6b6a4b53bfb7466916b97ed4f06073b92d3c927c 100644 --- a/src/GUI/StartScreen.java +++ b/src/GUI/StartScreen.java @@ -2,19 +2,31 @@ package GUI; import client.Client; +import javax.imageio.ImageIO; import javax.swing.*; import java.awt.event.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; + public class StartScreen { + private JTextPane information; private JPanel panel1; - private JTextArea information; - private JTextField textField1; + private JTextField usernameField; private JButton joinButton; + private JTextField textField2; private boolean kickedOut; private boolean appTerminated; + private JTextField serverField; + private JTextField textField3; + private JPasswordField passwordField; + JFrame frame; private Client client; @@ -30,10 +42,11 @@ public class StartScreen { { if (e.getSource() == joinButton) { - String serverAddress = textField2.getText(); - String userName = textField1.getText(); + String serverAddress = serverField.getText(); + String userName = usernameField.getText(); + String password = new String(passwordField.getPassword()); - int connectionStatus = client.connect(userName, serverAddress); + int connectionStatus = client.connect(userName, serverAddress, password); if( connectionStatus == 1 ) { @@ -49,15 +62,19 @@ public class StartScreen { } } - else if( connectionStatus == 2 || connectionStatus == 5 ) + else if( connectionStatus == 2 || connectionStatus == 6 ) { - showErrorMessage("Duplicate username: Please enter a new username"); + showErrorMessage("Duplicate usernameField: Please enter a new usernameField"); } else if( connectionStatus == 3 ) { showErrorMessage("Cannot connect to server: Please check the server address"); } else if( connectionStatus == 4 ) + { + showErrorMessage("Incorrect Password"); + } + else if( connectionStatus == 5 ) { frame.setVisible(false); frame.dispose(); @@ -87,6 +104,11 @@ public class StartScreen { frame.setContentPane(panel1); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); + frame.setLocationRelativeTo(null); + frame.getRootPane().setDefaultButton(joinButton); + joinButton.requestFocus(); + + //frame.getContentPane().add(new JPanelWithBackground("sample.jpeg")); frame.setVisible(true); frame.addWindowListener(new WindowAdapter() { @@ -125,4 +147,26 @@ public class StartScreen { "The manager terminated the application", "Application terminated", JOptionPane.ERROR_MESSAGE); } + +// public class JPanelWithBackground extends JPanel +// { +// +// private Image backgroundImage; +// +// // Some code to initialize the background image. +// // Here, we use the constructor to load the image. This +// // can vary depending on the use case of the panel. +// public JPanelWithBackground(String fileName) throws IOException +// { +// backgroundImage = ImageIO.read(new File(fileName)); +// } +// +// public void paintComponent(Graphics g) { +// super.paintComponent(g); +// +// // Draw the background image. +// g.drawImage(backgroundImage, 0, 0, this); +// } +// } + } diff --git a/src/GUI/ToolBar.java b/src/GUI/ToolBar.java deleted file mode 100644 index 04087e80db705c26881b58bcde46bfead77687d7..0000000000000000000000000000000000000000 --- a/src/GUI/ToolBar.java +++ /dev/null @@ -1,100 +0,0 @@ -package GUI; - -import javax.swing.*; -import java.awt.*; - -public class ToolBar extends JPanel { - private DrawingArea drawingArea; - - public ToolBar() { - - } -} - -class Tools extends JPanel { - -} - -class ColorPallete extends JPanel { - private Color color; - - public ColorPallete() { - this.color = new Color(0, 0, 0); // Black - } - - public void setColor(Color color) { - this.color = color; - } - - public void setColorRBG(int r, int b, int g) { - this.color = new Color(r, b, g); - } - - public Color getColor() { - return this.color; - } - - public void setColorAqua() { - this.color = new Color(0,255, 255); - } - - public void setColorBlack() { - this.color = new Color(0, 0, 0); - } - - public void setColorBlue() { - this.color = new Color(0, 0, 255); - } - - public void setColorFuchsia() { - this.color = new Color(255, 0, 255); - } - - public void setColorGray() { - this.color = new Color(128, 128, 128); - } - - public void setColorGreen() { - this.color = new Color(0, 128, 0); - } - - public void setColorLime() { - this.color = new Color(0, 255, 0); - } - - public void setColorMaroon() { - this.color = new Color(128,0, 0); - } - - public void setColorNavy() { - this.color = new Color(0, 0, 128); - } - - public void setColorOlive() { - this.color = new Color(128, 128, 0); - } - - public void setColorPurple() { - this.color = new Color(128, 0, 128); - } - - public void setColorRed() { - this.color = new Color(255, 0, 0); - } - - public void setColorSilver() { - this.color = new Color(192, 192, 192); - } - - public void setColorTeal() { - this.color = new Color(0, 128, 128); - } - - public void setColorWhite() { - this.color = new Color(255, 255, 255); - } - - public void setColorYellow() { - this.color = new Color(255, 255, 0); - } -} \ No newline at end of file diff --git a/src/client/Client.java b/src/client/Client.java index a3b23c6b153ee5a0cc1f0fb4d65936b65b80e846..a241d3301ac316466caf8ef33262d6f07ac28a1f 100644 --- a/src/client/Client.java +++ b/src/client/Client.java @@ -11,11 +11,14 @@ import remote.IDrawingController; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; public class Client { private final String DEFAULT_USERNAME = "Anonymous"; private final String DEFAULT_SERVER_ADDRESS = "localhost"; + private final EncryptionUpdate encryptionUpdate; private String defaultUserName; private String userName; @@ -29,9 +32,8 @@ public class Client private ClientUpdate clientUpdate; private ChatUpdate chatUpdate; private DrawingUpdate drawingUpdate; - + private ApplicationMain applicationMain; private StartScreen startScreen; - private PaintGUI paintGUI; public String getUserName() @@ -59,14 +61,9 @@ public class Client this.serverAddress = serverAddress; } - private ApplicationMain applicationMain; public ApplicationMain getApplicationMain() { return applicationMain; } - public PaintGUI getPaintGUI() { - return paintGUI; - } - public ChatScreen getChatScreen() { return getApplicationMain().getChatScreen(); } @@ -88,7 +85,7 @@ public class Client } - public Client(String username) throws RemoteException + public Client(String username) throws RemoteException, NoSuchProviderException, NoSuchAlgorithmException { this.defaultUserName = username; this.clientUpdate = new ClientUpdate(this); @@ -96,6 +93,7 @@ public class Client this.drawingUpdate = new DrawingUpdate(this); this.startScreen = new StartScreen(this); this.applicationMain = new ApplicationMain(this); + this.encryptionUpdate = new EncryptionUpdate(); } public static void main(String[] args) @@ -108,6 +106,7 @@ public class Client catch (Exception e) { StartScreen.showErrorMessage("Error starting up client"); + System.exit(0); } } @@ -135,9 +134,10 @@ public class Client // return = 1 -> connected successfully // return = 2 -> duplicate username // return = 3 -> error in locating the server - // return = 4 -> re-connected successfully - // return = 5 -> duplicate username when re-connecting - public int connect(String userName, String serverAddress) + // return = 4 -> incorrect password entered + // return = 5 -> re-connected successfully + // return = 6 -> duplicate username when re-connecting + public int connect(String userName, String serverAddress, String password) { try { @@ -151,13 +151,26 @@ public class Client if (registryServer != null && getUserName().equals(userName) && getServerAddress().equals(serverAddress) && getApplicationMain().getFrame() != null) { + System.out.println("Server address:" + getServerAddress()); System.out.println("User name:" + getUserName()); - if (clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate)) { - System.out.println("Connected to server"); + System.out.println("Password: " + password); + + if( clientController.checkPassword(password) ) + { + if (clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate, this.encryptionUpdate)) + { + System.out.println("Connected to server"); + return 5; + } + else + { + return 6; + } + } + else + { return 4; - } else { - return 5; } } // New connection @@ -172,13 +185,25 @@ public class Client drawingController = (IDrawingController) registryServer.lookup("DrawingController"); System.out.println("User name:" + getUserName()); - - if (clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate)) { - System.out.println("Connected to server"); - return 1; - } else { - return 2; + System.out.println("Password: " + password); + + if( clientController.checkPassword(password) ) + { + if (clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate, this.encryptionUpdate)) + { + System.out.println("Connected to server"); + return 1; + } + else + { + return 2; + } } + else + { + return 4; + } + } } catch (Exception e) diff --git a/src/client/ClientUpdate.java b/src/client/ClientUpdate.java index 89c77fe7f7360b989e4c34a376a4d82fc88ae7b1..860a34b829d1685b3150a8394c9137e14b61eeb5 100644 --- a/src/client/ClientUpdate.java +++ b/src/client/ClientUpdate.java @@ -41,18 +41,14 @@ public class ClientUpdate extends UnicastRemoteObject implements IClientUpdate, { 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()) ) diff --git a/src/client/DrawingUpdate.java b/src/client/DrawingUpdate.java index 59f39d947853d9edde1add1c7c901959875ebe14..68c8f9ae6c6b685aa99eca6a0ee64b4bf61bd230 100644 --- a/src/client/DrawingUpdate.java +++ b/src/client/DrawingUpdate.java @@ -4,6 +4,9 @@ import GUI.DrawingArea; import remote.IDrawingUpdate; import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.Serializable; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; @@ -19,9 +22,9 @@ public class DrawingUpdate extends UnicastRemoteObject implements IDrawingUpdate @Override public boolean notifyTextDrawing(String fromClient, String text, Font font, Point startPoint) throws RemoteException { - Graphics2D g2 = client.getApplicationMain().getPaintGUI().getDrawingArea().getG2(); - g2.setFont(font); - g2.drawString(text, startPoint.x, startPoint.y); + client.getApplicationMain().getPaintGUI().getDrawingArea().getG2().setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + client.getApplicationMain().getPaintGUI().getDrawingArea().getG2().setFont(font); + client.getApplicationMain().getPaintGUI().getDrawingArea().getG2().drawString(text, startPoint.x, startPoint.y); client.getApplicationMain().getPaintGUI().getDrawingArea().repaint(); return true; } @@ -70,4 +73,26 @@ public class DrawingUpdate extends UnicastRemoteObject implements IDrawingUpdate client.getApplicationMain().getPaintGUI().getDrawingArea().repaint(); return true; } + + public boolean notifyCanvasClearance(String fromClient) throws RemoteException { + client.getApplicationMain().getPaintGUI().getDrawingArea().clear(); + return true; + } + + public boolean receiveImage(byte[] rawImage) throws RemoteException { + try { +// BufferedImage bufferedImage = client.getApplicationMain().getPaintGUI().getDrawingArea().getImage(); + BufferedImage bufferedImage = javax.imageio.ImageIO.read(new ByteArrayInputStream(rawImage)); + client.getApplicationMain().getPaintGUI().getDrawingArea().setImage(bufferedImage); + client.getApplicationMain().getPaintGUI().getDrawingArea().setG2((Graphics2D) bufferedImage.getGraphics()); + client.getApplicationMain().getPaintGUI().getDrawingArea().getG2().setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + client.getApplicationMain().getPaintGUI().getDrawingArea().repaint(); + + // do whatever you wish with the image + } + catch (IOException err) { + err.printStackTrace(); + } + return true; + } } diff --git a/src/client/EncryptionUpdate.java b/src/client/EncryptionUpdate.java new file mode 100644 index 0000000000000000000000000000000000000000..001c1295c64d042cba748e108675cbe14f3a4503 --- /dev/null +++ b/src/client/EncryptionUpdate.java @@ -0,0 +1,58 @@ +package client; + +import remote.IDrawingUpdate; +import remote.IEncryptionUpdate; + +import javax.crypto.*; +import javax.crypto.spec.SecretKeySpec; +import java.io.Serializable; +import java.rmi.RemoteException; +import java.rmi.server.UnicastRemoteObject; +import java.security.*; + +public class EncryptionUpdate extends UnicastRemoteObject implements IEncryptionUpdate, Serializable { + + private PrivateKey priv; + private PublicKey pub; + private SecretKey sharedSecretKey; + + public PublicKey getPub() { + return pub; + } + + public void setSharedKey(byte[] encryptedSharedSecretKey){ + try { + Cipher cipher = Cipher.getInstance("RSA", "SunJCE"); + cipher.init(Cipher.DECRYPT_MODE, priv); + sharedSecretKey = new SecretKeySpec(cipher.doFinal(encryptedSharedSecretKey), "AES"); + System.out.println("Client holds this shared key: "+sharedSecretKey); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (NoSuchProviderException e) { + e.printStackTrace(); + } catch (NoSuchPaddingException | InvalidKeyException e) { + e.printStackTrace(); + } catch (BadPaddingException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } + + + } + + EncryptionUpdate() throws RemoteException { + try { + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "SunJSSE"); + keyGen.initialize(2048); + KeyPair pair = keyGen.generateKeyPair(); + this.priv = pair.getPrivate(); + this.pub = pair.getPublic(); + + } + catch (Exception e){ + e.printStackTrace(); + } + + } +} diff --git a/src/client/client.policy b/src/client/client.policy new file mode 100644 index 0000000000000000000000000000000000000000..a8f141af97047fdcc681f3d85b1eee1afa8372c4 --- /dev/null +++ b/src/client/client.policy @@ -0,0 +1,3 @@ +grant { + permission java.net.SocketPermission "10.13.64.162", "accept,connect"; +}; diff --git a/src/remote/IClientController.java b/src/remote/IClientController.java index 27fc06bfdc0cd939c9fbf59af87cbbf18938a376..a8b583f54c6e13d9bf60c7450dab34118ae8045b 100644 --- a/src/remote/IClientController.java +++ b/src/remote/IClientController.java @@ -7,7 +7,7 @@ public interface IClientController extends Remote { enum Action {KICKOUT, ASSIGNADMIN, KICKALL}; - boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing) throws RemoteException; + boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing, IEncryptionUpdate encryptionUpdate) throws RemoteException; void quit(String username) throws RemoteException; @@ -20,4 +20,6 @@ public interface IClientController extends Remote void kickAll(String manager) throws RemoteException; String getAdmin() throws RemoteException; + + boolean checkPassword(String password) throws RemoteException; } diff --git a/src/remote/IDrawingController.java b/src/remote/IDrawingController.java index e39d8ecfa95ea62e865a94a6e3c3cf8edac78347..be96a215a69686225e4db0ecfc69958a25396b33 100644 --- a/src/remote/IDrawingController.java +++ b/src/remote/IDrawingController.java @@ -1,10 +1,8 @@ package remote; import java.awt.*; -import java.awt.image.BufferedImage; import java.rmi.Remote; import java.rmi.RemoteException; -import java.util.ArrayList; /** @@ -20,13 +18,8 @@ public interface IDrawingController extends Remote { boolean broadcastText(String fromClient, String text, Font font, Point startPoint) throws RemoteException; boolean broadcastDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException; boolean broadcastDraggingDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException; - ArrayList<Shape> getShapeList() throws RemoteException; - ArrayList<Color> getColorList() throws RemoteException; - ArrayList<Integer> getStrokeSizeList() throws RemoteException; - - ArrayList<String> getTextList() throws RemoteException; - ArrayList<Font> getFontList() throws RemoteException; - ArrayList<Point> getTextStartPointList() throws RemoteException; -// BufferedImage getCurrentImage() throws RemoteException; - + boolean broadcastClearCanvas(String fromClient) throws RemoteException; + boolean broadcastUpdateImage(String fromClient) throws RemoteException; + boolean updateImage(byte[] rawImage) throws RemoteException; + void getImage(String fromClient) throws RemoteException; } diff --git a/src/remote/IDrawingUpdate.java b/src/remote/IDrawingUpdate.java index 27f73ccfb04917f7a20189f40b6e6762bbc9465f..02f17f1e685503799e74e2ca9f3f7d26bdff404d 100644 --- a/src/remote/IDrawingUpdate.java +++ b/src/remote/IDrawingUpdate.java @@ -9,4 +9,6 @@ public interface IDrawingUpdate extends Remote, Serializable { boolean notifyTextDrawing(String fromClient, String text, Font font, Point startPoint) throws RemoteException; boolean notifyDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException; boolean notifyDraggingDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException; + boolean notifyCanvasClearance(String fromClient) throws RemoteException; + boolean receiveImage(byte[] rawImage) throws RemoteException; } diff --git a/src/remote/IEncryptionUpdate.java b/src/remote/IEncryptionUpdate.java new file mode 100644 index 0000000000000000000000000000000000000000..3e8edf3e781713db3d351e740c5a692aab733925 --- /dev/null +++ b/src/remote/IEncryptionUpdate.java @@ -0,0 +1,10 @@ +package remote; + +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.security.PublicKey; + +public interface IEncryptionUpdate extends Remote { + public PublicKey getPub() throws RemoteException; + public void setSharedKey(byte[] encryptedSharedSecretKey) throws RemoteException; +} diff --git a/src/server/ClientController.java b/src/server/ClientController.java index 392e6a725cdc381253ee5c1e4463c287c0c9ef7b..6ff46e6e94e5dc7a6cc1d986ced4ff7866e9181f 100644 --- a/src/server/ClientController.java +++ b/src/server/ClientController.java @@ -1,9 +1,6 @@ package server; -import remote.IChatUpdate; -import remote.IClientUpdate; -import remote.IDrawingUpdate; -import remote.IClientController; +import remote.*; import java.io.Serializable; import java.rmi.Remote; @@ -20,7 +17,7 @@ public class ClientController extends UnicastRemoteObject implements IClientCont } @Override - public boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing) throws RemoteException + public boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing, IEncryptionUpdate encryptionUpdate) throws RemoteException { System.out.println("I am in join"); if( getUserIndex(username) < 0 ) @@ -28,6 +25,8 @@ public class ClientController extends UnicastRemoteObject implements IClientCont // user with same username is not connected server.chatController.broadcastMessageUserLogin(username); + new MySharedKey(encryptionUpdate); + User newUser = new User(username, clientChat, clientUpdate, clientDrawing); server.users.add(newUser); @@ -62,7 +61,6 @@ public class ClientController extends UnicastRemoteObject implements IClientCont broadcastUserList(); } } - } // for debuggins purposes @@ -71,7 +69,7 @@ public class ClientController extends UnicastRemoteObject implements IClientCont System.out.print("Currently connected users: "); for( User u : server.users ) { - System.out.print(u.getUserName()); + System.out.print(u.getUserName() + " "); } System.out.println(); } @@ -105,7 +103,8 @@ public class ClientController extends UnicastRemoteObject implements IClientCont if ( adminIndex >= 0 && userIndex >= 0 && server.users.get(adminIndex).isAdmin() ) { - try { + try + { server.users.get(userIndex).getIClientUpdate().terminateChat(); } finally { @@ -208,19 +207,33 @@ public class ClientController extends UnicastRemoteObject implements IClientCont IClientUpdate client; String toClient; - if ( server.users.get(adminIndex).isAdmin() ) - { - for( User u : server.users ) - { + if (server.users.get(adminIndex).isAdmin()) { + for (User u : server.users) { client = u.getIClientUpdate(); toClient = u.getUserName(); client.notifyManagerActions(toClient, remote.IClientUpdate.Action.KICKALL); } server.users.clear(); - } - else { + } else { System.out.println("You are not the manager"); } + } + + public boolean checkPassword(String password) + { + if( server.users.size() == 0 ) + { + server.setPassword(password); + return true; + } + else if( server.getPassword().equals(password) ) + { + return true; + } + else + { + return false; + } } } diff --git a/src/server/DrawingController.java b/src/server/DrawingController.java index da53d58f1248a09b7a6d712843c79aa809a3f712..00d42fc5e09937a1e7d587f062ad4e7221218754 100644 --- a/src/server/DrawingController.java +++ b/src/server/DrawingController.java @@ -3,57 +3,43 @@ package server; import remote.IDrawingController; import remote.IDrawingUpdate; -import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.reflect.Array; +import java.io.*; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; -import java.util.ArrayList; public class DrawingController extends UnicastRemoteObject implements IDrawingController { private final static int AREA_WIDTH = 600; - private final static int AREA_HEIGHT = 620; + private final static int AREA_HEIGHT = 600; private Server server; private BufferedImage bufferedImage; private Graphics2D g2; - private ArrayList<Shape> shapeList; - private ArrayList<Color> colorList; - private ArrayList<Integer> strokeSizeList; - - private ArrayList<String> textList; - private ArrayList<Font> fontList; - private ArrayList<Point> textStartPointList; - protected DrawingController(Server server) throws RemoteException { this.server = server; + this.bufferedImage = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB); g2 = (Graphics2D) bufferedImage.getGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - this.shapeList = new ArrayList<Shape>(); - this.colorList = new ArrayList<Color>(); - this.strokeSizeList = new ArrayList<Integer>(); - this.textList = new ArrayList<String>(); - this.fontList = new ArrayList<Font>(); - this.textStartPointList = new ArrayList<Point>(); } @Override public boolean broadcastText(String fromClient, String text, Font font, Point startPoint) throws RemoteException { System.out.print("Broadcasting drawing to everyone..."); - textList.add(text); - fontList.add(font); - textStartPointList.add(startPoint); + g2 = (Graphics2D) bufferedImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setFont(font); +// g2.setPaint(Color.BLACK); + g2.drawString(text, startPoint.x, startPoint.y); + g2 = (Graphics2D) bufferedImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + IDrawingUpdate client; @@ -75,9 +61,27 @@ public class DrawingController extends UnicastRemoteObject implements IDrawingCo public boolean broadcastDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException { System.out.print("Broadcasting drawing to everyone..."); - shapeList.add(drawing); - colorList.add(color); - strokeSizeList.add(strokeSize); + g2 = (Graphics2D) bufferedImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + switch (mode) { + case "OVAL": + case "RECTANGLE": + case "CIRCLE": + case "FREEHAND": + case "LINE": + g2.setColor(color); + // g2.fill(drawing); /// Uncomment the line to fill the shapes with color /// + g2.setStroke(new BasicStroke(strokeSize)); + g2.draw(drawing); + break; + case "TEXT": + case "ERASE": + default: + break; + } + + g2 = (Graphics2D) bufferedImage.getGraphics(); + g2.setColor(color); IDrawingUpdate client; @@ -97,12 +101,28 @@ public class DrawingController extends UnicastRemoteObject implements IDrawingCo public boolean broadcastDraggingDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException { System.out.print("Broadcasting dragging drawing to everyone..."); - if (mode.equals("FREEHAND")) { - shapeList.add(drawing); - colorList.add(color); - strokeSizeList.add(strokeSize); + g2 = (Graphics2D) bufferedImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + switch (mode) { + case "FREEHAND": + g2.setColor(color); + g2.setStroke(new BasicStroke(strokeSize)); + g2.draw(drawing); + break; + + case "ERASE": + g2.setColor(Color.WHITE); + g2.fill(drawing); + g2.draw(drawing); + break; + + default: + break; } + g2 = (Graphics2D) bufferedImage.getGraphics(); + g2.setColor(color); + IDrawingUpdate client; for( User u : server.users ) @@ -118,31 +138,97 @@ public class DrawingController extends UnicastRemoteObject implements IDrawingCo return true; } -// public ImageCanvas getCurrentImage() { -// return image; -// } + public boolean broadcastClearCanvas(String fromClient) throws RemoteException { + System.out.print("Broadcasting canvas clearance to everyone..."); - public ArrayList<Shape> getShapeList() { - return shapeList; - } + IDrawingUpdate client; - public ArrayList<Color> getColorList() { - return colorList; - } + bufferedImage = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB); + g2 = (Graphics2D) bufferedImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - public ArrayList<Integer> getStrokeSizeList() { - return strokeSizeList; + for( User u : server.users ) + { + if (!u.getUserName().equals(fromClient)) { + client = u.getIDrawingUpdate(); + client.notifyCanvasClearance(fromClient); + } + } + + System.out.print("...DONE\n"); + + return true; } - public ArrayList<String> getTextList() { - return textList; + + public boolean broadcastUpdateImage(String fromClient) throws RemoteException { + System.out.print("Broadcasting new image loading to everyone..."); + + try { + + // do whatever you wish with the image + IDrawingUpdate client; + + for( User u : server.users ) + { + if (!u.getUserName().equals(fromClient)) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + client = u.getIDrawingUpdate(); + try { + javax.imageio.ImageIO.write(bufferedImage, "png", baos); + baos.flush(); + client.receiveImage(baos.toByteArray()); + } + catch (IOException err) { + err.printStackTrace(); + } + baos.close(); + } + } + } + catch (IOException err) { + err.printStackTrace(); + } + + System.out.print("...DONE\n"); + + return true; } - public ArrayList<Font> getFontList() { - return fontList; + public boolean updateImage(byte[] rawImage) throws RemoteException { + try { + bufferedImage = ImageIO.read(new ByteArrayInputStream(rawImage)); + g2 = (Graphics2D) bufferedImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.drawImage(bufferedImage, null, 0, 0); + } + catch (IOException err) { + err.printStackTrace(); + } + return true; } - public ArrayList<Point> getTextStartPointList() { - return textStartPointList; + public void getImage(String fromClient) throws RemoteException { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + IDrawingUpdate client; + + try { + javax.imageio.ImageIO.write(bufferedImage, "png", baos); + baos.flush(); + baos.close(); + } + catch (IOException err) { + err.printStackTrace(); + } + + for( User u : server.users ) + { + if (u.getUserName().equals(fromClient)) { + client = u.getIDrawingUpdate(); + client.receiveImage(baos.toByteArray()); + } + } } } diff --git a/src/server/MySharedKey.java b/src/server/MySharedKey.java new file mode 100644 index 0000000000000000000000000000000000000000..e16485e2e87a5ff48c8ea4bd2bfe05757dc7802f --- /dev/null +++ b/src/server/MySharedKey.java @@ -0,0 +1,41 @@ +package server; + +import remote.IEncryptionUpdate; + +import javax.crypto.*; +import javax.crypto.spec.SecretKeySpec; +import java.rmi.RemoteException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.util.Base64; + +public class MySharedKey { + private byte[] encryptedSharedSecretKey; + private IEncryptionUpdate encryptionUpdate; + private SecretKey sharedSecretKey; + + + public MySharedKey (IEncryptionUpdate encryptionUpdate) throws RemoteException { + this.encryptionUpdate = encryptionUpdate; + this.sharedSecretKey = new SecretKeySpec(new byte[16], "AES"); + System.out.println(sharedSecretKey); + this.encryptedSharedSecretKey = wrapKey(encryptionUpdate.getPub()); + System.out.println("Shared key on server:" + encryptedSharedSecretKey); + encryptionUpdate.setSharedKey(encryptedSharedSecretKey); + } + + private byte[] wrapKey(PublicKey clientPubKey){ + + try { + Cipher c = Cipher.getInstance("RSA", "SunJCE"); + c.init(Cipher.WRAP_MODE, clientPubKey); + byte[] result2 = c.wrap(sharedSecretKey); + return result2; + } catch (Exception e) { + e.printStackTrace(); + throw new IllegalStateException( + e); + } + } +} diff --git a/src/server/Server.java b/src/server/Server.java index 65842248bec9de49f36f79a9e29c9e2eface21a3..1063d88fb21da8e2cd3ea5078816e9dff18712e8 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -4,9 +4,15 @@ import remote.IChatController; import remote.IClientController; import remote.IDrawingController; +import javax.naming.NamingEnumeration; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.UnknownHostException; +import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; +import java.rmi.server.UnicastRemoteObject; import java.util.ArrayList; public class Server @@ -17,14 +23,27 @@ public class Server protected ChatController chatController; protected DrawingController drawingController; + private String password; + public Server() throws RemoteException { + password = null; users = new ArrayList<User>(); clientController = new ClientController(this); chatController = new ChatController(this); drawingController = new DrawingController(this); } + protected void setPassword(String password) + { + this.password = password; + } + + protected String getPassword() + { + return password; + } + public static void main(String[] args) { try @@ -41,22 +60,56 @@ public class Server public void run() throws RemoteException { - LocateRegistry.createRegistry(1099); Registry registry = LocateRegistry.getRegistry(); +// if (System.getSecurityManager() == null) { +// System.setSecurityManager(new SecurityManager()); +// } +// System.setProperty("java.security.policy", "file:/Users/haiho/OneDrive - The University of Melbourne/Distributed Systems (COMP90015)/Assignment 2/InfinityMonkeys-remaster/comp90015-dsass2-infinitymonkeys-remaster/src/server/server.policy"); String clientControllerName = "ClientController"; String chatControllerName = "ChatController"; String drawingControllerName = "DrawingController"; - IClientController clientController = new ClientController(this); - IChatController chatController = new ChatController(this); - IDrawingController drawingController = new DrawingController(this); + IClientController clientController = this.clientController; + IChatController chatController = this.chatController; + IDrawingController drawingController = this.drawingController; registry.rebind(clientControllerName, clientController); registry.rebind(chatControllerName, chatController); registry.rebind(drawingControllerName, drawingController); +// registry.rebind(clientControllerName, UnicastRemoteObject.exportObject(clientController, 1099)); +// registry.rebind(chatControllerName, UnicastRemoteObject.exportObject(chatController, 1099)); +// registry.rebind(drawingControllerName, UnicastRemoteObject.exportObject(drawingController, 1099)); + +// try { +// Naming.rebind(clientControllerName, clientController); +// Naming.rebind(chatControllerName, chatController); +// Naming.rebind(drawingControllerName, drawingController); +// } catch (MalformedURLException e) { +// e.printStackTrace(); +// } + System.out.println("Server is ready"); + + printIP(); + } + + private void printIP() + { + InetAddress inetAddress = null; + + try + { + inetAddress = InetAddress.getLocalHost(); + } + catch (UnknownHostException e) + { + e.printStackTrace(); + } + + System.out.println("IP Address:- " + inetAddress.getHostAddress()); + System.out.println("Host Name:- " + inetAddress.getHostName()); } } diff --git a/src/server/server.policy b/src/server/server.policy new file mode 100644 index 0000000000000000000000000000000000000000..5c059491c631fa37d14fc62d9654cdb13ce184c0 --- /dev/null +++ b/src/server/server.policy @@ -0,0 +1,3 @@ +grant codeBase "file:/Users/haiho/OneDrive - The University of Melbourne/Distributed Systems (COMP90015)/Assignment 2/InfinityMonkeys-remaster/comp90015-dsass2-infinitymonkeys-remaster/out/production/comp90015-dsass2-infinitymonkeys-remaster/" { + permission java.security.AllPermission; +}; \ No newline at end of file