import java.awt.*; import java.applet.*; import java.awt.event.*; public class Sketching extends Applet implements MouseListener { /* * When the user release the mouse, we'll make changes to these * and then invoke repaint to install them */ private Graphics nextGraphics; private Image nextImage; /* * Dimensions of the applet, itself */ Dimension appletDim; /* * Start and finish of graphics objects, such as line, oval, rectangle, etc. */ private Point start, finish; /* * Checkboxes to select paint color */ private CheckboxGroup color; private Checkbox white, yellow, red, green, blue; /* * Checkboxes to select paint shape */ private CheckboxGroup shape; private Checkbox line, openOval, oval, openRectangle, rectangle; /* * This method forces a point within the area. * Negative coordiantes become 0. * Too large coordiantes become dim.width-1 or dim.height-1 */ private void fixPoint (Point point, Dimension dim) { int temp; if (point.x >= dim.width) point.x = dim.width-1; if (point.x < 0) point.x = 0; if (point.y >= dim.height) point.y = dim.height-1; if (point.y < 0) point.y = 0; } /* * This ensures that upper-left < lower-right. * x and/or y values are swapped, as necessary */ private void fixLineDirection (Point upperLeft, Point lowerRight) { int temp; if (upperLeft.x > lowerRight.x) { temp = upperLeft.x; upperLeft.x = lowerRight.x; lowerRight.x = temp; } if (upperLeft.y > lowerRight.y) { temp = upperLeft.y; upperLeft.y = lowerRight.y; lowerRight.y = temp; } } /* * This checks the state of the checkboxes and * sets the color for the specified graphics area accordingly */ private void setGraphicsColor (Graphics g) { // The getState() only returns true if the option has been selected. if (red.getState()) g.setColor (Color.red); if (yellow.getState()) g.setColor (Color.yellow); if (white.getState()) g.setColor (Color.white); if (green.getState()) g.setColor (Color.green); if (blue.getState()) g.setColor (Color.blue); } /* * This checks the status of the shape check boxes * as well as the start and finish points and * draws the specified shape in the previosuly set (or default) * color */ private void drawShapeToGraphics (Graphics g) { /* * Lines can be drawn in any direction -- and differ with direction * Other shapes are upper-left to lower-right, only. * So, if it isn't a line, we rework the coordinates to ensure that * they are in the right format */ if (!line.getState()) // Note: The getState() only returns true if the option has been selected. fixLineDirection (start, finish); /* * Now, we check to make sure the points are within the drawable * area, if not, we truncate the object at the edge of the area */ fixPoint (start, appletDim); fixPoint (finish, appletDim); /* * Now, that we've got the right control points, we draw the appropriate * shape into the buffer. */ if (line.getState()) g.drawLine (start.x, start.y, finish.x, finish.y); if (oval.getState()) g.fillOval (start.x, start.y, finish.x-start.x, finish.y-start.y); if (openOval.getState()) g.drawOval (start.x, start.y, finish.x-start.x, finish.y-start.y); if (rectangle.getState()) g.fillRect (start.x, start.y, finish.x-start.x, finish.y-start.y); if (openRectangle.getState()) g.drawRect (start.x, start.y, finish.x-start.x, finish.y-start.y); /* * Now, we make that buffer visible. * repaint() calls paint() */ repaint(); } /* * This method is called when the applet is initialized * In this case, it is setting up the two lists of radio boxes * and the drawing area */ public void init() { appletDim = getSize(); // size of the applet, itself /* * Build radio button group for color. Only one can be true * for a radio button */ color = new CheckboxGroup(); red = new Checkbox ("red", color, true); white = new Checkbox ("white", color, false); yellow = new Checkbox ("yellow", color, false); green = new Checkbox ("green", color, false); blue = new Checkbox ("blue", color, false); /* * Build radio button group for shapes. Only one can be true * for a radio button */ shape = new CheckboxGroup(); line = new Checkbox ("line", shape, true); oval = new Checkbox ("oval", shape, false); openOval = new Checkbox ("open oval", shape, false); rectangle = new Checkbox ("rectangle", shape, false); openRectangle = new Checkbox ("open rectangle", shape, false); /* * Figure out how much room we have to draw */ nextImage = createImage (appletDim.width, appletDim.height); nextGraphics = nextImage.getGraphics(); nextGraphics.setColor (Color.white); nextGraphics.fillRect (0,0, appletDim.width, appletDim.height); /* * Give the applet a layout with a large center region surrounded * by 4 border regions, "North", "South", "East" and "West". */ setLayout (new BorderLayout()); /* * Put the color selection into the left ("West") bar on the * screen */ Panel leftColumn = new Panel(); leftColumn.setLayout (new GridLayout (5, 1)); leftColumn.setBackground (Color.white); leftColumn.add (red); leftColumn.add (white); leftColumn.add (yellow); leftColumn.add (green); leftColumn.add (blue); add (leftColumn, BorderLayout.WEST); /* * Put the shape selection into the right ("East") bar on the * screen */ Panel rightColumn = new Panel(); rightColumn.setLayout (new GridLayout(5,1)); rightColumn.add (line); rightColumn.add (oval); rightColumn.add (openOval); rightColumn.add (rectangle); rightColumn.add (openRectangle); rightColumn.setBackground (Color.white); add (rightColumn, BorderLayout.EAST); /* * Instruct the applet to watch for mouse events */ addMouseListener(this); } /* * This is used, sometimes automatically, and sometimes * explicitly by the program, to redraw the screen * In this case, we prepare "nextImage" in advance. * When we wnat to redraw the screen, for example after a mouse * event that adds an object, we adjust nextImage, and then * call repaint(), which in turn calls this method. */ public void paint(Graphics g) { g.drawImage (nextImage, 0, 0, this); } /* * If the mouse is pressed, it is a starting point. * So, we want to mark it with a dot and store it for later, * so we can draw the obejct */ public void mousePressed (MouseEvent me) { // This saves the current position start = new Point (me.getX(), me.getY()); // Check the state of the color menu and set the color accordingly setGraphicsColor (nextGraphics); // Force the coordinates "in bounds" fixPoint (start, appletDim); // Draw the dot, a 1-dot line, and reapint the screen so it can be seen nextGraphics.drawLine (start.x, start.y, start.x, start.y); repaint(); } /* * When the mouse is released it is time to draw the object. * So, we find the point, set the color, and draw the right shape */ public void mouseReleased (MouseEvent me) { // Save the end point finish = new Point (me.getX(), me.getY()); // Check the menus and save the color setGraphicsColor (nextGraphics); // Clean-up start and finish values as necesary, then consult // the shape menu, and draw the right shape. drawShapeToGraphics (nextGraphics); // Call repaint, so the change can be seen. repaint(); } /* * We didn't need these actions. But, we do need to * define them, or we haven't complied with the * MouseAction interface. */ // This is received, if the user momentarily presses the mouse button public void mouseClicked (MouseEvent me) {} // This is received, if the mouse enters the applet area from outside public void mouseEntered (MouseEvent me) {} // This is received, if the mouse exits the applet area from outside public void mouseExited (MouseEvent me) {} }