// DrawCanvas.java // Most of the drawing functionality is provided here, // although a little bit is done in Toolbar.java and other files. // S. Tanimoto, 1 Feb. 2000. import java.awt.*; import java.awt.event.*; import java.util.*; public class DrawCanvas extends Canvas { PolyDraw pd; // reference to Applet Vector theDrawnObjects; DrawnObject currentObject; Controls ct; // reference to Controls panel boolean selecting, movingSelection; SelectionRect selectionRect; Vector selection; DrawCanvas(PolyDraw thePD) { pd = thePD; ct = pd.getControls(); theDrawnObjects = new Vector(); MouseHandlerForDrawCanvas mh = new MouseHandlerForDrawCanvas(); addMouseListener(mh); addMouseMotionListener(mh); selectionRect = new SelectionRect(); selecting = false; movingSelection = false; selection = new Vector(); } public void addObject(DrawnObject anObject) { theDrawnObjects.addElement(anObject); currentObject = anObject; } public void cancelSelecting() { selecting = false; movingSelection = false; } public void paint(Graphics g) { g.setColor(Color.black); for (Enumeration enum = theDrawnObjects.elements(); enum.hasMoreElements();) { DrawnObject dObject = (DrawnObject) enum.nextElement(); dObject.paint(g); } if (selecting) selectionRect.paint(g); } class MouseHandlerForDrawCanvas extends MouseAdapter implements MouseMotionListener { private int savedMouseX, savedMouseY; public void mousePressed(MouseEvent e) { int x = e.getX(); int y = e.getY(); if (ct.usingGrid()) { x = snapToGrid(x); y = snapToGrid(y); } String currentTool = pd.getToolbar().whichTool(); if (currentTool.equals("Poly")) { if (currentObject == null) return; Polygon thisPoly = (Polygon)currentObject; if (thisPoly.lastVertexNotAt(x, y)) thisPoly.addVertex(new PDPoint(x, y)); } else if (currentTool.equals("Edit")) { if (hitSelected(selection, e.getX(), e.getY())) { savedMouseX = e.getX(); savedMouseY = e.getY(); movingSelection = true; } else { for (Enumeration vEnum = selection.elements(); vEnum.hasMoreElements();) { ((PDPoint)vEnum.nextElement()).unmark(); } selectionRect.setP1(e.getX(), e.getY()); selecting = true; movingSelection = false; } } repaint(); } public void mouseDragged (MouseEvent e) { if (selecting) { selectionRect.setP2(e.getX(), e.getY()); repaint(); } else if (movingSelection) { int x = e.getX(); int y = e.getY(); if (ct.usingGrid()) { x = snapToGrid(x); y = snapToGrid(y); } int deltaX = x - savedMouseX; int deltaY = y - savedMouseY; updateSelectedPoints(selection, deltaX, deltaY); savedMouseX += deltaX; savedMouseY += deltaY; repaint(); } } public void mouseMoved (MouseEvent e) {} public void mouseEntered (MouseEvent e) {} public void mouseExited (MouseEvent e) {} public void mouseClicked (MouseEvent e) { if (e.getClickCount() == 2) { ((Polygon)currentObject).close(); currentObject = null; repaint(); } } public void mouseReleased(MouseEvent e) { if (selecting) { selection = selectionRect.computeSelection(theDrawnObjects); selecting = false; System.out.println("Number of selected items is " + selection.size()); } else if (movingSelection) movingSelection = false; repaint(); } } public void deleteSelected() { System.out.println("Deleting the selected points from their respective Polygons"); for (Enumeration enum = theDrawnObjects.elements(); enum.hasMoreElements();) { DrawnObject dObject = (DrawnObject) enum.nextElement(); System.out.println("Considering an object of type:" + dObject.getClass() + "."); if ((dObject.getClass().toString()).equals("class Polygon")) { Vector vertices = ((Polygon)dObject).getVertices(); System.out.println("Processing this polygon of degree " + vertices.size()); for (Enumeration vEnum = selection.elements(); vEnum.hasMoreElements();) { vertices.removeElement((PDPoint) vEnum.nextElement()); } } } // deletePointsFromPolygons(selection, theDrawnObjects); repaint(); } public int snapToGrid(int coord) { int gridSpacing = ct.getGridSpacing(); int newCoord = (coord / gridSpacing) * gridSpacing + (gridSpacing / 2); return newCoord; } private static boolean hitSelected(Vector vec, int x, int y) { // Return true if (x,y) is close to any vertex in vec. int RADIUS_SQUARED = 64; // radius is 8. for (Enumeration vEnum = vec.elements(); vEnum.hasMoreElements();) { PDPoint p = (PDPoint) vEnum.nextElement(); int dx = p.x - x; int dy = p.y - y; int dist = (dx * dx) + (dy * dy); if (dist < RADIUS_SQUARED) return true; } return false; } private static void updateSelectedPoints(Vector vec, int dx, int dy) { // Move all the selected points by (dx, dy). for (Enumeration vEnum = vec.elements(); vEnum.hasMoreElements();) { PDPoint p = (PDPoint) vEnum.nextElement(); p.setLocation(p.x + dx, p.y + dy); } } } class SelectionRect { int x1, y1, x2, y2, minx, miny, maxx, maxy; SelectionRect() { } void setP1(int x, int y) { x1 = x; y1 = y; x2 = x; y2 = y; } void setP2(int x, int y) { x2 = x; y2 = y; } void sort() { minx = Math.min(x1,x2); miny = Math.min(y1,y2); maxx = Math.max(x1,x2); maxy = Math.max(y1,y2); } void paint(Graphics g) { sort(); Color oldColor = g.getColor(); g.setColor(Color.red); g.drawRect(minx, miny, maxx - minx, maxy - miny); g.setColor(oldColor); } Vector computeSelection(Vector objList) { Vector sel = new Vector(); for (Enumeration enum = objList.elements(); enum.hasMoreElements();) { DrawnObject dObject = (DrawnObject) enum.nextElement(); System.out.println("Considering an object of type:" + dObject.getClass() + "."); if ((dObject.getClass().toString()).equals("class Polygon")) { System.out.println("Processing this polygon of degree " + ((Polygon)dObject).getVertices().size()); for (Enumeration vEnum = ((Polygon)dObject).getVertices().elements(); vEnum.hasMoreElements();) { PDPoint vertex = (PDPoint) vEnum.nextElement(); int px = vertex.x; int py = vertex.y; System.out.println("Considering vertex:(" + vertex.x +", " + vertex.y + ")"); if ((minx <= px) && (px <= maxx) && (miny <= py) && (py <= maxy)) { sel.addElement(vertex); vertex.mark(); } } } } return sel; } }