diff --git a/src/GUI/ApplicationMain.java b/src/GUI/ApplicationMain.java index f58583c786fdc49d256d02afc788c81f773f9f06..32275b92f8dece89d30856904b4cab47a776d11d 100644 --- a/src/GUI/ApplicationMain.java +++ b/src/GUI/ApplicationMain.java @@ -7,6 +7,7 @@ import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.rmi.RemoteException; +import java.util.ArrayList; public class ApplicationMain extends JPanel { private Client client; @@ -38,6 +39,36 @@ public class ApplicationMain extends JPanel { content.add(chatScreen.panel2, BorderLayout.EAST); 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(); + + 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(); + } + } + catch (RemoteException e) { + e.printStackTrace(); + } + + SwingUtilities.getRootPane(chatScreen.getSendButton()).setDefaultButton(chatScreen.getSendButton()); frame.addWindowListener(new WindowAdapter() { @@ -62,18 +93,13 @@ public class ApplicationMain extends JPanel { System.exit(0); } - - if( reply == JOptionPane.NO_OPTION ) - { - //do nothing - } } }); frame.setSize(1200, 700); frame.setLocationRelativeTo( null ); frame.setResizable(false); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); frame.pack(); frame.setVisible(true); } diff --git a/src/GUI/ChatScreen.form b/src/GUI/ChatScreen.form index d33374440b768c016d7fb477525ab8432cac3f01..fc19ecab3953bc99aa5416516e99b31508b22226 100644 --- a/src/GUI/ChatScreen.form +++ b/src/GUI/ChatScreen.form @@ -8,7 +8,7 @@ <properties> <maximumSize width="-1" height="-1"/> <minimumSize width="-1" height="-1"/> - <preferredSize width="700" height="600"/> + <preferredSize width="500" height="600"/> </properties> <border type="none"/> <children> @@ -20,7 +20,7 @@ <properties/> <border type="none"/> <children> - <grid id="bad73" binding="myAreaPanel" layout-manager="GridLayoutManager" row-count="12" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <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="1" vsize-policy="7" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false"/> @@ -30,7 +30,7 @@ <children> <component id="a35da" class="javax.swing.JLabel" binding="managersNameLabel"> <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"/> + <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> <font size="14" style="1"/> @@ -39,12 +39,12 @@ </component> <vspacer id="38e19"> <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"/> + <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="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"/> + <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"/> @@ -53,7 +53,7 @@ </component> <component id="33d66" class="javax.swing.JLabel" binding="yourNameDisplay"> <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"/> + <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"/> @@ -62,7 +62,7 @@ <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="6" 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="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"/> @@ -100,7 +100,7 @@ </grid> <component id="51b56" class="javax.swing.JLabel" binding="managersNameDisplay"> <constraints> - <grid row="5" 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="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"/> @@ -108,7 +108,7 @@ </component> <vspacer id="e9e96"> <constraints> - <grid row="11" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> + <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"> @@ -119,14 +119,6 @@ <text value="Exit This Room"/> </properties> </component> - <component id="bd8ec" class="javax.swing.JButton" binding="quitButton"> - <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="Quit Program"/> - </properties> - </component> </children> </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"> @@ -163,7 +155,7 @@ <component id="c55f3" class="javax.swing.JTextArea" binding="chatDisplayBox"> <constraints/> <properties> - <editable value="true"/> + <editable value="false"/> <lineWrap value="true"/> </properties> </component> diff --git a/src/GUI/ChatScreen.java b/src/GUI/ChatScreen.java index b36a1a53b732ce6027fb4fc3de3dec9c97b63ee4..1c70a5f1b6933fae7b920b0039b8e4af9dc4639a 100644 --- a/src/GUI/ChatScreen.java +++ b/src/GUI/ChatScreen.java @@ -30,7 +30,6 @@ public class ChatScreen { private JPanel managersPanel; private JPanel chatPanel; private JButton exitThisRoomButton; - private JButton quitButton; private JFrame frame; public Client getClient() { @@ -44,7 +43,6 @@ public class ChatScreen { this.client = client; yourNameDisplay.setText(client.getUserName()); exitThisRoomButton.addActionListener(actionListener); - quitButton.addActionListener(actionListener); sendButton.addActionListener(actionListener); kickOutButton.addActionListener(actionListener); promoteToManagerButton.addActionListener(actionListener); diff --git a/src/GUI/DrawingArea.java b/src/GUI/DrawingArea.java index 21069490ac09b3a85c3eb35b876440ee928f206a..a5dfa87448243d06b8516b17802b3b51af883a64 100644 --- a/src/GUI/DrawingArea.java +++ b/src/GUI/DrawingArea.java @@ -6,9 +6,7 @@ import remote.IDrawingController; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; +import java.awt.event.*; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; @@ -16,38 +14,38 @@ import java.awt.geom.RectangularShape; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.io.Serializable; import java.rmi.RemoteException; -public class DrawingArea extends JPanel implements MouseMotionListener, MouseListener { - - +public class DrawingArea extends JPanel implements MouseMotionListener, MouseListener, Serializable { /// enum for all different mode /// - enum Mode { FREEHAND, LINE, CIRCLE, RECTANGLE, OVAL, ERASE } + enum Mode { FREEHAND, LINE, CIRCLE, RECTANGLE, OVAL, ERASE, TEXT } /// Canvas size parameter /// private final static int AREA_WIDTH = 600; - private final static int AREA_HEIGHT = 620; + private final static int AREA_HEIGHT = 600; /// Shape to be drawn on the canvas /// private Client client; - private Shape drawing; - private Point startPoint; private Point previousPoint; - private Point currentPoint; - /// Default mode and color /// - private Color shapeColor;// = new Color(0, 0, 0); - - private Mode currentMode;// = Mode.FREEHAND; - /// Create a empty canvas /// - private BufferedImage image;// = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB); - - /// Drawing tool - private Graphics2D g2;// = (Graphics2D) image.getGraphics(); + /// Default mode and color /// + private Mode currentMode; + private Color shapeColor; + private Stroke lineStroke; + private int strokeSize; + private int eraserSize; + private int textSize; + private String textString; + + /// Create a empty canvas // + private BufferedImage image; + private Graphics2D g2; + private Shape drawing; public DrawingArea(Client client) { this.client = client; @@ -59,12 +57,16 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis 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..."; drawing = null; addMouseListener(this); addMouseMotionListener(this); } - public Shape getDrawing() { return drawing; } @@ -73,6 +75,16 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis this.drawing = drawing; } + public Graphics2D getG2() { return g2; } + + + public void setG2(Graphics2D g2) { this.g2 = g2; } + + + public BufferedImage getImage() { return image; } + + public void setImage(BufferedImage image) { this.image = image; } + @Override public Dimension getPreferredSize() @@ -108,24 +120,38 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis Color borderColor = currentMode != Mode.ERASE ? shapeColor : Color.WHITE; g2.setColor(borderColor); g2.draw(drawing); - IDrawingController drawingController = client.getDrawingController(); - try { - drawingController.broadcastDrawing(client.getUserName(), drawing); - } catch (RemoteException ex) { - ex.printStackTrace(); - } } } /// File manipulations (PNG only) /// - public void saveFile() { + + public void saveAsPNGFile(File file) { try { - ImageIO.write(image, "PNG", new File("Saved_White_Board.png")); + ImageIO.write(image, "PNG", file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void saveAsJPGFile(File file) { + + BufferedImage imageJPG = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB); + imageJPG.createGraphics().drawImage(image, 0, 0, Color.WHITE, null); + try { + ImageIO.write(imageJPG, "JPG", file); } catch (IOException e) { e.printStackTrace(); } } +// 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); @@ -169,75 +195,111 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis currentMode = Mode.ERASE; } -/// Drawing color setters /// - - 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 setModeText(String string, int size) { + currentMode = Mode.TEXT; + textString = string; + textSize = size; } - 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); - } +/// Drawing color setters /// - public void setColorYellow() { - shapeColor = new Color(255, 255, 0); - } + public void setColor(Color color) { + shapeColor = color; + } + +/// Drawing stroke setter /// + + public void setStroke(int size) { + strokeSize = size; + lineStroke = new BasicStroke(strokeSize); + } + + public void setEraserSize(int size) { + 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(); + +/// Instantiate object based on current mode /// + switch (currentMode) { + case TEXT: + + g2.setFont(new Font("TimesRoman", Font.PLAIN, textSize)); + g2.drawString(textString, startPoint.x, startPoint.y); + try { + client.getDrawingController().broadcastText(client.getUserName(), textString, g2.getFont(), startPoint); + } catch (RemoteException ex) { + ex.printStackTrace(); + } + break; + } } @Override @@ -264,27 +326,40 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis drawing = new Rectangle2D.Double(); break; + +// case TEXT: +// +// g2.setFont(new Font("TimesRoman", Font.PLAIN, textSize)); +// g2.drawString(textString, startPoint.x, startPoint.y); +// try { +// client.getDrawingController().broadcastText(client.getUserName(), textString, g2.getFont(), startPoint); +// } catch (RemoteException ex) { +// ex.printStackTrace(); +// } +// break; } } @Override public void mouseReleased(MouseEvent e) { + IDrawingController drawingController = client.getDrawingController(); switch (currentMode) { case OVAL: case RECTANGLE: case CIRCLE: -/// Abort drawing if 2D has no width or height /// + /// 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(); + // Graphics2D g2 = (Graphics2D) image.getGraphics(); g2.setColor(shapeColor); -/// Uncomment the line below to fill the shapes with color /// -// g2.fill(drawing); + /// Uncomment the line below to fill the shapes with color /// + // g2.fill(drawing); + g2.setStroke(lineStroke); g2.draw(drawing); } @@ -292,9 +367,15 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis 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 + /// This repaint is needed if we want to fill the drawing shape with color repaint(); + try { + drawingController.broadcastDrawing(client.getUserName(), drawing, currentMode.toString(), shapeColor, strokeSize); + } catch (RemoteException ex) { + ex.printStackTrace(); + } + drawing = null; } @@ -310,8 +391,9 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis @Override public void mouseDragged(MouseEvent e) { - currentPoint = e.getPoint(); + IDrawingController drawingController = client.getDrawingController(); + currentPoint = e.getPoint(); int x = Math.min(startPoint.x, e.getX()); int y = Math.min(startPoint.y, e.getY()); int width = Math.abs(startPoint.x - e.getX()); @@ -324,6 +406,7 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis ((Line2D) drawing).setLine(currentPoint, previousPoint); g2.setColor(shapeColor); + g2.setStroke(lineStroke); g2.draw(drawing); previousPoint = currentPoint; break; @@ -362,9 +445,17 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis ((Rectangle2D) drawing).setFrame(x, y, width, height); break; + + case TEXT: + break; } repaint(); + try { + drawingController.broadcastDraggingDrawing(client.getUserName(), drawing, currentMode.toString(), shapeColor, strokeSize); + } catch (RemoteException ex) { + ex.printStackTrace(); + } } @Override diff --git a/src/GUI/PaintGUI.java b/src/GUI/PaintGUI.java index 40a63589b23c67847eade7ad28d6ae306516d3fd..0621a492813df01f10cc8e58bb1fbd89455cddcd 100644 --- a/src/GUI/PaintGUI.java +++ b/src/GUI/PaintGUI.java @@ -2,29 +2,43 @@ package GUI; import client.Client; +import javax.imageio.ImageIO; import javax.swing.*; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.image.BufferedImage; import java.io.File; public class PaintGUI extends JPanel { Client client; + DrawingArea drawingArea; - String[] shapes = {"Freehand", "Line", "Circle", "Rectangle", "Oval", "Eraser"}; - String[] colors = {"Aqua", "Black", "Blue", "Fuchsia", "Gray", "Green", "Lime", "Maroon", "Navy", "Olive", "Purple", "Red", "Silver", "Teal", "White", "Yellow"}; + String[] shapes = {"Freehand", "Line", "Circle", "Rectangle", "Oval", "Eraser", "Text"}; + String[] strokes = {"Small", "Medium", "Large"}; + String[] eraserSizes = {"Small", "Medium", "Large"}; JFrame frame; - JButton clearBtn, newBtn, openBtn, saveBtn, saveAsBtn, closeBtn; - JComboBox colorOptions; - JComboBox shapeOptions; - DrawingArea drawingArea; + JButton clearBtn, newBtn, openBtn, saveBtn, saveAsBtn; + JButton freehandBtn, lineBtn, circleBtn, rectBtn, ovalBtn, eraserBtn, textBtn; + JButton colorPaletteBtn, setFontBtn; + JTextField textInput, textSize; + JComboBox strokeOptions; + JComboBox eraserSizeOptions; + String filePath = ""; + Color currentColor = Color.BLACK; JPanel global = new JPanel(); - JFileChooser fileChooser= new JFileChooser(); JPanel toolbox = new JPanel(); + JPanel toolbox1 = new JPanel(); + JPanel toolbox2 = new JPanel(); JPanel fileControl = new JPanel(); + JFileChooser fileChooser= new JFileChooser(); /// GUI setup /// public PaintGUI(Client client) { @@ -33,16 +47,71 @@ public class PaintGUI extends JPanel { /// Main drawing area /// drawingArea = new DrawingArea(client); +// drawingArea.setPreferredSize(new Dimension(600, 620)); /// Set up main frame and container /// global.setLayout(new BorderLayout()); + toolbox.setLayout(new BorderLayout()); + + /// Set up button icons /// + try { + String path = System.getProperty("user.dir"); + System.out.println(path); + File palettePic = new File(path + "/src/GUI/icon/palette.png"); + File freehandPic = new File(path + "/src/GUI/icon/freehand.png"); + File linePic = new File(path + "/src/GUI/icon/line.png"); + File circlePic = new File(path + "/src/GUI/icon/circle.png"); + File rectPic = new File(path + "/src/GUI/icon/rectangle.png"); + File ovalPic = new File(path + "/src/GUI/icon/oval.png"); + File eraserPic = new File(path + "/src/GUI/icon/eraser.png"); + File textPic = new File(path + "/src/GUI/icon/text.png"); + BufferedImage paletteIcon = ImageIO.read(palettePic); + BufferedImage freehandIcon = ImageIO.read(freehandPic); + BufferedImage lineIcon = ImageIO.read(linePic); + BufferedImage circleIcon = ImageIO.read(circlePic); + BufferedImage rectIcon = ImageIO.read(rectPic); + BufferedImage ovalIcon = ImageIO.read(ovalPic); + BufferedImage eraserIcon = ImageIO.read(eraserPic); + BufferedImage textIcon = ImageIO.read(textPic); + colorPaletteBtn = new JButton(new ImageIcon(paletteIcon)); + colorPaletteBtn.addActionListener(actionListener); + freehandBtn = new JButton(new ImageIcon(freehandIcon)); + freehandBtn.addActionListener(actionListener); + lineBtn = new JButton(new ImageIcon(lineIcon)); + lineBtn.addActionListener(actionListener); + circleBtn = new JButton(new ImageIcon(circleIcon)); + circleBtn.addActionListener(actionListener); + rectBtn = new JButton(new ImageIcon(rectIcon)); + rectBtn.addActionListener(actionListener); + ovalBtn = new JButton(new ImageIcon(ovalIcon)); + ovalBtn.addActionListener(actionListener); + eraserBtn = new JButton(new ImageIcon(eraserIcon)); + eraserBtn.addActionListener(actionListener); + textBtn = new JButton(new ImageIcon(textIcon)); + textBtn.addActionListener(actionListener); + } catch (Exception e) { + e.printStackTrace(); + } + + strokeOptions = new JComboBox(strokes); + strokeOptions.setSelectedItem("Small"); + strokeOptions.addActionListener(actionListener); + eraserSizeOptions = new JComboBox(eraserSizes); + eraserSizeOptions.setSelectedItem("Small"); + eraserSizeOptions.addActionListener(actionListener); + + // setFontBtn = new JButton("Font"); +// setFontBtn.addActionListener(actionListener); + textInput = new JTextField("Text here."); + textInput.setColumns(8); + textInput.addFocusListener(focusListener); +// textInput.setVisible(false); + textSize = new JTextField("12"); + textSize.setColumns(2); + textSize.addFocusListener(focusListener); +// textSize.setVisible(false); /// Set up elements /// - shapeOptions = new JComboBox(shapes); - shapeOptions.addActionListener(actionListener); - colorOptions = new JComboBox(colors); - colorOptions.setSelectedItem("Black"); - colorOptions.addActionListener(actionListener); clearBtn = new JButton("Clear"); clearBtn.addActionListener(actionListener); newBtn = new JButton("New"); @@ -53,22 +122,32 @@ public class PaintGUI extends JPanel { saveBtn.addActionListener(actionListener); saveAsBtn = new JButton("Save As"); saveAsBtn.addActionListener(actionListener); - closeBtn = new JButton("Close"); - closeBtn.addActionListener(actionListener); /// Toolbox panel /// - toolbox.add(colorOptions); - toolbox.add(shapeOptions); - toolbox.add(clearBtn); + 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); + toolbox2.add(textInput); + toolbox2.add(textSize); + toolbox2.add(strokeOptions); + toolbox2.add(eraserSizeOptions); + toolbox2.add(clearBtn); /// File control panel /// fileControl.add(newBtn); fileControl.add(openBtn); fileControl.add(saveBtn); fileControl.add(saveAsBtn); - fileControl.add(closeBtn); /// Layout /// + toolbox.add(toolbox1, BorderLayout.NORTH); + toolbox.add(toolbox2, BorderLayout.SOUTH); global.add(fileControl, BorderLayout.NORTH); global.add(drawingArea); global.add(toolbox, BorderLayout.SOUTH); @@ -78,6 +157,8 @@ public class PaintGUI extends JPanel { return global; } + public DrawingArea getDrawingArea() { return drawingArea; } + ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -88,10 +169,19 @@ public class PaintGUI extends JPanel { /// Create new canvas /// } else if (e.getSource() == newBtn) { + File file; + int returnVal = JOptionPane.showConfirmDialog(new JFrame(), "Save your current whiteboard?", "Save or Discard", JOptionPane.YES_NO_CANCEL_OPTION); if (returnVal == JOptionPane.YES_OPTION) { - drawingArea.saveFile(); + if (filePath.isEmpty()) { + file = chooseSaveFile(); + + } else { + file = new File(filePath); + + } + drawingArea.saveAsPNGFile(file); drawingArea.clear(); } else if (returnVal == JOptionPane.NO_OPTION) { @@ -110,123 +200,161 @@ public class PaintGUI extends JPanel { /// Save under project directory without filename (PNG file with default filename) /// } else if (e.getSource() == saveBtn) { - drawingArea.saveFile(); + + File file; + + if (filePath.isEmpty()) { + file = chooseSaveFile(); + } else { + file = new File(filePath); + + } + if (file != null) { + if (filePath.endsWith(".jpg")) { + drawingArea.saveAsJPGFile(file); + } else if (filePath.endsWith(".png")) { + drawingArea.saveAsPNGFile(file); + } + } /// Save with other filename (PNG only) /// } else if (e.getSource() == saveAsBtn) { - fileChooser = new JFileChooser(); - int returnVal = fileChooser.showSaveDialog(frame); - if (returnVal == JFileChooser.APPROVE_OPTION) { - File file = fileChooser.getSelectedFile(); - drawingArea.saveAsFile(file); - } -/// Close application /// - } else if (e.getSource() == closeBtn) { - System.exit(0); + File file = chooseSaveFile(); + + if (file != null) { + if (filePath.endsWith(".jpg")) { + drawingArea.saveAsJPGFile(file); + } else if (filePath.endsWith(".png")) { + drawingArea.saveAsPNGFile(file); + } + } /// Choose drawing color /// - } else if (e.getSource() == colorOptions) { + } else if (e.getSource() == colorPaletteBtn) { + drawingArea.setColor(JColorChooser.showDialog(null, "Choose a Color", currentColor)); - String colorChosen = (String) colorOptions.getSelectedItem(); +/// Choose drawing tool /// + } else if (e.getSource() == freehandBtn) { + drawingArea.setModeFreehand(); - switch (colorChosen){ - case "Aqua": - drawingArea.setColorAqua(); - break; - case "Black": - drawingArea.setColorBlack(); - break; - case "Blue": - drawingArea.setColorBlue(); - break; - case "Fuchsia": - drawingArea.setColorFuchsia(); - break; - case "Gray": - drawingArea.setColorGray(); - break; - case "Green": - drawingArea.setColorGreen(); - break; - case "Lime": - drawingArea.setColorLime(); - break; - case "Maroon": - drawingArea.setColorMaroon(); - break; - case "Navy": - drawingArea.setColorNavy(); - break; - case "Olive": - drawingArea.setColorOlive(); - break; - case "Purple": - drawingArea.setColorPurple(); - break; - case "Red": - drawingArea.setColorRed(); - break; - case "Silver": - drawingArea.setColorSilver(); - break; - case "Teal": - drawingArea.setColorTeal(); - break; - case "White": - drawingArea.setColorWhite(); - break; - case "Yellow": - drawingArea.setColorYellow(); - break; - } + } else if (e.getSource() == lineBtn) { + drawingArea.setModeLine(); -/// Choose drawing tool /// - } else if (e.getSource() == shapeOptions) { + } else if (e.getSource() == circleBtn) { + drawingArea.setModeCircle(); + + } else if (e.getSource() == rectBtn) { + drawingArea.setModeRectangle(); + + } else if (e.getSource() == ovalBtn) { + drawingArea.setModeOval(); + + } else if (e.getSource() == eraserBtn) { + drawingArea.setModeErase(); - String shapeChosen = (String) shapeOptions.getSelectedItem(); + } else if (e.getSource() == textBtn) { + // textInput.setVisible(true); + // textSize.setVisible(true); + setTextDetail(); + } else if (e.getSource() == strokeOptions) { + String strokeChosen = (String) strokeOptions.getSelectedItem(); - switch (shapeChosen){ - case "Freehand": - drawingArea.setModeFreehand(); + switch (strokeChosen) { + case "Small": + drawingArea.setStroke(3); break; - case "Line": - drawingArea.setModeLine(); + case "Medium": + drawingArea.setStroke(6); break; - case "Circle": - drawingArea.setModeCircle(); + case "Large": + drawingArea.setStroke(10); break; - case "Rectangle": - drawingArea.setModeRectangle(); + } + + } else if (e.getSource() == eraserSizeOptions) { + String eraserSizeChosen = (String) eraserSizeOptions.getSelectedItem(); + + switch (eraserSizeChosen) { + case "Small": + drawingArea.setEraserSize(10); break; - case "Oval": - drawingArea.setModeOval(); + case "Medium": + drawingArea.setEraserSize(20); break; - case "Eraser": - drawingArea.setModeErase(); + case "Large": + drawingArea.setEraserSize(30); break; } } } }; - public DrawingArea getDrawingArea() { - return drawingArea; - } + FocusListener focusListener = new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + setTextDetail(); + } + @Override + public void focusLost(FocusEvent e) { + setTextDetail(); + } + }; + + private File chooseSaveFile() { + + fileChooser = new JFileChooser(); + FileFilter png = new FileNameExtensionFilter("PNG format", "png"); + FileFilter jpg = new FileNameExtensionFilter("JPG format", "jpg"); + fileChooser.addChoosableFileFilter(png); + fileChooser.addChoosableFileFilter(jpg); + fileChooser.setFileFilter(png); + int returnVal = fileChooser.showSaveDialog(frame); + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fileChooser.getSelectedFile(); + filePath = file.getAbsolutePath(); + + if (fileChooser.getFileFilter().getDescription().equals("JPG format")) { + if (!filePath.toLowerCase().endsWith(".jpg")) { + filePath = filePath + ".jpg"; + file = new File(file + ".jpg"); + } + return file; + } else { + if (!filePath.toLowerCase().endsWith(".png")) { + filePath = filePath + ".png"; + file = new File(file + ".png"); + } + return file; + } + } else { + return null; + } + } - public void showGUI() { - frame = new JFrame("Shared Whiteboard System"); - JFrame.setDefaultLookAndFeelDecorated(true); - frame.setContentPane(global); + private void setTextDetail() { + String textString = textInput.getText(); + int size = Integer.parseInt(textSize.getText()); - frame.setSize(800, 600); - frame.setLocationRelativeTo( null ); - frame.setResizable(false); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setVisible(true); + 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/icon/circle.png b/src/GUI/icon/circle.png new file mode 100644 index 0000000000000000000000000000000000000000..0c23e5a725c3b9d87d0765641e401184be837d24 Binary files /dev/null and b/src/GUI/icon/circle.png differ diff --git a/src/GUI/icon/eraser.png b/src/GUI/icon/eraser.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d98df4ca4a1a677baaf83a00fbc903f814119c Binary files /dev/null and b/src/GUI/icon/eraser.png differ diff --git a/src/GUI/icon/freehand.png b/src/GUI/icon/freehand.png new file mode 100644 index 0000000000000000000000000000000000000000..5d162ecd975889c2ff84b0b3e456a4d4115eb82f Binary files /dev/null and b/src/GUI/icon/freehand.png differ diff --git a/src/GUI/icon/line.png b/src/GUI/icon/line.png new file mode 100644 index 0000000000000000000000000000000000000000..31156130a58ec6c455be88f00e470329cba61afd Binary files /dev/null and b/src/GUI/icon/line.png differ diff --git a/src/GUI/icon/oval.png b/src/GUI/icon/oval.png new file mode 100644 index 0000000000000000000000000000000000000000..665c0a0c7c3b1eaa4ba51e6baa6c150f651f8b5f Binary files /dev/null and b/src/GUI/icon/oval.png differ diff --git a/src/GUI/icon/palette.png b/src/GUI/icon/palette.png new file mode 100644 index 0000000000000000000000000000000000000000..813d7ffbe98d40089591256979bd1f21514abdc9 Binary files /dev/null and b/src/GUI/icon/palette.png differ diff --git a/src/GUI/icon/rectangle.png b/src/GUI/icon/rectangle.png new file mode 100644 index 0000000000000000000000000000000000000000..94d8278acf49ff157270cc81e0967334936611ec Binary files /dev/null and b/src/GUI/icon/rectangle.png differ diff --git a/src/GUI/icon/square.png b/src/GUI/icon/square.png new file mode 100644 index 0000000000000000000000000000000000000000..38657f5a2779b68ecab7d083e8c112b879bf77bc Binary files /dev/null and b/src/GUI/icon/square.png differ diff --git a/src/GUI/icon/text.png b/src/GUI/icon/text.png new file mode 100644 index 0000000000000000000000000000000000000000..33af1a2708cee9b502580ce4b6380c3a1d8740c8 Binary files /dev/null and b/src/GUI/icon/text.png differ diff --git a/src/client/DrawingUpdate.java b/src/client/DrawingUpdate.java index 4b41c0285681b1674f9b35cc61336ca6d4451426..59f39d947853d9edde1add1c7c901959875ebe14 100644 --- a/src/client/DrawingUpdate.java +++ b/src/client/DrawingUpdate.java @@ -18,12 +18,56 @@ public class DrawingUpdate extends UnicastRemoteObject implements IDrawingUpdate } @Override - public boolean notifyDrawing(String fromClient, Shape drawing) throws RemoteException { - client.getApplicationMain().getPaintGUI().getDrawingArea().setDrawing(drawing); + 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().repaint(); -// DrawingArea drawingArea = (DrawingArea) client.getChatScreen().getDrawingPanel().getComponent(1); -// drawingArea.setDrawing(drawing); -// drawingArea.repaint(); - return false; + return true; + } + + @Override + public boolean notifyDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException { + Graphics2D g2 = client.getApplicationMain().getPaintGUI().getDrawingArea().getG2(); + switch (mode) { + case "OVAL": + case "RECTANGLE": + case "CIRCLE": + case "FREEHAND": + case "LINE": + g2.setColor(color); + g2.setStroke(new BasicStroke(strokeSize)); + g2.draw(drawing); + break; + default: + System.out.println("Erased"); + } + g2 = (Graphics2D) client.getApplicationMain().getPaintGUI().getDrawingArea().getImage().getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setColor(color); + client.getApplicationMain().getPaintGUI().getDrawingArea().repaint(); + return true; + } + + public boolean notifyDraggingDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException { + Graphics2D g2 = client.getApplicationMain().getPaintGUI().getDrawingArea().getG2(); + 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; + } + client.getApplicationMain().getPaintGUI().getDrawingArea().repaint(); + return true; } } diff --git a/src/remote/IDrawingController.java b/src/remote/IDrawingController.java index 145cc49619dcab3c25de449b706221fff56ecab6..e39d8ecfa95ea62e865a94a6e3c3cf8edac78347 100644 --- a/src/remote/IDrawingController.java +++ b/src/remote/IDrawingController.java @@ -1,8 +1,10 @@ package remote; import java.awt.*; +import java.awt.image.BufferedImage; import java.rmi.Remote; import java.rmi.RemoteException; +import java.util.ArrayList; /** @@ -15,7 +17,16 @@ import java.rmi.RemoteException; */ public interface IDrawingController extends Remote { - boolean broadcastDrawing(String fromClient, Shape drawing) throws RemoteException; + 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; } diff --git a/src/remote/IDrawingUpdate.java b/src/remote/IDrawingUpdate.java index 3df14ff51b7f3bbb41069b15f36ea23627699439..27f73ccfb04917f7a20189f40b6e6762bbc9465f 100644 --- a/src/remote/IDrawingUpdate.java +++ b/src/remote/IDrawingUpdate.java @@ -6,5 +6,7 @@ import java.rmi.Remote; import java.rmi.RemoteException; public interface IDrawingUpdate extends Remote, Serializable { - boolean notifyDrawing(String fromClient, Shape drawing) throws RemoteException; + 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; } diff --git a/src/server/DrawingController.java b/src/server/DrawingController.java index 1471e8a38a33c3fc1d496f36ffa306ad0f0a1888..da53d58f1248a09b7a6d712843c79aa809a3f712 100644 --- a/src/server/DrawingController.java +++ b/src/server/DrawingController.java @@ -3,32 +3,146 @@ 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.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 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 broadcastDrawing(String fromClient, Shape drawing) throws RemoteException { + 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); + IDrawingUpdate client; for( User u : server.users ) { - client = u.getIDrawingUpdate(); - client.notifyDrawing(fromClient, drawing); + if (!u.getUserName().equals(fromClient)) { + client = u.getIDrawingUpdate(); + client.notifyTextDrawing(fromClient, text, font, startPoint); + } } System.out.print("...DONE\n"); return true; } -} \ No newline at end of file + + + @Override + 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); + + IDrawingUpdate client; + + for( User u : server.users ) + { + if (!u.getUserName().equals(fromClient)) { + client = u.getIDrawingUpdate(); + client.notifyDrawing(fromClient, drawing, mode, color, strokeSize); + } + } + + System.out.print("...DONE\n"); + + return true; + } + + 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); + } + + IDrawingUpdate client; + + for( User u : server.users ) + { + if (!u.getUserName().equals(fromClient)) { + client = u.getIDrawingUpdate(); + client.notifyDraggingDrawing(fromClient, drawing, mode, color, strokeSize); + } + } + + System.out.print("...DONE\n"); + + return true; + } + +// public ImageCanvas getCurrentImage() { +// return image; +// } + + public ArrayList<Shape> getShapeList() { + return shapeList; + } + + public ArrayList<Color> getColorList() { + return colorList; + } + + public ArrayList<Integer> getStrokeSizeList() { + return strokeSizeList; + } + + public ArrayList<String> getTextList() { + return textList; + } + + public ArrayList<Font> getFontList() { + return fontList; + } + + public ArrayList<Point> getTextStartPointList() { + return textStartPointList; + } +}