import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.util.*; /** * Class LineDrawingListener extends Java's MouseInputAdpater to provide * handlers for three mouse events: mouse pressed, mouse dragged, and mouse * released. The comments for the event-handling methods describe in * detail what each method does to allow the user to draw lines. *
* The general drawing strategy is to add and remove lines from the * canvas shapeList as the mouse is being dragged, repainting the canvas at * each addition. Since repainting is done efficiently by Java, this * technique is visually OK even if the canvas shapeList contains a large * number of other lines to be drawn. */ public class LineDrawingListener extends MouseInputAdapter { private DrawingCanvas canvas; private WorkSpace workSpace; /** The starting x-axis position for drawing a shape */ private int startX; /** The starting y-axis position for drawing a shape */ private int startY; /** Quadrant-I normalized value of startY */ private int nStartY; /** Starting x,y as a point */ private Point startXY; /** True if the user is moving the mouse. */ private boolean moving = false; public LineDrawingListener(DrawingCanvas canvas, WorkSpace workSpace) { this.canvas = canvas; this.workSpace = workSpace; } /** * Record the initial mouse press as the starting point of the * line to be drawn. Add a single-point line to the * shapeList to start off the add/remove drawing process. In this way, * mouseDragged will do a remove first, then add a new line. */ public void mousePressed(MouseEvent e) { Shape selection = workSpace.getSelection(); if (selection != null) { selection.selected = false; } int ch = canvas.getHeight(); startX = e.getX(); startY = e.getY(); nStartY = ch - startY; // System.out.println("startX=" + startX + ", startY=" + startY); workSpace.add(new Line(startXY = new Point(startX, nStartY), new Point(startX, nStartY), Color.BLACK, false)); moving = true; } /** * Remove the previously drawn line and add a new one that extends from * the starting point to the current mouse position. Then call * canvas.repaint, which will efficiently redraw the entire canvas, * including all of the other items in the shapeList. */ public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); int ch = canvas.getHeight(); int ny = ch - y; int width = x - startX; int height = y - startY; // System.out.println( // "Mouse dragged in panel at " + e.getX() + "," + e.getY()); workSpace.remove(workSpace.size() - 1); workSpace.add(new Line( startXY, new Point(x, ny), Color.BLACK, false)); /* workSpace.add(new Line( startXY, new Point( width >= 0 ? startX : x, height >= 0 ? nStartY : ny), Color.BLACK, false)); */ canvas.repaint(); /* * The following might look like an alternative implementation, * however it produces a smearing effect, since lines drawn in * previous invocations of mouseDragged are not erased. * g2.drawLine( startX, startY, e.getX() - startX, e.getY() - startY); * */ } /** * Remove the previously drawn line and add a new line in its final * position. Then call repaint. */ public void mouseReleased(MouseEvent e) { int x = e.getX(); int y = e.getY(); int ch = canvas.getHeight(); int ny = ch - y; int width = x - startX; int height = y - startY; Line line; workSpace.remove(workSpace.size() - 1); workSpace.add(line = new Line( startXY, new Point(x, ny), Color.BLACK, false)); /* workSpace.add(line = new Line( startXY, new Point( width >= 0 ? startX : x, height >= 0 ? nStartY : ny), Color.BLACK, false)); */ // System.out.println(x + "," + y + "," + width + "," + height); moving = false; line.selected = true; workSpace.setSelection(line); canvas.repaint(); } }