import java.awt.*; import java.awt.event.*; import java.applet.Applet; /** * A Java applet which implements a drawing pad. It allows the * user to create several different shapes, including: *

* The user can specify which color these shapes are made in, as well * as whether they are filled or hollow. * * @author Hans Wild * @version 1.0 (Nov. 2000) * @see java.applet.Applet */ public class DrawPad extends Applet implements MouseListener, MouseMotionListener, ItemListener, ActionListener { //============================================================== // Instance Variables private Point last, curr, start; public Choice colors, shapes = null; public Checkbox filled; public Label instructions; public Button clear; private String currShape, currFill; private Color currColor; private int lastWidth, lastHeight, currWidth, currHeight; private int xPoints[], yPoints[]; /** * Initialization routine for the DrawPad class. * Initializes variables, creates controls and also creates * three panels to arrange controls on the screen. */ public void init() { setLayout(new BorderLayout()); setBackground(Color.white); //Create Panels needed for Border Layout Panel topPanel = new Panel(); topPanel.setLayout(new GridLayout(2,1)); Panel controlPanel = new Panel(); Panel instructPanel = new Panel(); Panel clearPanel = new Panel(); //Set initial control values currFill = "N"; currColor = Color.black; currShape = "Rectangle"; //Create and initialize arrays used for triangle creation xPoints = new int[3]; yPoints = new int[3]; xPoints[0] = -1; yPoints[0] = -1; xPoints[1] = -1; yPoints[1] = -1; xPoints[2] = -1; yPoints[2] = -1; //Add Listeners for Mouse addMouseListener(this); addMouseMotionListener(this); //Create shape control and add to panel Label shapeLabel = new Label("Shape:", Label.RIGHT); shapes = new Choice(); shapes.addItem("Rectangle"); shapes.addItem("Oval"); shapes.addItem("Line"); shapes.addItem("Triangle"); shapes.addItemListener(this); controlPanel.add(shapeLabel); controlPanel.add(shapes); //Create color control and add to panel Label colorLabel = new Label("Color:", Label.RIGHT); colors = new Choice(); colors.addItem("Black"); colors.addItem("Blue"); colors.addItem("Cyan"); colors.addItem("Dark Gray"); colors.addItem("Gray"); colors.addItem("Green"); colors.addItem("Magenta"); colors.addItem("Orange"); colors.addItem("Pink"); colors.addItem("Red"); colors.addItem("Yellow"); colors.addItemListener(this); controlPanel.add(colorLabel); controlPanel.add(colors); //Create fill control and add to panel filled = new Checkbox("Filled"); controlPanel.add(filled); filled.addItemListener(this); //Create clear button and add to panel clear = new Button("Clear Drawing Area"); clearPanel.add(clear); clear.addActionListener(this); //Create instruction label and add to panel instructions = new Label (" Hold Left Mouse button and drag to create a rectangle ", Label.CENTER); instructPanel.add(instructions); //Add Panels to window in correct location topPanel.add(controlPanel); topPanel.add(instructPanel); add("North", topPanel); add("South", clearPanel); } /** * Dummy event inserted for MouseListener interface * * @param e MouseEvent object */ public void mouseEntered(MouseEvent e){ } /** * Records the point where the mouse is pressed to be used as an * origin point for the shape being drawn. * * @param e MouseEvent object, used to get point at mouse location */ public void mousePressed(MouseEvent e){ if (currShape == "Line"){ curr = e.getPoint(); last = e.getPoint(); } else if (currShape == "Rectangle" || currShape == "Oval") { start = e.getPoint(); curr = e.getPoint(); last = e.getPoint(); lastWidth = 0; lastHeight = 0; currWidth = 0; currHeight = 0; } } /** * Records the point where the mouse is clicked during the * creation of a triangle. If it is the second or third * point, a line is drawn between the points already set. * If it is the third point, the triangle is filled if needed, * and the arrary of points is reinitialized. * * @param e MouseEvent object, used to get point at mouse location */ public void mouseClicked(MouseEvent e){ if (currShape == "Triangle") { if (xPoints[0] == -1) { //First Point Clicked xPoints[0] = e.getX(); yPoints[0] = e.getY(); last = e.getPoint(); } else if (xPoints[1] == -1) { //Second Point Clicked xPoints[1] = e.getX(); yPoints[1] = e.getY(); Graphics g = getGraphics(); //Erase last rubberband line g.drawLine(xPoints[0],yPoints[0],last.x,last.y); g.setColor(currColor); //Draw Permanent Line from Point 1 to 2 g.drawLine(xPoints[0],yPoints[0],xPoints[1],yPoints[1]); } else if (xPoints[2] == -1) { //Third Point Clicked xPoints[2] = e.getX(); yPoints[2] = e.getY(); Graphics g = getGraphics(); //Erase last rubberband line g.drawLine(xPoints[1],yPoints[1],last.x,last.y); g.setColor(currColor); //Draw Permanent Line from Point 1 to 3 and 2 to 3 g.drawLine(xPoints[1],yPoints[1],xPoints[2],yPoints[2]); g.drawLine(xPoints[2],yPoints[2],xPoints[0],yPoints[0]); //Fill Triangle if needed if (currFill == "Y") { g.fillPolygon(xPoints,yPoints,3); } //Reinitialize array for next use xPoints[0] = -1; yPoints[0] = -1; xPoints[1] = -1; yPoints[1] = -1; xPoints[2] = -1; yPoints[2] = -1; } } } /** * Dummy event inserted for MouseListener interface * * @param e MouseEvent object */ public void mouseExited(MouseEvent e){ } /** * Records point where mouse button is released and draws * appropriate shape, filling if needed. * * @param e MouseEvent object, used to get point at mouse location */ public void mouseReleased(MouseEvent e){ if (currShape == "Rectangle") { curr = e.getPoint(); Graphics g = getGraphics(); //Erase last rubberband rectangle g.drawRect(last.x, last.y, lastWidth, lastHeight); g.setColor(currColor); //Draw rectangle (filled or not) if (currFill == "Y") g.fillRect(Math.min(start.x, curr.x), Math.min(start.y, curr.y), currWidth, currHeight); else g.drawRect(Math.min(start.x, curr.x), Math.min(start.y, curr.y), currWidth, currHeight); } else if (currShape == "Oval") { curr = e.getPoint(); Graphics g = getGraphics(); //Erase last rubberband Oval g.drawOval(last.x, last.y, lastWidth, lastHeight); g.setColor(currColor); //Draw Oval (filled or not) if (currFill == "Y") g.fillOval(Math.min(start.x, curr.x), Math.min(start.y, curr.y), currWidth, currHeight); else g.drawOval(Math.min(start.x, curr.x), Math.min(start.y, curr.y), currWidth, currHeight); } } /** * Dummy event inserted for MouseListener interface * * @param e MouseEvent object */ public void mouseEnter(MouseEvent e){ } /** * Records current point. In the case of a line, a line is drawn * between the last point and the current point. The * changeLastPoint() function is then called to * set the last point to the current point. *

* In the case of a rectangle or oval, a temporary shape is * created, and the previous temporary shape is erased. * This gives a "rubberbanding" effect toshape creation. * * @param e MouseEvent object, used to get point at mouse location * @see #changeLastPoint */ public void mouseDragged(MouseEvent e) { curr = e.getPoint(); if (currShape == "Line") { Graphics g = getGraphics(); g.setColor(currColor); //Draw Line from last point recorded to current point g.drawLine(last.x, last.y, curr.x, curr.y); //Change last recorded point to equal current point changeLastPoint(curr.x, curr.y); } else if (currShape == "Rectangle") { //Take absolute value to ensure height and width > 0 currWidth = Math.abs(curr.x - start.x); currHeight = Math.abs(curr.y - start.y); Graphics g = getGraphics(); //Set XOR mode for rubberbanding g.setXORMode(Color.lightGray); //Erase last rubberband rectangle g.drawRect(last.x, last.y, lastWidth, lastHeight); //Draw current rubberband rectangle g.drawRect(Math.min(start.x, curr.x), Math.min(start.y, curr.y), currWidth, currHeight); //Set last values equal to current values last.x = Math.min(start.x, curr.x); last.y = Math.min(start.y, curr.y); lastWidth = currWidth; lastHeight = currHeight; } else if (currShape == "Oval") { //Take absolute value to ensure height and width > 0 currWidth = Math.abs(curr.x - start.x); currHeight = Math.abs(curr.y - start.y); Graphics g = getGraphics(); //Set XOR mode for rubberbanding g.setXORMode(Color.lightGray); //Erase last rubberband oval g.drawOval(last.x, last.y, lastWidth, lastHeight); //Draw current rubberband oval g.drawOval(Math.min(start.x, curr.x), Math.min(start.y, curr.y), currWidth, currHeight); //Set last values equal to current values last.x = Math.min(start.x, curr.x); last.y = Math.min(start.y, curr.y); lastWidth = currWidth; lastHeight = currHeight; } } /** * Creates rubberbanding effect for creation of triangle. * This effect is created by drawing a temporary line from * the previous anchored point of the triangle to the current * point. The previous temporary line is erased. * * @param e MouseEvent object, used to get point at mouse location */ public void mouseMoved(MouseEvent e) { if (currShape == "Triangle") { if (xPoints[1] != -1) { //Rubberband from second vertex curr = e.getPoint(); Graphics g = getGraphics(); //Set XOR mode for rubberbanding g.setXORMode(Color.lightGray); //Erase last rubberband line g.drawLine(xPoints[1], yPoints[1], last.x, last.y); //Draw new rubberband line g.drawLine(xPoints[1], yPoints[1], curr.x, curr.y); //Set last point equal to current point last.x = curr.x; last.y = curr.y; } else if (xPoints[0] != -1) { //Rubberband from first point curr = e.getPoint(); Graphics g = getGraphics(); //Set XOR mode for rubberbanding g.setXORMode(Color.lightGray); //Erase last rubberband line g.drawLine(xPoints[0], yPoints[0], last.x, last.y); //Draw new rubberband line g.drawLine(xPoints[0], yPoints[0], curr.x, curr.y); //Set last point equal to current point last.x = curr.x; last.y = curr.y; } } } /** * Updates drawing instructions in window based on what shape is * selected in the choice box. * * @see #itemStateChanged */ protected void updateInstructions() { if (currShape == "Rectangle") instructions.setText(" Hold Left Mouse button and drag to create a rectangle "); else if (currShape == "Line") instructions.setText("Hold Left Mouse button and move mouse to create a line"); else if (currShape == "Oval") instructions.setText("Hold Left Mouse button and drag to create an oval"); else if (currShape == "Triangle") instructions.setText("Click Three Points with left mouse button to create a triangle"); else instructions.setText("Welcome to the DrawPad applet!!!"); } /** * Updates last point x and y values with new values * * @param xVal X coordinate of new point * @param yVal Y corrdinate of new point * @see #mouseDragged */ protected void changeLastPoint (int xVal, int yVal) { last.x = xVal; last.y = yVal; } /** * Updates current color, shape, or fill values based on which * control was changed. If shape was changed, * updateInstructions() is called to change * instructions to those required by new shape. * * @param e ItemEvent object, used to check which control was * changed and what value that control was changed to * @see #updateInstructions */ public void itemStateChanged(ItemEvent e) { //Get name of control being changed if (e.getItemSelectable() == colors) { //Get new color value String ms = ((Choice)e.getItemSelectable()).getSelectedItem(); //Set color variable if (ms == "Black") currColor = Color.black; else if (ms == "Blue") currColor = Color.blue; else if (ms == "Cyan") currColor = Color.cyan; else if (ms == "Dark Gray") currColor = Color.darkGray; else if (ms == "Gray") currColor = Color.gray; else if (ms == "Green") currColor = Color.green; else if (ms == "Magenta") currColor = Color.magenta; else if (ms == "Orange") currColor = Color.orange; else if (ms == "Pink") currColor = Color.pink; else if (ms == "Red") currColor = Color.red; else if (ms == "Yellow") currColor = Color.yellow; else currColor = Color.black; } //Get name of control being changed else if (e.getItemSelectable() == shapes) { //Get new shape value and set shape variable currShape = ((Choice)e.getItemSelectable()).getSelectedItem(); //Update drawing instructions based on shape selected updateInstructions(); } //Get name of control being changed else if (e.getItemSelectable() == filled) { //Set filled variable if (filled.getState()) currFill = "Y"; else currFill = "N"; } } /** * Clears drawing area by repainting window * * @param a ActionEvent object */ public void actionPerformed(ActionEvent a) { repaint(); } }