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();
}
}