aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator
diff options
context:
space:
mode:
authorYana Stamcheva <yana@jitsi.org>2007-11-28 10:58:56 +0000
committerYana Stamcheva <yana@jitsi.org>2007-11-28 10:58:56 +0000
commit0dc7be20d2a6522e19e24229857edc2d93a4b1d9 (patch)
treeafec949f1263b95db236993562db4985303315a3 /src/net/java/sip/communicator
parentadfe51be7cf6c0b5dc84a42660b13bc07b89b136 (diff)
downloadjitsi-0dc7be20d2a6522e19e24229857edc2d93a4b1d9.zip
jitsi-0dc7be20d2a6522e19e24229857edc2d93a4b1d9.tar.gz
jitsi-0dc7be20d2a6522e19e24229857edc2d93a4b1d9.tar.bz2
whiteboard plugin
Diffstat (limited to 'src/net/java/sip/communicator')
-rw-r--r--src/net/java/sip/communicator/plugin/whiteboard/gui/InvitationReceivedDialog.java175
-rw-r--r--src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFileFilter.java91
-rw-r--r--src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFrame.java2480
-rw-r--r--src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardPanel.java296
4 files changed, 3042 insertions, 0 deletions
diff --git a/src/net/java/sip/communicator/plugin/whiteboard/gui/InvitationReceivedDialog.java b/src/net/java/sip/communicator/plugin/whiteboard/gui/InvitationReceivedDialog.java
new file mode 100644
index 0000000..a706d9b
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/whiteboard/gui/InvitationReceivedDialog.java
@@ -0,0 +1,175 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.plugin.whiteboard.gui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.plugin.whiteboard.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The dialog that pops up when a chat room invitation is received.
+ *
+ * @author Yana Stamcheva
+ */
+public class InvitationReceivedDialog
+ extends JDialog
+ implements ActionListener
+{
+ private JTextArea infoTextArea = new JTextArea();
+
+ private JTextArea invitationReasonTextArea = new JTextArea();
+
+ private JPanel reasonPanel = new JPanel(new BorderLayout());
+
+ private JLabel reasonLabel = new JLabel(
+ Resources.getString("reason") + ": ");
+
+ private JTextField reasonField = new JTextField();
+
+ private JPanel dataPanel = new JPanel(new BorderLayout(10, 10));
+
+ private JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+
+ private JButton acceptButton = new JButton(Resources.getString("accept"));
+
+ private JButton rejectButton = new JButton(Resources.getString("reject"));
+
+ private JButton ignoreButton = new JButton(Resources.getString("ignore"));
+
+ private JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
+
+ private JPanel northPanel = new JPanel(new BorderLayout(10, 10));
+
+ private JLabel iconLabel = new JLabel(Resources.getImage("inviteIcon"));
+
+ private String title
+ = Resources.getString("invitationReceived");
+
+ /**
+ * The <tt>ChatRoomInvitation</tt> for which this dialog is.
+ */
+ private WhiteboardInvitation invitation;
+
+ /**
+ * The <tt>MultiUserChatManager</tt> is the one that deals with invitation
+ * events.
+ */
+ private WhiteboardSessionManager whiteboardManager;
+
+ /**
+ * The operation set that would handle the rejection if the user choose to
+ * reject the invitation.
+ */
+ private OperationSetWhiteboarding whiteboardOpSet;
+
+ /**
+ * Constructs the <tt>ChatInviteDialog</tt>.
+ *
+ * @param whiteboardManager the <tt>WhiteboardSessionManager</tt> is the one
+ * that deals with invitation events
+ * @param whiteboardOpSet the operation set that would handle the
+ * rejection if the user choose to reject the invitation
+ * @param invitation the invitation that this dialog represents
+ */
+ public InvitationReceivedDialog (WhiteboardSessionManager whiteboardManager,
+ OperationSetWhiteboarding whiteboardOpSet,
+ WhiteboardInvitation invitation)
+ {
+ this.whiteboardManager = whiteboardManager;
+
+ this.whiteboardOpSet = whiteboardOpSet;
+
+ this.invitation = invitation;
+
+ this.setModal(false);
+
+ this.setTitle(title);
+
+ this.mainPanel.setPreferredSize(new Dimension(400, 230));
+
+ infoTextArea.setText(
+ Resources.getString("invitationReceivedFormInfo",
+ new String[] { invitation.getInviter(),
+ invitation.getTargetWhiteboard()
+ .getWhiteboardID()}));
+
+ if(invitation.getReason() != null && invitation.getReason() != "")
+ {
+ invitationReasonTextArea.setText(invitation.getReason());
+ invitationReasonTextArea.setBorder(
+ BorderFactory.createTitledBorder(
+ Resources.getString("invitation")));
+
+ this.dataPanel.add(invitationReasonTextArea, BorderLayout.CENTER);
+ }
+
+ this.infoTextArea.setFont(
+ infoTextArea.getFont().deriveFont(Font.BOLD, 12f));
+ this.infoTextArea.setLineWrap(true);
+ this.infoTextArea.setOpaque(false);
+ this.infoTextArea.setWrapStyleWord(true);
+ this.infoTextArea.setEditable(false);
+
+ this.northPanel.add(iconLabel, BorderLayout.WEST);
+ this.northPanel.add(infoTextArea, BorderLayout.CENTER);
+
+ this.reasonPanel.add(reasonLabel, BorderLayout.WEST);
+ this.reasonPanel.add(reasonField, BorderLayout.CENTER);
+
+ this.dataPanel.add(reasonPanel, BorderLayout.SOUTH);
+
+ this.acceptButton.addActionListener(this);
+ this.rejectButton.addActionListener(this);
+ this.ignoreButton.addActionListener(this);
+
+ this.buttonsPanel.add(acceptButton);
+ this.buttonsPanel.add(rejectButton);
+ this.buttonsPanel.add(ignoreButton);
+
+ this.getRootPane().setDefaultButton(acceptButton);
+ this.acceptButton.setMnemonic(Resources.getMnemonic("accept"));
+ this.rejectButton.setMnemonic(Resources.getMnemonic("reject"));
+ this.ignoreButton.setMnemonic(Resources.getMnemonic("ignore"));
+
+ this.mainPanel.setBorder(
+ BorderFactory.createEmptyBorder(15, 15, 15, 15));
+
+ this.mainPanel.add(northPanel, BorderLayout.NORTH);
+ this.mainPanel.add(dataPanel, BorderLayout.CENTER);
+ this.mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
+
+ this.getContentPane().add(mainPanel);
+ }
+
+ /**
+ * Handles the <tt>ActionEvent</tt> triggered when one user clicks
+ * on one of the buttons.
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ JButton button = (JButton)e.getSource();
+
+ if (button.equals(acceptButton))
+ {
+ whiteboardManager.acceptInvitation(invitation);
+ }
+ else if (button.equals(rejectButton))
+ {
+ whiteboardManager.rejectInvitation(whiteboardOpSet,
+ invitation, reasonField.getText());
+ }
+
+ this.dispose();
+ }
+
+ protected void close(boolean isEscaped)
+ {}
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFileFilter.java b/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFileFilter.java
new file mode 100644
index 0000000..ed0d305
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFileFilter.java
@@ -0,0 +1,91 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package net.java.sip.communicator.plugin.whiteboard.gui;
+
+import java.io.File;
+import javax.swing.filechooser.FileFilter;
+
+/**
+ * A simple file filter manager
+ *
+ * @author Julien Waechter
+ */
+public class WhiteboardFileFilter extends FileFilter {
+
+ /**
+ * file extension
+ */
+ private String ext;
+ /**
+ * file description
+ */
+ private String description;
+
+ /**
+ * WhiteboardFileFilter constructor
+ * @param ext extension
+ * @param description description
+ */
+ public WhiteboardFileFilter (String ext, String description) {
+ this.ext = ext;
+ this.description = description;
+ }
+
+ /**
+ * Tests the specified file,
+ * returning true if the file is accepted, false otherwise.
+ * True is returned if the extension matches one of
+ * the file name extensions of this FileFilter,
+ * or the file is a directory.
+ * @param f file
+ * @return true if file is accepted
+ */
+ public boolean accept (File f) {
+ if (f != null) {
+ if (f.isDirectory ()) {
+ return true;
+ }
+ String e = getExtension (f);
+ if (e != null && e.equals (ext)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * The description of this filter. For example: "JPG and GIF Images"
+ * @return description
+ */
+ public String getDescription () {
+ return description;
+ }
+ /**
+ * The description of this filter. For example: "JPG and GIF Images"
+ * @return description
+ */
+ public String getExtension () {
+ return ext;
+ }
+
+ /**
+ * The extension of the file"
+ * @param f File
+ * @return file extension
+ */
+ public String getExtension (File f) {
+ if (f != null) {
+ String filename = f.getName ();
+ int i = filename.lastIndexOf ('.');
+ if (i > 0 && i < filename.length () - 1) {
+ return filename.substring (i + 1).toLowerCase ();
+ }
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFrame.java b/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFrame.java
new file mode 100644
index 0000000..6a3b7e1
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardFrame.java
@@ -0,0 +1,2480 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+
+package net.java.sip.communicator.plugin.whiteboard.gui;
+
+import java.awt.event.*;
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.*;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import javax.swing.*;
+
+import net.java.sip.communicator.plugin.whiteboard.*;
+import net.java.sip.communicator.plugin.whiteboard.gui.whiteboardshapes.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.whiteboardobjects.*;
+import net.java.sip.communicator.util.Logger;
+
+/**
+ * The frame for the Whiteboard
+ *
+ * @author Julien Waechter
+ */
+public class WhiteboardFrame
+ extends javax.swing.JFrame
+{
+ private static final Logger logger =
+ Logger.getLogger(WhiteboardFrame.class);
+
+ /**
+ * A type int constant indicating that we use the pen tool.
+ */
+ private static final int PEN = 1;
+
+ /**
+ * A type int constant indicating that we use the line tool
+ */
+ private static final int LINE = 2;
+
+ /**
+ * A type int constant indicating that we use the rectangle tool.
+ */
+ private static final int RECTANGLE = 3;
+
+ /**
+ * A type int constant indicating that we use the fill rectangle tool.
+ */
+ private static final int FILL_RECTANGLE = 4;
+
+ /**
+ * A type int constant indicating that we use the circle tool.
+ */
+ private static final int CIRCLE = 5;
+
+ /**
+ * A type int constant indicating that we use the fill circle tool.
+ */
+ private static final int FILL_CIRCLE = 6;
+
+ /**
+ * A type int constant indicating that we use the text tool.
+ */
+ private static final int TEXT = 7;
+
+ /**
+ * A type int constant indicating that we use the selection tool.
+ */
+ private static final int SELECTION = 8;
+
+ /**
+ * A type int constant indicating that we use the image tool.
+ */
+ private static final int IMAGE = 9;
+
+ /**
+ * A type int constant indicating that we use the polyline tool.
+ */
+ private static final int POLYLINE = 10;
+
+ /**
+ * A type int constant indicating that we use the fill polyline tool.
+ */
+ private static final int FILL_POLYLINE = 11;
+
+ /**
+ * A type int constant indicating that we use the polygon tool..
+ */
+ private static final int POLYGON = 12;
+
+ /**
+ * A type int constant indicating that we use the fill polygon tool..
+ */
+ private static final int FILL_POLYGON = 13;
+
+ /**
+ * A type int constant indicating that we use the modification tool.
+ */
+ private static final int MODIF = 15;
+
+ /**
+ * A type int constant indicating that we use the pan tool.
+ */
+ private static final int PAN = 16;
+
+ /**
+ * The last file dir open
+ */
+ private File lastDir;
+
+ /**
+ * The current tool (= one of the previous type int constant)
+ */
+ private int currentTool = 0;
+
+ /**
+ * X mouse coordinates
+ */
+ private int mouseX = 0;
+
+ /**
+ * Y mouse coordinates
+ */
+ private int mouseY = 0;
+
+ /**
+ * Old X mouse coordinates
+ */
+ private int previousMouseX = 0;
+
+ /**
+ * Old Y mouse coordinates
+ */
+ private int previousMouseY = 0;
+
+ /**
+ * Default size grid
+ */
+ private int defaultGrid = 25;
+
+ /**
+ * Old coordinates
+ */
+ private Point2D previousPoint;
+
+ /**
+ * The current selected shape (null if nothing is seleted)
+ */
+ private WhiteboardShape selectedShape = null;
+
+ /**
+ * The current selected point (null if nothing is seleted)
+ */
+ private Point2D selectedPoint = null;
+
+ /**
+ * The current preselected shape (null if nothing is preseleted) A shape is
+ * preselected when the mouse move on.
+ */
+ private WhiteboardShape preselected = null;
+
+ /**
+ * The current copied shape (null if nothing is copied)
+ */
+ private WhiteboardShape copiedShape = null;
+
+ /**
+ * True if the draw is finish
+ */
+ private boolean doneDrawing = true;
+
+ /**
+ * Start X mouse coordinates
+ */
+ private int originX = 0;
+
+ /**
+ * Start Y mouse coordinates
+ */
+ private int originY = 0;
+
+ /**
+ * Start width size
+ */
+ private int originWidth = 0;
+
+ /**
+ * Start height size
+ */
+ private int originHeight = 0;
+
+ /**
+ * X coordinates for draw the shape
+ */
+ private int drawX = 0;
+
+ /**
+ * Y coordinates for draw the shape
+ */
+ private int drawY = 0;
+
+ /**
+ * The current color for the shapes (black by default)
+ */
+ private Color currentColor = Color.BLACK;
+
+ /**
+ * The XOR alternation color for display
+ */
+ private Color xorColor = Color.WHITE;
+
+ /**
+ * List of WhiteboardShape
+ */
+ private List displayList = new CopyOnWriteArrayList();
+
+ /**
+ * Aarray of WhiteboardPoint
+ */
+ private List pathList = new ArrayList();
+
+ /**
+ * WhiteboardPanel where the shapes are drawn
+ */
+ private WhiteboardPanel drawCanvas;
+
+ /**
+ * True if we are in "move" state
+ */
+ private boolean moving;
+
+ /**
+ * Default font size for the text.
+ */
+ private int defaultFontSize = WhiteboardShapeText.DEFAULT_FONT_SIZE;
+
+ /**
+ * Affine transform world to shape.
+ */
+ private AffineTransform w2s;
+
+ /**
+ * Affine transform shape to world.
+ */
+ private AffineTransform s2w;
+
+ /**
+ * The color chooser for choose the shape's color
+ */
+ private JColorChooser colorChooser = new JColorChooser();
+
+ /**
+ * The color chooser dialog created by colorChooser.
+ */
+ private JDialog colorChooserDialog;
+
+ /**
+ * Spinner to choose the thickness
+ */
+ private SpinnerNumberModel spinModel;
+
+ /**
+ * Contact associated with this WhiteboardFrame
+ */
+ private Contact contact;
+
+ /**
+ * WhiteboardSessionManager associated with this WhiteboardFrame.
+ */
+ private WhiteboardSessionManager sessionManager;
+
+ /**
+ * WhiteboardSession associated with this WhiteboardFrame
+ */
+ private WhiteboardSession session;
+
+ /**
+ * Constructor for WhiteboardFrame.
+ *
+ * @param wps WhiteboardSessionManager
+ * @param session WhiteboardSession associated with this frame
+ */
+ public WhiteboardFrame(WhiteboardSessionManager wps,
+ WhiteboardSession session)
+ {
+ super();
+ this.drawCanvas = new WhiteboardPanel(displayList, this);
+ this.sessionManager = wps;
+ this.session = session;
+
+ initComponents();
+ initIcons();
+ initMouse();
+
+ drawCanvas.setLayout(new java.awt.BorderLayout());
+ getContentPane().add(drawCanvas, java.awt.BorderLayout.CENTER);
+
+ setSize(800, 600);
+ initializeTransform();
+
+ Integer value = new Integer(1);
+ Integer min = new Integer(1);
+ Integer max = new Integer(10);
+ Integer step = new Integer(1);
+ spinModel = new SpinnerNumberModel(value, min, max, step);
+ jSpinnerThickness.setModel(spinModel);
+
+ if (contact != null)
+ this.jLabelStatus.setText("PictoChat with: "
+ + contact.getDisplayName());
+ }
+
+ /**
+ * Initialize all icons in the frame.
+ */
+ private void initIcons()
+ {
+ setIconImage(Resources.getImage("sc_logo16x16").getImage());
+
+ selectionButton.setIcon(Resources.getImage("selectIcon"));
+ penButton.setIcon(Resources.getImage("penIcon"));
+ lineButton.setIcon(Resources.getImage("line2Icon"));
+ rectangleButton.setIcon(Resources.getImage("rectIcon"));
+ fillRectangleButton.setIcon(Resources.getImage("rectFIcon"));
+ circleButton.setIcon(Resources.getImage("circle2Icon"));
+ fillCircleButton.setIcon(Resources.getImage("circleFIcon"));
+ textButton.setIcon(Resources.getImage("text2Icon"));
+ colorChooserButton.setIcon(Resources.getImage("colorIcon"));
+ polylineButton.setIcon(Resources.getImage("polyLineIcon"));
+ polygonButton.setIcon(Resources.getImage("polyIcon"));
+ fillPolygonButton.setIcon(Resources.getImage("polyFIcon"));
+ imageButton.setIcon(Resources.getImage("imgIcon"));
+ modifButton.setIcon(Resources.getImage("modifIcon"));
+
+ jButtonNew.setIcon(Resources.getImage("fileNewIcon"));
+ jButtonCopy.setIcon(Resources.getImage("editCopyIcon"));
+ jButtonPaste.setIcon(Resources.getImage("editPasteIcon"));
+ jButtonOpen.setIcon(Resources.getImage("fileImportIcon"));
+ jButtonSave.setIcon(Resources.getImage("fileSaveIcon"));
+ }
+
+ /**
+ * Initialize all transformations.
+ */
+ private void initializeTransform()
+ {
+ w2s = new AffineTransform();
+ w2s.setToScale(1, 1);
+ try
+ {
+ s2w = w2s.createInverse();
+ }
+ catch (NoninvertibleTransformException e)
+ {
+ logger.error(e.getMessage());
+ }
+ }
+
+ /**
+ * Initialize all mouse events.
+ */
+ private void initMouse()
+ {
+ drawCanvas.addMouseListener(new java.awt.event.MouseListener()
+ {
+ /**
+ * Invoked when the mouse button has been clicked (pressed and
+ * released) on a component.
+ */
+ public void mouseClicked(MouseEvent e)
+ {
+ switch (currentTool)
+ {
+ case POLYLINE:
+ if (e.getClickCount() == 1)
+ {
+ polyOperation(e);
+ }
+
+ if (e.getClickCount() == 2)
+ {
+ releasedPolyline(false);
+ }
+ break;
+
+ case FILL_POLYLINE:
+ if (e.getClickCount() == 1)
+ {
+ polyOperation(e);
+ }
+
+ if (e.getClickCount() == 2)
+ {
+ releasedPolyline(true);
+ }
+ break;
+
+ case POLYGON:
+ if (e.getClickCount() == 1)
+ {
+ polyOperation(e);
+ }
+
+ if (e.getClickCount() == 2)
+ {
+ releasedPolygon(false);
+ }
+ break;
+
+ case FILL_POLYGON:
+ if (e.getClickCount() == 1)
+ {
+ polyOperation(e);
+ }
+
+ if (e.getClickCount() == 2)
+ {
+ releasedPolygon(true);
+ }
+ break;
+ }
+ }
+
+ /**
+ * Invoked when a mouse button has been pressed on a component.
+ */
+ public void mousePressed(MouseEvent e)
+ {
+ selectedShape = null;
+ if (currentTool == SELECTION)
+ {
+ deselect();
+ for (int i = displayList.size() - 1; i >= 0; i--)
+ {
+ WhiteboardShape shape =
+ (WhiteboardShape) displayList.get(i);
+
+ if (shape.contains(s2w.transform(e.getPoint(), null)))
+ {
+ shape.setSelected(true);
+ selectedShape = shape;
+ spinModel.setValue(new Integer(selectedShape
+ .getThickness()));
+ jLabelColor.setBackground(Color.getColor("",
+ selectedShape.getColor()));
+ break;
+ }
+ }
+ repaint();
+ }
+ else if (currentTool == MODIF)
+ {
+ deselect();
+ for (int i = displayList.size() - 1; i >= 0; i--)
+ {
+ WhiteboardShape shape =
+ (WhiteboardShape) displayList.get(i);
+
+ WhiteboardPoint point = shape.getSelectionPoint(
+ s2w.transform(e.getPoint(), null));
+
+ if (point != null)
+ {
+ shape.setSelected(true);
+ shape.setModifyPoint(point);
+
+ selectedShape = shape;
+ spinModel.setValue(new Integer(selectedShape
+ .getThickness()));
+ jLabelColor.setBackground(
+ Color.getColor("", selectedShape.getColor()));
+ break;
+ }
+ }
+ repaint();
+ }
+ else if (currentTool == PAN)
+ {
+ previousPoint = e.getPoint();
+ }
+ }
+
+ /**
+ * Invoked when a mouse button has been released on a component.
+ */
+ public void mouseReleased(MouseEvent e)
+ {
+ switch (currentTool)
+ {
+ case SELECTION:
+ releasedMove();
+ break;
+
+ case MODIF:
+ releasedModif();
+ break;
+
+ case PEN:
+ releasedPen();
+ break;
+
+ case LINE:
+ releasedLine();
+ break;
+
+ case RECTANGLE:
+ releasedRectangle(false);
+ break;
+
+ case FILL_RECTANGLE:
+ releasedRectangle(true);
+ break;
+
+ case CIRCLE:
+ releasedCircle(false);
+ break;
+
+ case FILL_CIRCLE:
+ releasedCircle(true);
+ break;
+
+ case TEXT:
+ releasedText(e.getX(), e.getY());
+ break;
+
+ case IMAGE:
+ releasedImage();
+ break;
+
+ case POLYLINE:
+ polyOperation(e);
+
+ case POLYGON:
+ polyOperation(e);
+
+ case FILL_POLYGON:
+ polyOperation(e);
+ }
+ }
+
+ /**
+ * Invoked when the mouse enters a component.
+ */
+ public void mouseEntered(MouseEvent e)
+ {
+ toggleCursor();
+ }
+
+ /**
+ * Invoked when the mouse exits a component.
+ */
+ public void mouseExited(MouseEvent e)
+ {
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ });
+
+ drawCanvas
+ .addMouseMotionListener(new java.awt.event.MouseMotionListener()
+ {
+ /**
+ * Invoked when a mouse button is pressed on a component and
+ * then dragged.
+ *
+ * @param e
+ */
+ public void mouseDragged(MouseEvent e)
+ {
+ switch (currentTool)
+ {
+ case SELECTION:
+ moveOperation(e);
+ break;
+
+ case MODIF:
+ modifOperation(e);
+ break;
+
+ case PEN:
+ penOperation(e);
+ break;
+
+ case LINE:
+ lineOperation(e);
+ break;
+
+ case RECTANGLE:
+ rectangleOperation(e);
+ break;
+
+ case FILL_RECTANGLE:
+ rectangleOperation(e);
+ break;
+
+ case CIRCLE:
+ circleOperation(e);
+ break;
+
+ case FILL_CIRCLE:
+ circleOperation(e);
+ break;
+
+ case IMAGE:
+ imageOperation(e);
+ break;
+
+ case PAN:
+ panOperation(e);
+ break;
+
+ case POLYLINE:
+ polyDragOperation(e);
+ break;
+
+ case POLYGON:
+ polyDragOperation(e);
+ break;
+
+ case FILL_POLYGON:
+ polyDragOperation(e);
+ break;
+ }
+ }
+
+ /**
+ * Invoked when the mouse cursor has been moved onto a component
+ * but no buttons have been pushed.
+ *
+ * @param e
+ */
+ public void mouseMoved(MouseEvent e)
+ {
+ WhiteboardShape shape;
+ for (int i = 0; i < displayList.size(); i++)
+ {
+ shape = (WhiteboardShape) displayList.get(i);
+ if (shape.contains(s2w.transform(e.getPoint(), null)))
+ {
+
+ if (currentTool == MODIF)
+ {
+ setCursor(Cursor.getDefaultCursor());
+ }
+ else
+ setCursor(Cursor
+ .getPredefinedCursor(Cursor.HAND_CURSOR));
+
+ if (currentTool == SELECTION
+ || currentTool == MODIF)
+ {
+ if (preselected == null)
+ {
+ Graphics g = drawCanvas.getGraphics();
+ shape.preselect(g, w2s);
+ preselected = shape;
+ }
+ else if (!preselected.equals(shape))
+ {
+ repaint();
+ Graphics g = drawCanvas.getGraphics();
+ shape.preselect(g, w2s);
+ preselected = shape;
+ }
+ }
+ return;
+ }
+ else if (shape.getSelectionPoint(s2w.transform(e
+ .getPoint(), null)) != null)
+ {
+ if (currentTool == MODIF)
+ {
+
+ setCursor(Cursor
+ .getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
+
+ if (preselected == null)
+ {
+ Graphics g = drawCanvas.getGraphics();
+ shape.preselect(g, w2s);
+ preselected = shape;
+ }
+ else if (!preselected.equals(shape))
+ {
+ repaint();
+ Graphics g = drawCanvas.getGraphics();
+ shape.preselect(g, w2s);
+ preselected = shape;
+ }
+ }
+ return;
+ }
+
+ }
+ if (preselected != null)
+ {
+ preselected = null;
+ repaint();
+ }
+ toggleCursor();
+ }
+ });
+ }
+
+ /**
+ * Sets the appropriate cursor depending on the current tool.
+ */
+ private void toggleCursor()
+ {
+ switch (currentTool)
+ {
+ case SELECTION:
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ break;
+ case MODIF:
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ break;
+ case PAN:
+ setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ break;
+
+ case TEXT:
+ setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
+ break;
+
+ case PEN:
+ case LINE:
+ case RECTANGLE:
+ case FILL_RECTANGLE:
+ case CIRCLE:
+ case FILL_CIRCLE:
+ case POLYLINE:
+ case FILL_POLYLINE:
+ case POLYGON:
+ case FILL_POLYGON:
+ case IMAGE:
+ setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
+ break;
+
+ default:
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor. (NetBeans 5.5)
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code
+ // ">//GEN-BEGIN:initComponents
+ private void initComponents()
+ {
+ buttonGroup = new ButtonGroup();
+ jLabelStatus = new JLabel();
+ jToolBar1 = new JToolBar();
+ jButtonNew = new JButton();
+ jButtonSave = new JButton();
+ jButtonOpen = new JButton();
+ jButtonCopy = new JButton();
+ jButtonPaste = new JButton();
+ jPanel1 = new JPanel();
+ toolBar = new JPanel();
+ penButton = new JToggleButton();
+ selectionButton = new JToggleButton();
+ lineButton = new JToggleButton();
+ rectangleButton = new JToggleButton();
+ fillRectangleButton = new JToggleButton();
+ textButton = new JToggleButton();
+ imageButton = new JToggleButton();
+ polygonButton = new JToggleButton();
+ fillPolygonButton = new JToggleButton();
+ polylineButton = new JToggleButton();
+ circleButton = new JToggleButton();
+ fillCircleButton = new JToggleButton();
+ colorChooserButton = new JButton();
+ jLabelColor = new JLabel();
+ modifButton = new JToggleButton();
+ jPanel2 = new JPanel();
+ jLabelThickness = new JLabel();
+ jLabel1 = new JLabel();
+ jSpinnerThickness = new JSpinner();
+ menuBar = new JMenuBar();
+ fileMenu = new JMenu();
+ newMenuItem = new JMenuItem();
+ openMenuItem = new JMenuItem();
+ saveMenuItem = new JMenuItem();
+ sendMenuItem = new JMenuItem();
+ printMenuItem = new JMenuItem();
+ exitMenuItem = new JMenuItem();
+ editMenu = new JMenu();
+ gridMenuItem = new JCheckBoxMenuItem();
+ deselectMenuItem = new JMenuItem();
+ copyMenuItem = new JMenuItem();
+ pasteMenuItem = new JMenuItem();
+ deleteMenuItem = new javax.swing.JMenuItem();
+ propertiesMenuItem = new JMenuItem();
+ helpMenu = new JMenu();
+ helpMenuItem = new JMenuItem();
+ aboutMenuItem = new JMenuItem();
+ leftPanel = new JPanel(new BorderLayout());
+
+ setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ setTitle(Resources.getString("whiteboardTitle"));
+
+ if (session != null)
+ {
+ Iterator participants = session.getWhiteboardParticipants();
+
+ while (participants.hasNext())
+ {
+ this.setTitle(this.getTitle() + " - " + participants.next());
+ }
+ }
+
+ jLabelStatus.setText(Resources.getString("draw"));
+ jLabelStatus.setBorder(javax.swing.BorderFactory
+ .createEtchedBorder(javax.swing.border.EtchedBorder.RAISED));
+ getContentPane().add(jLabelStatus, java.awt.BorderLayout.SOUTH);
+
+ jButtonNew.setToolTipText(Resources.getString("new"));
+ jButtonNew.setEnabled(false);
+ jToolBar1.add(jButtonNew);
+
+ jButtonSave.setToolTipText(Resources.getString("save"));
+ jButtonSave.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ jButtonSaveActionPerformed(evt);
+ }
+ });
+
+ jToolBar1.add(jButtonSave);
+
+ jButtonOpen.setToolTipText(Resources.getString("open"));
+ jButtonOpen.setEnabled(false);
+ jToolBar1.add(jButtonOpen);
+
+ jButtonCopy.setToolTipText(Resources.getString("copy"));
+ jButtonCopy.setEnabled(false);
+ jToolBar1.add(jButtonCopy);
+
+ jButtonPaste.setToolTipText(Resources.getString("paste"));
+ jButtonPaste.setEnabled(false);
+ jToolBar1.add(jButtonPaste);
+
+ getContentPane().add(jToolBar1, BorderLayout.NORTH);
+
+ jPanel1.setLayout(new BorderLayout());
+
+ jPanel1.setPreferredSize(new Dimension(110, 350));
+ toolBar.setLayout(new GridLayout(0, 2, 5, 5));
+ toolBar.setBorder(BorderFactory.createEmptyBorder(5, 8, 5, 8));
+
+ buttonGroup.add(selectionButton);
+ selectionButton.setToolTipText(Resources.getString("select"));
+ selectionButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ selectionButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(selectionButton);
+
+ buttonGroup.add(modifButton);
+ modifButton.setToolTipText(Resources.getString("modification"));
+ modifButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ modifButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(modifButton);
+
+ buttonGroup.add(penButton);
+ penButton.setToolTipText(Resources.getString("pen"));
+ penButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ penButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(penButton);
+
+ buttonGroup.add(textButton);
+ textButton.setToolTipText(Resources.getString("text"));
+ textButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ textButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(textButton);
+
+ buttonGroup.add(lineButton);
+ lineButton.setToolTipText(Resources.getString("line"));
+ lineButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ lineButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(lineButton);
+
+ buttonGroup.add(polylineButton);
+ polylineButton.setToolTipText(Resources.getString("polyline"));
+ polylineButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ polylineButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(polylineButton);
+
+ buttonGroup.add(rectangleButton);
+ rectangleButton.setToolTipText(Resources.getString("rectangle"));
+ rectangleButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ rectangleButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(rectangleButton);
+
+ buttonGroup.add(fillRectangleButton);
+ fillRectangleButton.setToolTipText(Resources.getString("fillRectangle"));
+ fillRectangleButton
+ .addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ fillRectangleButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(fillRectangleButton);
+
+ buttonGroup.add(imageButton);
+ imageButton.setToolTipText(Resources.getString("image"));
+ imageButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ imageButtonActionPerformed(evt);
+ }
+ });
+
+// toolBar.add(imageButton);
+
+ buttonGroup.add(polygonButton);
+ polygonButton.setToolTipText(Resources.getString("polygon"));
+ polygonButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ polygonButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(polygonButton);
+
+ buttonGroup.add(fillPolygonButton);
+ fillPolygonButton.setToolTipText(Resources.getString("fillPolygon"));
+ fillPolygonButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ fillPolygonButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(fillPolygonButton);
+
+ buttonGroup.add(circleButton);
+ circleButton.setToolTipText(Resources.getString("circle"));
+ circleButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ circleButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(circleButton);
+
+ buttonGroup.add(fillCircleButton);
+ fillCircleButton.setToolTipText(Resources.getString("fillCircle"));
+ fillCircleButton.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ fillCircleButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(fillCircleButton);
+
+ colorChooserButton.setToolTipText(Resources.getString("color"));
+ colorChooserButton
+ .addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ colorChooserButtonActionPerformed(evt);
+ }
+ });
+
+ toolBar.add(colorChooserButton);
+
+ jLabelColor.setOpaque(true);
+ jLabelColor.setBackground(currentColor);
+ jLabelColor.setBorder(BorderFactory.createLineBorder(Color.GRAY, 3));
+ toolBar.add(jLabelColor);
+
+ jPanel1.add(toolBar, BorderLayout.NORTH);
+
+ jPanel2.setLayout(new GridBagLayout());
+
+ jLabelThickness.setText(Resources.getString("thickness"));
+
+ jPanel2.add(jLabelThickness);
+
+ jSpinnerThickness
+ .addChangeListener(new javax.swing.event.ChangeListener()
+ {
+ public void stateChanged(javax.swing.event.ChangeEvent evt)
+ {
+ jSpinnerThicknessStateChanged(evt);
+ }
+ });
+
+ jPanel2.add(jSpinnerThickness);
+
+ jPanel1.add(jPanel2, BorderLayout.CENTER);
+
+ leftPanel.add(jPanel1, BorderLayout.NORTH);
+
+ getContentPane().add(leftPanel, BorderLayout.WEST);
+
+ fileMenu.setText(Resources.getString("file"));
+ fileMenu.setEnabled(false);
+ newMenuItem.setText(Resources.getString("new"));
+ fileMenu.add(newMenuItem);
+
+ openMenuItem.setText(Resources.getString("open"));
+ fileMenu.add(openMenuItem);
+
+ saveMenuItem.setText(Resources.getString("save"));
+ fileMenu.add(saveMenuItem);
+
+ sendMenuItem.setText(Resources.getString("send"));
+ fileMenu.add(sendMenuItem);
+
+ printMenuItem.setText(Resources.getString("print"));
+ fileMenu.add(printMenuItem);
+
+ exitMenuItem.setText(Resources.getString("exit"));
+ fileMenu.add(exitMenuItem);
+
+ menuBar.add(fileMenu);
+
+ editMenu.setText(Resources.getString("edit"));
+ gridMenuItem.setText(Resources.getString("grid"));
+ gridMenuItem.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ gridMenuItemActionPerformed(evt);
+ }
+ });
+
+ editMenu.add(gridMenuItem);
+
+ deselectMenuItem.setText(Resources.getString("deselect"));
+ deselectMenuItem.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ deselectMenuItemActionPerformed(evt);
+ }
+ });
+
+ editMenu.add(deselectMenuItem);
+
+ copyMenuItem.setText(Resources.getString("copy"));
+ copyMenuItem.setEnabled(false);
+ editMenu.add(copyMenuItem);
+
+ pasteMenuItem.setText(Resources.getString("paste"));
+ pasteMenuItem.setEnabled(false);
+ editMenu.add(pasteMenuItem);
+
+ deleteMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_DELETE, 0));
+ deleteMenuItem.setText(Resources.getString("delete"));
+ deleteMenuItem.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ deleteMenuItemActionPerformed(evt);
+ }
+ });
+
+ editMenu.add(deleteMenuItem);
+
+ propertiesMenuItem.setText(Resources.getString("properties"));
+ propertiesMenuItem.setEnabled(false);
+ editMenu.add(propertiesMenuItem);
+
+ menuBar.add(editMenu);
+
+ helpMenu.setText(Resources.getString("help"));
+ helpMenu.setEnabled(false);
+ helpMenuItem.setText(Resources.getString("help"));
+ helpMenu.add(helpMenuItem);
+
+ aboutMenuItem.setText(Resources.getString("about"));
+ helpMenu.add(aboutMenuItem);
+
+ menuBar.add(helpMenu);
+
+ setJMenuBar(menuBar);
+
+ pack();
+ }
+
+ /**
+ * Invoked when an action occurs on the modifButton.
+ *
+ * @param evt
+ */
+ private void modifButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {
+ if (modifButton.isSelected())
+ currentTool = MODIF;
+ }
+
+ /**
+ * Invoked when an action occurs on the jButtonSave.
+ *
+ * @param evt
+ */
+ private void jButtonSaveActionPerformed(java.awt.event.ActionEvent evt)
+ {
+
+ JFileChooser chooser = new JFileChooser(lastDir);
+ chooser.removeChoosableFileFilter(chooser.getAcceptAllFileFilter());
+ WhiteboardFileFilter filterJpg =
+ new WhiteboardFileFilter("jpg", "JPEG Files (*.jpg)");
+ WhiteboardFileFilter filterPng =
+ new WhiteboardFileFilter("png", "PNG Files (*.png)");
+ chooser.setFileFilter(filterJpg);
+ chooser.addChoosableFileFilter(filterPng);
+ int returnVal = chooser.showSaveDialog(WhiteboardFrame.this);
+ if (returnVal == JFileChooser.APPROVE_OPTION)
+ {
+ try
+ {
+ File file = chooser.getSelectedFile();
+ WhiteboardFileFilter ff =
+ (WhiteboardFileFilter) chooser.getFileFilter();
+ if (!ff.getExtension().equals(ff.getExtension(file)))
+ {
+ file =
+ new File(file.getAbsolutePath() + "."
+ + ff.getExtension());
+ }
+ lastDir = file.getParentFile();
+ BufferedImage buf =
+ new BufferedImage(drawCanvas.getWidth(), drawCanvas
+ .getHeight(), BufferedImage.TYPE_INT_RGB);
+ Graphics2D g = buf.createGraphics();
+
+ this.drawCanvas.paint(g);
+ g.dispose();
+ ImageIO.write(buf, ff.getExtension(), file);
+ }
+ catch (IOException ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ }// GEN-LAST:event_jButtonSaveActionPerformed
+
+ /**
+ * Invoked when an action occurs on the delete menu.
+ *
+ * @param evt
+ */
+ private void deleteMenuItemActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_deleteMenuItemActionPerformed
+ this.deleteSelected();
+ }// GEN-LAST:event_deleteMenuItemActionPerformed
+
+ /**
+ * Invoked when an action occurs on the deselect menu.
+ *
+ * @param evt
+ */
+ private void deselectMenuItemActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_deselectMenuItemActionPerformed
+ this.deselect();
+ }// GEN-LAST:event_deselectMenuItemActionPerformed
+
+ /**
+ * Invoked when the jSpinnerThickness has changed its state.
+ *
+ * @param evt
+ */
+ private void jSpinnerThicknessStateChanged(javax.swing.event.ChangeEvent evt)
+ {// GEN-FIRST:event_jSpinnerThicknessStateChanged
+ if (selectedShape != null)
+ {
+ selectedShape.setThickness(spinModel.getNumber().intValue());
+ sendMoveShape(selectedShape);
+ repaint();
+ }
+ }// GEN-LAST:event_jSpinnerThicknessStateChanged
+
+ /**
+ * Invoked when an action occurs on the fillCircleButton.
+ *
+ * @param evt
+ */
+ private void fillCircleButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_fillCircleButtonActionPerformed
+ if (fillCircleButton.isSelected())
+ currentTool = FILL_CIRCLE;
+ }// GEN-LAST:event_fillCircleButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the circleButton.
+ *
+ * @param evt
+ */
+ private void circleButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_circleButtonActionPerformed
+ if (circleButton.isSelected())
+ currentTool = CIRCLE;
+ }// GEN-LAST:event_circleButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the polylineButton.
+ *
+ * @param evt
+ */
+ private void polylineButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_polylineButtonActionPerformed
+ if (polylineButton.isSelected())
+ currentTool = POLYLINE;
+ }// GEN-LAST:event_polylineButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the fillPolygonButton.
+ *
+ * @param evt
+ */
+ private void fillPolygonButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_fillPolygonButtonActionPerformed
+ if (fillPolygonButton.isSelected())
+ currentTool = FILL_POLYGON;
+ }// GEN-LAST:event_fillPolygonButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the polygonButton.
+ *
+ * @param evt
+ */
+ private void polygonButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_polygonButtonActionPerformed
+ if (polygonButton.isSelected())
+ currentTool = POLYGON;
+ }// GEN-LAST:event_polygonButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the imageButton.
+ *
+ * @param evt
+ */
+ private void imageButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_imageButtonActionPerformed
+ if (imageButton.isSelected())
+ currentTool = IMAGE;
+ }// GEN-LAST:event_imageButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the rectangleButton.
+ *
+ * @param evt
+ */
+ private void rectangleButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_rectangleButtonActionPerformed
+ if (rectangleButton.isSelected())
+ currentTool = RECTANGLE;
+ }// GEN-LAST:event_rectangleButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the lineButton.
+ *
+ * @param evt
+ */
+ private void lineButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_lineButtonActionPerformed
+ if (lineButton.isSelected())
+ currentTool = LINE;
+ }// GEN-LAST:event_lineButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the fillRectangleButton.
+ *
+ * @param evt
+ */
+ private void fillRectangleButtonActionPerformed(
+ java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_fillRectangleButtonActionPerformed
+ if (fillRectangleButton.isSelected())
+ currentTool = FILL_RECTANGLE;
+ }// GEN-LAST:event_fillRectangleButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the textButto.
+ *
+ * @param evt
+ */
+ private void textButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_textButtonActionPerformed
+ if (textButton.isSelected())
+ currentTool = TEXT;
+ }// GEN-LAST:event_textButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the penButton.
+ *
+ * @param evt
+ */
+ private void penButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_penButtonActionPerformed
+ if (penButton.isSelected())
+ currentTool = PEN;
+ }// GEN-LAST:event_penButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the selectionButton.
+ *
+ * @param evt
+ */
+ private void selectionButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_selectionButtonActionPerformed
+ if (selectionButton.isSelected())
+ currentTool = SELECTION;
+ deselect();
+ repaint();
+ }// GEN-LAST:event_selectionButtonActionPerformed
+
+ /**
+ * Invoked when an action occurs on the gridMenuItem.
+ *
+ * @param evt
+ */
+ private void gridMenuItemActionPerformed(java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_gridMenuItemActionPerformed
+ this.drawCanvas.drawGrid(gridMenuItem.isSelected());
+ repaint();
+ }// GEN-LAST:event_gridMenuItemActionPerformed
+
+ /**
+ * Invoked when an action occurs on the colorChooserButton.
+ *
+ * @param evt
+ */
+ private void colorChooserButtonActionPerformed(
+ java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_colorChooserButtonActionPerformed
+ this.chooseColor();
+ }// GEN-LAST:event_colorChooserButtonActionPerformed
+
+ /**
+ * Components used for the GUI:
+ */
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JMenuItem aboutMenuItem;
+
+ private javax.swing.ButtonGroup buttonGroup;
+
+ private javax.swing.JToggleButton circleButton;
+
+ private javax.swing.JButton colorChooserButton;
+
+ private javax.swing.JMenuItem copyMenuItem;
+
+ private javax.swing.JMenuItem deleteMenuItem;
+
+ private javax.swing.JMenuItem deselectMenuItem;
+
+ private javax.swing.JMenu editMenu;
+
+ private javax.swing.JMenuItem exitMenuItem;
+
+ private javax.swing.JMenu fileMenu;
+
+ private javax.swing.JToggleButton fillCircleButton;
+
+ private javax.swing.JToggleButton fillPolygonButton;
+
+ private javax.swing.JToggleButton fillRectangleButton;
+
+ private javax.swing.JCheckBoxMenuItem gridMenuItem;
+
+ private javax.swing.JMenu helpMenu;
+
+ private javax.swing.JMenuItem helpMenuItem;
+
+ private javax.swing.JToggleButton imageButton;
+
+ private javax.swing.JButton jButtonCopy;
+
+ private javax.swing.JButton jButtonNew;
+
+ private javax.swing.JButton jButtonOpen;
+
+ private javax.swing.JButton jButtonPaste;
+
+ private javax.swing.JButton jButtonSave;
+
+ private javax.swing.JLabel jLabel1;
+
+ private javax.swing.JLabel jLabelColor;
+
+ private javax.swing.JLabel jLabelStatus;
+
+ private javax.swing.JLabel jLabelThickness;
+
+ private JPanel leftPanel;
+
+ private javax.swing.JPanel jPanel1;
+
+ private javax.swing.JPanel jPanel2;
+
+ private javax.swing.JSpinner jSpinnerThickness;
+
+ private javax.swing.JToolBar jToolBar1;
+
+ private javax.swing.JToggleButton lineButton;
+
+ private javax.swing.JMenuBar menuBar;
+
+ private javax.swing.JToggleButton modifButton;
+
+ private javax.swing.JMenuItem newMenuItem;
+
+ private javax.swing.JMenuItem openMenuItem;
+
+ private javax.swing.JMenuItem pasteMenuItem;
+
+ private javax.swing.JToggleButton penButton;
+
+ private javax.swing.JToggleButton polygonButton;
+
+ private javax.swing.JToggleButton polylineButton;
+
+ private javax.swing.JMenuItem printMenuItem;
+
+ private javax.swing.JMenuItem propertiesMenuItem;
+
+ private javax.swing.JToggleButton rectangleButton;
+
+ private javax.swing.JMenuItem saveMenuItem;
+
+ private javax.swing.JToggleButton selectionButton;
+
+ private javax.swing.JMenuItem sendMenuItem;
+
+ private javax.swing.JToggleButton textButton;
+
+ private javax.swing.JPanel toolBar;
+
+ // End of variables declaration//GEN-END:variables
+
+ /**
+ * Action when the shape is drawn.
+ *
+ * @param e
+ */
+ private void penOperation(MouseEvent e)
+ {
+ Graphics g = drawCanvas.getGraphics();
+ g.setColor(currentColor);
+
+ if (doneDrawing)
+ {
+ reInitMouse(e);
+ doneDrawing = false;
+ g.drawLine(previousMouseX, previousMouseY, mouseX, mouseY);
+ }
+
+ if (hasMouseMoved(e))
+ {
+ mouseX = snapToX(e.getX());
+ mouseY = snapToY(e.getY());
+ WhiteboardPoint point = new WhiteboardPoint(mouseX, mouseY);
+ pathList.add(point);
+ g.drawLine(previousMouseX, previousMouseY, mouseX, mouseY);
+
+ previousMouseX = mouseX;
+ previousMouseY = mouseY;
+ }
+ }
+
+ /**
+ * Action when the shape is drawn.
+ *
+ * @param e
+ */
+ private void lineOperation(MouseEvent e)
+ {
+ Graphics g = drawCanvas.getGraphics();
+ g.setColor(currentColor);
+
+ if (doneDrawing)
+ {
+ reInitMouse(e);
+ g.setXORMode(xorColor);
+ g.drawLine(originX, originY, mouseX, mouseY);
+ doneDrawing = false;
+ }
+
+ if (hasMouseMoved(e))
+ {
+ g.setXORMode(xorColor);
+ g.drawLine(originX, originY, mouseX, mouseY);
+
+ mouseX = snapToX(e.getX());
+ mouseY = snapToX(e.getY());
+
+ g.drawLine(originX, originY, mouseX, mouseY);
+ }
+ }
+
+ /**
+ * Action when the shape is drawn.
+ *
+ * @param e
+ */
+ private void rectangleOperation(MouseEvent e)
+ {
+ Graphics g = drawCanvas.getGraphics();
+ g.setColor(currentColor);
+
+ if (doneDrawing)
+ {
+ reInitMouse(e);
+ doneDrawing = false;
+ }
+
+ if (hasMouseMoved(e))
+ {
+ g.setXORMode(drawCanvas.getBackground());
+ g.drawRect(drawX, drawY, originWidth, originHeight);
+
+ mouseX = snapToX(e.getX());
+ mouseY = snapToY(e.getY());
+
+ setActualBoundry();
+
+ g.drawRect(drawX, drawY, originWidth, originHeight);
+ }
+ }
+
+ /**
+ * Action when the shape is drawn.
+ *
+ * @param e
+ */
+ private void ellipseOperation(MouseEvent e)
+ {
+ Graphics g = drawCanvas.getGraphics();
+ g.setColor(currentColor);
+
+ if (doneDrawing)
+ {
+ reInitMouse(e);
+ doneDrawing = false;
+ }
+
+ if (hasMouseMoved(e))
+ {
+ g.setXORMode(xorColor);
+ g.drawOval(drawX, drawY, originWidth, originHeight);
+
+ mouseX = snapToX(e.getX());
+ mouseY = snapToY(e.getY());
+
+ setActualBoundry();
+
+ g.drawOval(drawX, drawY, originWidth, originHeight);
+ }
+ }
+
+ /**
+ * Action when the shape is drawn.
+ *
+ * @param e
+ */
+ private void circleOperation(MouseEvent e)
+ {
+ Graphics g = drawCanvas.getGraphics();
+ g.setColor(currentColor);
+
+ if (doneDrawing)
+ {
+ reInitMouse(e);
+ doneDrawing = false;
+ }
+
+ if (hasMouseMoved(e))
+ {
+ g.setXORMode(xorColor);
+ g.drawOval(drawX, drawY, originWidth, originWidth);
+
+ mouseX = snapToX(e.getX());
+ mouseY = snapToY(e.getY());
+
+ setActualBoundry();
+
+ g.drawOval(drawX, drawY, originWidth, originWidth);
+ }
+ }
+
+ private void polyDragOperation(MouseEvent e)
+ {
+ Graphics g = drawCanvas.getGraphics();
+ g.setColor(currentColor);
+
+ if (hasMouseMoved(e))
+ {
+ g.setXORMode(xorColor);
+ g.drawLine(originX, originY, mouseX, mouseY);
+
+ mouseX = snapToX(e.getX());
+ mouseY = snapToX(e.getY());
+
+ g.drawLine(originX, originY, mouseX, mouseY);
+ }
+ }
+
+ /**
+ * Action when the shape is drawn.
+ *
+ * @param e
+ */
+ private void polyOperation(MouseEvent e)
+ {
+ logger.debug("[log] : polyOperation");
+ Graphics g = drawCanvas.getGraphics();
+ g.setColor(currentColor);
+
+ if (doneDrawing)
+ {
+ reInitMouse(e);
+ doneDrawing = false;
+ pathList.clear();
+ }
+
+ mouseX = snapToX(e.getX());
+ mouseY = snapToX(e.getY());
+
+ originX = snapToX(e.getX());
+ originY = snapToY(e.getY());
+
+ WhiteboardPoint point = new WhiteboardPoint(mouseX, mouseY);
+ pathList.add(point);
+ }
+
+ /**
+ * Action when the shape is drawn.
+ *
+ * @param e
+ */
+ private void imageOperation(MouseEvent e)
+ {
+ Graphics g = drawCanvas.getGraphics();
+ g.setColor(currentColor);
+
+ if (doneDrawing)
+ {
+ reInitMouse(e);
+ doneDrawing = false;
+ }
+
+ if (hasMouseMoved(e))
+ {
+ g.setXORMode(drawCanvas.getBackground());
+ g.drawRect(drawX, drawY, originWidth, originHeight);
+
+ mouseX = snapToX(e.getX());
+ mouseY = snapToY(e.getY());
+
+ setActualBoundry();
+
+ g.drawRect(drawX, drawY, originWidth, originHeight);
+ }
+ }
+
+ /**
+ * Action when the shape modified
+ *
+ * @param e
+ */
+ private void modifOperation(MouseEvent e)
+ {
+ if (selectedShape == null)
+ {
+ return;
+ }
+
+ moving = true;
+ if (doneDrawing)
+ {
+ reInitMouse(e);
+ doneDrawing = false;
+ }
+
+ if (hasMouseMoved(e))
+ {
+ int x = snapToX(e.getX());
+ int y = snapToY(e.getY());
+
+ Point2D s0 = new Point2D.Double(mouseX, mouseY);
+ Point2D s1 = new Point2D.Double(x, y);
+
+ Point2D w0 = s2w.transform(s0, null);
+ Point2D w1 = s2w.transform(s1, null);
+
+ selectedShape.translateSelectedPoint(
+ w1.getX() - w0.getX(),
+ w1.getY() - w0.getY());
+
+ mouseX = x;
+ mouseY = y;
+ repaint();
+ }
+ }
+
+ /**
+ * Action when the shape is moved.
+ *
+ * @param e
+ */
+ private void moveOperation(MouseEvent e)
+ {
+ if (selectedShape == null)
+ {
+ return;
+ }
+
+ moving = true;
+ if (doneDrawing)
+ {
+ reInitMouse(e);
+ doneDrawing = false;
+ }
+ int x = snapToX(e.getX());
+ int y = snapToY(e.getY());
+
+ if (hasMouseMoved(e))
+ {
+ Point2D s0 = new Point2D.Double(mouseX, mouseY);
+ Point2D s1 = new Point2D.Double(x, y);
+
+ Point2D w0 = s2w.transform(s0, null);
+ Point2D w1 = s2w.transform(s1, null);
+
+ selectedShape.translate(w1.getX() - w0.getX(), w1.getY()
+ - w0.getY());
+ mouseX = x;
+ mouseY = y;
+
+ repaint();
+ }
+ }
+
+ /**
+ * Action when the shape is translated.
+ *
+ * @param e
+ */
+ private void panOperation(MouseEvent e)
+ {
+ Point2D currentPoint = e.getPoint();
+
+ Point2D wCurrentPoint = s2w.transform(currentPoint, null);
+ Point2D wPreviousPoint = s2w.transform(previousPoint, null);
+
+ double deltaX = wCurrentPoint.getX() - wPreviousPoint.getX();
+ double deltaY = wCurrentPoint.getY() - wPreviousPoint.getY();
+
+ translate(deltaX, deltaY);
+
+ previousPoint = currentPoint;
+ }
+
+ /**
+ * Returns the X coordinate on the grid.
+ *
+ * @param x current x mouse coordinate
+ * @return X coordinate on the grid
+ */
+ private int snapToX(int x)
+ {
+ return gridMenuItem.isSelected() ? snap(x) : x;
+ }
+
+ /**
+ * Returns the Y coordinate on the grid.
+ *
+ * @param y current y mouse coordinate
+ * @return Y coordinate on the grid
+ */
+ private int snapToY(int y)
+ {
+ return gridMenuItem.isSelected() ? snap(y) : y;
+ }
+
+ /**
+ * Rounds off the position to the grid.
+ *
+ * @param i an approximate value
+ * @return a value on the grid
+ */
+ private int snap(int i)
+ {
+ int snap = i % defaultGrid;
+ if (snap < ((double) defaultGrid / (double) 2))
+ {
+ return (i - snap);
+ }
+ return (i + defaultGrid - snap);
+ }
+
+ /**
+ * Returns true if mouse has moved since last test.
+ *
+ * @param e
+ * @return true if mouse has moved
+ */
+ private boolean hasMouseMoved(MouseEvent e)
+ {
+ return (mouseX != e.getX() || mouseY != e.getY());
+ }
+
+ /**
+ * Returns the current selected WhiteboardShape.
+ *
+ * @return selected shape
+ */
+ public WhiteboardShape getSelectedShape()
+ {
+ return selectedShape;
+ }
+
+ /**
+ * Returns the current copied WhiteboardShape
+ *
+ * @return the copied shape
+ */
+ public WhiteboardShape getCopiedShape()
+ {
+ return copiedShape;
+ }
+
+ /**
+ * Calculate the new values for the global varibles drawX and drawY
+ * according to the new positions of the mouse cursor.
+ */
+ private void setActualBoundry()
+ {
+ if (mouseX < originX || mouseY < originY)
+ {
+ if (mouseX < originX)
+ {
+ originWidth = originX - mouseX;
+ drawX = originX - originWidth;
+ }
+ else
+ {
+ drawX = originX;
+ originWidth = mouseX - originX;
+ }
+
+ if (mouseY < originY)
+ {
+ originHeight = originY - mouseY;
+ drawY = originY - originHeight;
+ }
+ else
+ {
+ drawY = originY;
+ originHeight = mouseY - originY;
+ }
+ }
+ else
+ {
+ drawX = originX;
+ drawY = originY;
+ originWidth = mouseX - originX;
+ originHeight = mouseY - originY;
+ }
+ }
+
+ /**
+ * Set drawing variables to the current position of the cursor. Height and
+ * width varibles are zeroed off.
+ *
+ * @param e MouseEvent
+ */
+ private void reInitMouse(MouseEvent e)
+ {
+ int x = snapToX(e.getX());
+ int y = snapToY(e.getY());
+ mouseX = x;
+ mouseY = y;
+ previousMouseX = x;
+ previousMouseY = y;
+ originX = x;
+ originY = y;
+ drawX = x;
+ drawY = y;
+ originWidth = 0;
+ originHeight = 0;
+ }
+
+ /**
+ * Method to create-add-send a WhiteboardShapePath when mouse released
+ */
+ private void releasedPen()
+ {
+ doneDrawing = true;
+ appendAndSend(new WhiteboardShapePath(id(), spinModel.getNumber()
+ .intValue(), currentColor, pathList, s2w));
+ pathList.clear();
+ }
+
+ /**
+ * Method to create-add-send a WhiteboardShapeRect when mouse released.
+ *
+ * @param fill true if is fill
+ */
+ private void releasedRectangle(boolean fill)
+ {
+ doneDrawing = true;
+ appendAndSend(new WhiteboardShapeRect(id(), spinModel.getNumber()
+ .intValue(), currentColor, new WhiteboardPoint(drawX, drawY),
+ originWidth, originHeight, fill, s2w));
+ }
+
+ /**
+ * Method to create-add-send a WhiteboardShapeImage when mouse released
+ */
+ private void releasedImage()
+ {
+ doneDrawing = true;
+
+ JFileChooser chooser = new JFileChooser(lastDir);
+ WhiteboardFileFilter filter =
+ new WhiteboardFileFilter("jpg", "JPEG Files (*.jpg)");
+ chooser.setFileFilter(filter);
+ int returnVal = chooser.showOpenDialog(WhiteboardFrame.this);
+ if (returnVal == JFileChooser.APPROVE_OPTION)
+ {
+ try
+ {
+ File file = chooser.getSelectedFile();
+ lastDir = file.getParentFile();
+ FileInputStream in = new FileInputStream(file);
+ byte buffer[] = new byte[in.available()];
+ in.read(buffer);
+ WhiteboardShapeImage image =
+ new WhiteboardShapeImage(id(), new WhiteboardPoint(drawX,
+ drawY), originWidth, originHeight, buffer);
+ appendAndSend(image);
+ }
+ catch (IOException ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Method to create-add-send a WhiteboardShapeLine when mouse released
+ */
+ private void releasedLine()
+ {
+ if ((Math.abs(originX - mouseX) + Math.abs(originY - mouseY)) != 0)
+ {
+ doneDrawing = true;
+ appendAndSend(new WhiteboardShapeLine(id(), spinModel.getNumber()
+ .intValue(), currentColor,
+ new WhiteboardPoint(originX, originY), new WhiteboardPoint(
+ mouseX, mouseY), s2w));
+ }
+ }
+
+ /**
+ * Method to create-add-send a WhiteboardShapeCircle when mouse released.
+ *
+ * @param fill true if is fill
+ */
+ private void releasedCircle(boolean fill)
+ {
+ doneDrawing = true;
+
+ int r = originWidth / 2;
+ int cx = drawX + r;
+ int cy = drawY + r;
+
+ appendAndSend(new WhiteboardShapeCircle(id(), spinModel.getNumber()
+ .intValue(), currentColor, new WhiteboardPoint(cx, cy), r, fill,
+ s2w));
+ }
+
+ /**
+ * Method to create-add-send a WhiteboardShapePolyLine when mouse released.
+ *
+ * @param fill true if is fill
+ */
+ private void releasedPolyline(boolean fill)
+ {
+ logger.debug("[log] : releasedPolyline");
+ doneDrawing = true;
+ appendAndSend(new WhiteboardShapePolyLine(id(), spinModel.getNumber()
+ .intValue(), currentColor, pathList, fill, s2w));
+ pathList.clear();
+ }
+
+ /**
+ * Method to create-add-send a WhiteboardShapePolygon when mouse released.
+ *
+ * @param fill true if is fill
+ */
+ private void releasedPolygon(boolean fill)
+ {
+ doneDrawing = true;
+ appendAndSend(new WhiteboardShapePolygon(id(), spinModel.getNumber()
+ .intValue(), currentColor, pathList, fill, s2w));
+ pathList.clear();
+ }
+
+ /**
+ * Method to create-add-send a WhiteboardShapeText when mouse released.
+ *
+ * @param x x coord
+ * @param y y coord
+ */
+ private void releasedText(int x, int y)
+ {
+
+ doneDrawing = true;
+
+ Graphics g = drawCanvas.getGraphics();
+ g.setColor(Color.BLACK);
+ g.drawLine(x, y - 10, x, y + 10);
+
+ String t =
+ (String) JOptionPane.showInputDialog(this,
+ "Please enter your text", "Text", JOptionPane.QUESTION_MESSAGE,
+ null, null, "text");
+
+ if (t != null && t.length() > 0)
+ {
+ appendAndSend(new WhiteboardShapeText(id(), currentColor,
+ new WhiteboardPoint(x, y), defaultFontSize, t, s2w));
+ }
+
+ }
+
+ /**
+ * When a shap is modified we send a message with the new position rather
+ * than deleting the shape
+ */
+ private void releasedModif()
+ {
+ if (moving)
+ {
+ if (selectedShape == null)
+ return;
+ doneDrawing = true;
+ sendMoveShape(selectedShape);
+ selectedShape = null;
+ moving = false;
+ repaint();
+ }
+ }
+
+ /**
+ * When a shap is moved we send a message with the new position rather than
+ * deleting the shape
+ */
+ private void releasedMove()
+ {
+ if (moving)
+ {
+ if (selectedShape == null)
+ return;
+ doneDrawing = true;
+ sendMoveShape(selectedShape);
+ selectedShape = null;
+ moving = false;
+ repaint();
+ }
+ }
+
+ /**
+ * Returns a String uniquely identifying this WhiteboardFrame
+ *
+ * @return identifier of this WhiteboardFrame
+ */
+ private String id()
+ {
+ return String.valueOf(System.currentTimeMillis())
+ + String.valueOf(super.hashCode());
+ }
+
+ /**
+ * Translates current frame
+ *
+ * @param xTrans x coord
+ * @param yTrans y coord
+ */
+ private void translate(double xTrans, double yTrans)
+ {
+ if (w2s.getDeterminant() != 0)
+ {
+ w2s.translate(xTrans, yTrans);
+ try
+ {
+ s2w = w2s.createInverse();
+ }
+ catch (NoninvertibleTransformException e)
+ {
+ logger.debug(e.getMessage());
+ }
+ repaint();
+ }
+ }
+
+ /**
+ * Deselect all previously selected shapes.
+ */
+ private void deselect()
+ {
+ WhiteboardShape shape;
+ for (int i = 0; i < displayList.size(); i++)
+ {
+ shape = (WhiteboardShape) displayList.get(i);
+ shape.setSelected(false);
+ shape.setModifyPoint(null);
+ }
+ selectedShape = null;
+ }
+
+ /**
+ * Appends a Shape in the shape list and send it
+ *
+ * @param s shape to send and append
+ */
+ private void appendAndSend(WhiteboardShape s)
+ {
+ displayList.add(s);
+ repaint();
+ sendShape(s);
+ }
+
+ /**
+ * Method to send a shape.
+ *
+ * @param shape the white-board shape to send
+ */
+ private void sendShape(WhiteboardShape shape)
+ {
+ WhiteboardObject wbObject;
+
+ try
+ {
+ wbObject = sessionManager.sendWhiteboardObject(session, shape);
+
+ if (wbObject != null)
+ shape.setID(wbObject.getID());
+ }
+ catch (OperationFailedException ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Method to send an existing shape (to move/modify it).
+ *
+ * @param shape the white-board shape to send
+ */
+ private void sendMoveShape(WhiteboardShape shape)
+ {
+ sessionManager.moveWhiteboardObject(session, shape);
+ }
+
+ /**
+ * Method to delete a shape at the contact.
+ *
+ * @param shape the white-board shape to delete
+ */
+ private void sendDeleteShape(WhiteboardShape shape)
+ {
+ sessionManager.deleteWhiteboardObject(session, shape);
+ }
+
+ /**
+ * Method for add a WhiteboardObject into this frame.
+ *
+ * @param wbo WhiteboardObject to add
+ */
+ public void receiveWhiteboardObject(WhiteboardObject wbo)
+ {
+ logger.debug("receiveWhiteboardObject: " + wbo.getID());
+ WhiteboardShape ws = createWhiteboardShape(wbo);
+ for (int i = 0; i < displayList.size(); i++)
+ {
+ WhiteboardShape wbs = (WhiteboardShape) displayList.get(i);
+ if (wbs.getID().equals(wbo.getID()))
+ {
+ displayList.set(i, ws);
+ repaint();
+ return;
+ }
+ }
+ displayList.add(ws);
+ repaint();
+ }
+
+ /**
+ * Method for delete a WhiteboardObject in this frame.
+ *
+ * @param id WhiteboardObject's identifier to delete
+ */
+ public void receiveDeleteWhiteboardObject(String id)
+ {
+ logger.debug("receiveDeleteWhiteboardObject");
+ int i = 0;
+ while (i < displayList.size())
+ {
+ WhiteboardShape wbs = (WhiteboardShape) displayList.get(i);
+ if (id.equals(wbs.getID()))
+ displayList.remove(i);
+ else
+ i++;
+ }
+ repaint();
+ return;
+ }
+
+ /**
+ * Method to create/convert a WhiteboardShape with a WhiteboardObject.
+ *
+ * @param wbo WhiteboardObject to convert
+ * @return WhiteboardShape
+ */
+ private WhiteboardShape createWhiteboardShape(WhiteboardObject wbo)
+ {
+ logger.debug("CreateWhiteboardShape");
+ WhiteboardShape wShape = null;
+ String id = wbo.getID();
+ int color = wbo.getColor();
+ int t = wbo.getThickness();
+
+ if (wbo instanceof WhiteboardObjectPath)
+ {
+ WhiteboardObjectPath path = (WhiteboardObjectPath) wbo;
+ logger.debug("[log] : WB_PATH");
+ Color c = Color.getColor("", color);
+ List points = path.getPoints();
+ wShape = new WhiteboardShapePath(id, t, c, points);
+ }
+ else if (wbo instanceof WhiteboardObjectPolyLine)
+ {
+ WhiteboardObjectPolyLine pLine = (WhiteboardObjectPolyLine) wbo;
+ logger.debug("[log] : WB_POLYLINE");
+ Color c = Color.getColor("", color);
+ List points = pLine.getPoints();
+ wShape = new WhiteboardShapePolyLine(id, t, c, points, false);
+
+ }
+ else if (wbo instanceof WhiteboardObjectPolygon)
+ {
+ WhiteboardObjectPolygon polygon = (WhiteboardObjectPolygon) wbo;
+ logger.debug("[log] : WB_POLYGON");
+ Color c = Color.getColor("", color);
+ List points = polygon.getPoints();
+ boolean fill = polygon.isFill();
+ wShape = new WhiteboardShapePolygon(id, t, c, points, fill);
+
+ }
+ else if (wbo instanceof WhiteboardObjectLine)
+ {
+ WhiteboardObjectLine line = (WhiteboardObjectLine) wbo;
+ logger.debug("[log] : WB_LINE");
+ WhiteboardPoint pStart = line.getWhiteboardPointStart();
+ WhiteboardPoint pEnd = line.getWhiteboardPointEnd();
+ Color c = Color.getColor("", color);
+ wShape = new WhiteboardShapeLine(id, t, c, pStart, pEnd);
+
+ }
+ else if (wbo instanceof WhiteboardObjectRect)
+ {
+ WhiteboardObjectRect rect = (WhiteboardObjectRect) wbo;
+ logger.debug("[log] : WB_RECT");
+ Color c = Color.getColor("", color);
+ double height, width;
+ WhiteboardPoint p = rect.getWhiteboardPoint();
+ width = rect.getWidth();
+ height = rect.getHeight();
+ boolean fill = rect.isFill();
+ wShape = new WhiteboardShapeRect(id, t, c, p, width, height, fill);
+
+ }
+ else if (wbo instanceof WhiteboardObjectCircle)
+ {
+ WhiteboardObjectCircle circle = (WhiteboardObjectCircle) wbo;
+ logger.debug("[log] : WB_CIRCLE");
+ Color c = Color.getColor("", color);
+ WhiteboardPoint p = circle.getWhiteboardPoint();
+ double r = circle.getRadius();
+ boolean fill = circle.isFill();
+ wShape = new WhiteboardShapeCircle(id, t, c, p, r, fill);
+
+ }
+ else if (wbo instanceof WhiteboardObjectText)
+ {
+ WhiteboardObjectText text = (WhiteboardObjectText) wbo;
+ logger.debug("[log] : WB_TEXT");
+ Color c = Color.getColor("", color);
+ WhiteboardPoint p = text.getWhiteboardPoint();
+ int size;
+ String txt, fontFamily;
+ size = text.getFontSize();
+ txt = text.getText();
+ fontFamily = text.getFontName();
+ wShape = new WhiteboardShapeText(id, c, p, size, txt);
+
+ }
+ else if (wbo instanceof WhiteboardObjectImage)
+ {
+ WhiteboardObjectImage img = (WhiteboardObjectImage) wbo;
+ logger.debug("[log] : WB_IMAGE");
+ Color c = Color.getColor("", color);
+ double height, width;
+ WhiteboardPoint p = img.getWhiteboardPoint();
+ width = img.getWidth();
+ height = img.getHeight();
+ byte[] b = img.getBackgroundImage();
+ wShape = new WhiteboardShapeImage(id, p, width, height, b);
+ }
+ return wShape;
+ }
+
+ /**
+ * Deletes currently selected shape.
+ */
+ public void deleteSelected()
+ {
+ WhiteboardShape s;
+ int i = 0;
+ while (i < displayList.size())
+ {
+ s = (WhiteboardShape) displayList.get(i);
+ if (s.isSelected())
+ {
+ this.sendDeleteShape(s);
+ displayList.remove(i);
+ }
+ else
+ i++;
+ }
+ repaint();
+ }
+
+ /**
+ * Call a color chooser for the current selected shape
+ */
+ public void chooseColor()
+ {
+ if (selectedShape != null)
+ {
+ colorChooser.setColor(new Color(selectedShape.getColor()));
+ }
+
+ if (colorChooserDialog == null)
+ {
+ ActionListener okListener = new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ currentColor = colorChooser.getColor();
+ jLabelColor.setBackground(currentColor);
+ colorChooserDialog.setVisible(false);
+
+ if (selectedShape != null)
+ {
+ selectedShape.setColor(currentColor);
+ sendMoveShape(selectedShape);
+ repaint();
+ }
+ }
+ };
+
+ ActionListener cancelListener = new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ colorChooserDialog.setVisible(false);
+ }
+ };
+
+ colorChooserDialog =
+ JColorChooser.createDialog(this, "Choose a color", false,
+ colorChooser, okListener, cancelListener);
+ }
+
+ colorChooserDialog.setVisible(true);
+ }
+
+ /**
+ * Sets the current contact. (temporary) -> WhiteboardParticipant
+ *
+ * @param c Contact to use in the WhiteboardFrame
+ */
+ public void setContact(Contact c)
+ {
+ this.contact = c;
+ this.setTitle(getTitle() + " - " + contact.getDisplayName());
+ }
+
+ /**
+ * Returns contact used in this WhiteboardFrame.
+ *
+ * @return used Contact in the WhiteboardFrame
+ */
+ public Contact getContact()
+ {
+ return this.contact;
+ }
+
+ /**
+ * Current WhiteboardSession used in the WhiteboardFrame.
+ *
+ * @return current WhiteboardSession
+ */
+ public WhiteboardSession getWhiteboardSession()
+ {
+ return this.session;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardPanel.java b/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardPanel.java
new file mode 100644
index 0000000..cf91d71
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/whiteboard/gui/WhiteboardPanel.java
@@ -0,0 +1,296 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+
+package net.java.sip.communicator.plugin.whiteboard.gui;
+
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.awt.geom.AffineTransform;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import net.java.sip.communicator.plugin.whiteboard.gui.whiteboardshapes.*;
+
+/**
+ * Panel for drawing shapes
+ *
+ * @author Julien Waechter
+ */
+public class WhiteboardPanel
+ extends javax.swing.JPanel
+ implements Printable
+{
+ /**
+ * Shapes to display
+ */
+ private List displayList = new CopyOnWriteArrayList();
+
+ /**
+ * Default grid space
+ */
+ private int defaultGrid = 25;
+
+ private AffineTransform affineTrans;
+
+ /**
+ * True: display grid, false no grid.
+ */
+ private boolean grid = false;
+
+ /**
+ * Parent WhiteboardFrame
+ */
+ private WhiteboardFrame wf;
+
+ /**
+ * WhiteboardPanel constructor.
+ *
+ * @param displayList Shapes to display
+ * @param wf WhiteboardFrame
+ */
+ public WhiteboardPanel(List displayList, WhiteboardFrame wf)
+ {
+ super();
+ this.wf = wf;
+ this.displayList = displayList;
+ affineTrans = new AffineTransform();
+ affineTrans.setToScale(1, 1);
+ setBackground(Color.white);
+ initComponents();
+ }
+
+ /**
+ * Method to draw/hide grid
+ *
+ * @param grid if true, draw grid
+ */
+ public void drawGrid(boolean grid)
+ {
+ this.grid = grid;
+ }
+
+ /**
+ * Calls the UI delegate's paint method, if the UI delegate is non-<code>null</code>.
+ * We pass the delegate a copy of the <code>Graphics</code> object to
+ * protect the rest of the paint code from irrevocable changes (for example,
+ * <code>Graphics.translate</code>).
+ * <p>
+ * The passed in <code>Graphics</code> object might have a transform other
+ * than the identify transform installed on it. In this case, you might get
+ * unexpected results if you cumulatively apply another transform.
+ *
+ * @param g the <code>Graphics</code> object to protect
+ * @see #paint
+ * @see ComponentUI
+ */
+ public void paintComponent(Graphics g)
+ {
+ super.paintComponent(g);
+
+ Graphics2D g2 = (Graphics2D) g;
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+
+ if (grid)
+ {
+ for (int x = 0; x < this.getWidth(); x += defaultGrid)
+ {
+ for (int y = 0; y < this.getHeight(); y += defaultGrid)
+ {
+ g.setColor(Color.LIGHT_GRAY);
+ g.fillOval(x, y, 2, 2);
+ }
+ }
+ }
+ WhiteboardShape s;
+ for (int i = 0; i < displayList.size(); i++)
+ {
+ s = (WhiteboardShape) displayList.get(i);
+ s.paint(g, affineTrans);
+ }
+ }
+
+ /**
+ * Prints the page at the specified index into the specified
+ * {@link Graphics} context in the specified format. A
+ * <code>PrinterJob</code> calls the <code>Printable</code> interface to
+ * request that a page be rendered into the context specified by
+ * <code>graphics</code>. The format of the page to be drawn is specified
+ * by <code>pageFormat</code>. The zero based index of the requested page
+ * is specified by <code>pageIndex</code>. If the requested page does not
+ * exist then this method returns NO_SUCH_PAGE; otherwise PAGE_EXISTS is
+ * returned. The <code>Graphics</code> class or subclass implements the
+ * {@link PrinterGraphics} interface to provide additional information. If
+ * the <code>Printable</code> object aborts the print job then it throws a
+ * {@link PrinterException}.
+ *
+ * @param graphics the context into which the page is drawn
+ * @param pageFormat the size and orientation of the page being drawn
+ * @param pageIndex the zero based index of the page to be drawn
+ * @return PAGE_EXISTS if the page is rendered successfully or NO_SUCH_PAGE
+ * if <code>pageIndex</code> specifies a non-existent page.
+ */
+ public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
+ {
+ return NO_SUCH_PAGE;
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code
+ // ">//GEN-BEGIN:initComponents
+ private void initComponents()
+ {
+ popupMenu = new javax.swing.JPopupMenu();
+ copyPopupMenuItem = new javax.swing.JMenuItem();
+ pastePopupMenuItem = new javax.swing.JMenuItem();
+ colorPopupMenuItem = new javax.swing.JMenuItem();
+ propetiesPopupMenuItem = new javax.swing.JMenuItem();
+ deletePopupMenuItem = new javax.swing.JMenuItem();
+
+ copyPopupMenuItem.setText("Copy");
+ popupMenu.add(copyPopupMenuItem);
+
+ pastePopupMenuItem.setText("Paste");
+ popupMenu.add(pastePopupMenuItem);
+
+ colorPopupMenuItem.setText("Color");
+ colorPopupMenuItem
+ .addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ colorPopupMenuItemActionPerformed(evt);
+ }
+ });
+
+ popupMenu.add(colorPopupMenuItem);
+
+ propetiesPopupMenuItem.setText("Properties");
+ popupMenu.add(propetiesPopupMenuItem);
+
+ deletePopupMenuItem.setText("Delete");
+ deletePopupMenuItem
+ .addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ deletePopupMenuItemActionPerformed(evt);
+ }
+ });
+
+ popupMenu.add(deletePopupMenuItem);
+
+ setLayout(null);
+
+ addMouseListener(new java.awt.event.MouseAdapter()
+ {
+ public void mousePressed(java.awt.event.MouseEvent evt)
+ {
+ formMousePressed(evt);
+ }
+
+ public void mouseReleased(java.awt.event.MouseEvent evt)
+ {
+ formMouseReleased(evt);
+ }
+ });
+
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * Invoked when an action occurs on the delete popup menu.
+ *
+ * @param evt
+ */
+ private void deletePopupMenuItemActionPerformed(
+ java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_deletePopupMenuItemActionPerformed
+ wf.deleteSelected();
+ }// GEN-LAST:event_deletePopupMenuItemActionPerformed
+
+ /**
+ * Invoked when an action occurs on the color popup menu.
+ *
+ * @param evt
+ */
+ private void colorPopupMenuItemActionPerformed(
+ java.awt.event.ActionEvent evt)
+ {// GEN-FIRST:event_colorPopupMenuItemActionPerformed
+ wf.chooseColor();
+ }// GEN-LAST:event_colorPopupMenuItemActionPerformed
+
+ /**
+ * Invoked when a mouse button has been released on the WhiteboardPanel.
+ *
+ * @param evt
+ */
+ private void formMouseReleased(java.awt.event.MouseEvent evt)
+ {// GEN-FIRST:event_formMouseReleased
+ checkPopupEvent(evt);
+ }// GEN-LAST:event_formMouseReleased
+
+ /**
+ * Invoked when a mouse button has been pressed on the WhiteboardPanel.
+ *
+ * @param evt
+ */
+ private void formMousePressed(java.awt.event.MouseEvent evt)
+ {// GEN-FIRST:event_formMousePressed
+ checkPopupEvent(evt);
+ }// GEN-LAST:event_formMousePressed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JMenuItem colorPopupMenuItem;
+
+ private javax.swing.JMenuItem copyPopupMenuItem;
+
+ private javax.swing.JMenuItem deletePopupMenuItem;
+
+ private javax.swing.JMenuItem pastePopupMenuItem;
+
+ private javax.swing.JPopupMenu popupMenu;
+
+ private javax.swing.JMenuItem propetiesPopupMenuItem;
+
+ // End of variables declaration//GEN-END:variables
+
+ /**
+ * Manage popup event
+ *
+ * @param e MouseEvent
+ */
+ private void checkPopupEvent(MouseEvent e)
+ {
+ copyPopupMenuItem.setEnabled(false);
+ pastePopupMenuItem.setEnabled(false);
+ colorPopupMenuItem.setEnabled(false);
+ propetiesPopupMenuItem.setEnabled(false);
+ deletePopupMenuItem.setEnabled(false);
+
+ if (e.isPopupTrigger())
+ {
+ if (wf.getSelectedShape() != null)
+ {
+ copyPopupMenuItem.setEnabled(true);
+ colorPopupMenuItem.setEnabled(true);
+ propetiesPopupMenuItem.setEnabled(true);
+ deletePopupMenuItem.setEnabled(true);
+ }
+
+ if (wf.getCopiedShape() != null)
+ {
+ pastePopupMenuItem.setEnabled(true);
+ }
+ if (e.getButton() == e.BUTTON3)
+ popupMenu.show(e.getComponent(), e.getX(), e.getY());
+ }
+ }
+} \ No newline at end of file