/* * JavASketch.java * * Version 2.0 * * Written by: Mark Masse * Date: 7-28-96 (original version: 12-23-95) * * This software is in the public domain, furnished "as is", without technical * support, and with no warranty, express or implied, as to its usefulness for * any purpose. */ import java.applet.Applet; import java.awt.*; /** * An Applet that implements a JavASketch drawing "toy". * @author Mark Masse * @version 2.0 */ public class JavASketch extends Applet { //DATA MEMBERS /** * The current x coordinate of the sketch-point. */ protected int x; /** * The current y coordinate of the sketch-point. */ protected int y; /** * Is true when drawing up and false otherwise. */ protected boolean up; /** * Is true when drawing down and false otherwise. */ protected boolean down; /** * Is true when drawing left and false otherwise. */ protected boolean left; /** * Is true when drawing right and false otherwise. */ protected boolean right; /** * The image used to create the graphics. */ protected Image img; /** * The dimensions of the JavASketch. */ protected Dimension dim; /** * The graphic content of the JavASketch. */ protected Graphics gra; /** * The width of the JavASketch. */ protected int w; /** * The height of the JavASketch. */ protected int h; /** * The previous x-coordinate. */ protected int lastx; /** * The previous y-coordinate. */ protected int lasty; /** * Determines whether the first point has been added to the JavASketch. */ protected boolean gotFirstPoint; /** * Determines whether the JavASketch needs to be updated. */ protected boolean updateSketch = true; /** * Determines whether the Jav A Sketch was erased . */ protected boolean shaken; /** * The initial angle of the left knob's ridges. */ protected float leftKnobAngle; /** * The initial angle of the right knob's ridges. */ protected float rightKnobAngle; //METHODS /** * Initialization of the JavASketch Applet */ public void init() { // Set the bg color to white setBackground(Color.white); // Set the starting point x = 200; y = 100; // Add the starting point to the JavASketch addPoint(x,y); showStatus("Jav A Sketch written by Mark Masse"); } /** * Info * @return Info about the Applet's author */ public String getAppletInfo() { return "JavASketch by Mark Masse"; } /** * The event-handler for the JavASketch Applet. * @param evt The Event */ public boolean handleEvent(Event evt) { switch(evt.id) { case Event.KEY_PRESS: case Event.KEY_ACTION: // Bind Space to erase the Jav A Sketch if(evt.key == ' ') { showStatus("Shaking Jav A Sketch"); shake(); addPoint(x, y); repaint(); } // // Bind the key press events to "turn on" direction // else if(evt.key == 'l' || evt.key == 'L' || evt.key == Event.UP) { draw("UP", true); } else if(evt.key == 'k' || evt.key == 'K' || evt.key == Event.DOWN) { draw("DOWN", true); } else if(evt.key == 'a' || evt.key == 'A' || evt.key == Event.LEFT) { draw("LEFT", true); } else if(evt.key == 's' || evt.key == 'S' || evt.key == Event.RIGHT) { draw("RIGHT", true); } break; case Event.KEY_RELEASE: case Event.KEY_ACTION_RELEASE: // // Bind the key release events to "turn off" direction // if(evt.key == 'a' || evt.key == 'A' || evt.key == Event.LEFT) { draw("LEFT", false); } else if(evt.key == 's' || evt.key == 'S' || evt.key == Event.RIGHT) { draw("RIGHT", false); } else if(evt.key == 'k' || evt.key == 'K' || evt.key == Event.DOWN) { draw("DOWN", false); } else if(evt.key == 'l' || evt.key == 'L' || evt.key == Event.UP) { draw("UP", false); } break; case Event.MOUSE_DOWN: showStatus("a = left, s = right, k = down, l = up," + " and space = erase"); break; } return true; } /** * Paints the JavASketch with the current graphic content * @param g The graphics content */ public void paint(Graphics g) { update(g); } /** * Updates the graphic content of the JavASketch * @param ig The graphics content */ public void update(Graphics igra) { Dimension d = size(); if ((img == null) || (d.width != dim.width) || (d.height != dim.height)) { w = d.width; h = d.height; img = createImage(w, h); dim = d; gra = img.getGraphics(); updateSketch = true; } // Check to see if the erasing "shake" should be performed if(shaken) { int i, j; int distance = 50; // Shake up and down for(i=0; i < 3; i++) { distance -= 10; for(j=0; j >= -100; j-=distance) { igra.drawImage(img, 0, j, null); } for(j=-100; j <= 100; j+=distance) { igra.drawImage(img, 0, j, null); } for(j=100; j >= 0; j-=distance) { igra.drawImage(img, 0, j, null); } } shaken = false; } if(updateSketch) { // Redraw the JavASketch // NOTE: This will erase the current sketch drawSketch(); updateSketch = false; } igra.drawImage(img, 0, 0, null); } /** * Draws all of the graphics for the JavASketch. Including the * red border, and the "Jav A sketch" title */ public void drawSketch() { // Draw the red border gra.setColor(Color.red); gra.fillRoundRect(0, 0, w, h, 80, 80); // Draw main rectangular drawing surface gra.setColor(Color.gray); gra.fillRoundRect(40, 40, w-80, h-130, 20, 20); gra.setColor(Color.lightGray); gra.fillRoundRect(43, 43, w-86, h-136, 20, 20); // Create the color fdd017 Color Gold = new Color(253, 208, 23); gra.setColor(Gold); // Create Polygon for left arrow Polygon leftArrow = new Polygon(); // Create Polygon for right arrow Polygon rightArrow = new Polygon(); // Create Polygon for up arrow Polygon upArrow = new Polygon(); // Create Polygon for down arrow Polygon downArrow = new Polygon(); // Add points to leftArrow Polygon leftArrow.addPoint(10,h-95); leftArrow.addPoint(20,h-105); leftArrow.addPoint(20,h-85); // Add points to rightArrow Polygon rightArrow.addPoint(34,h-95); rightArrow.addPoint(24,h-105); rightArrow.addPoint(24,h-85); // Add points to downArrow Polygon downArrow.addPoint(w-20,h-85); downArrow.addPoint(w-10,h-95); downArrow.addPoint(w-30,h-95); // Add points to upArrow Polygon upArrow.addPoint(w-20,h-109); upArrow.addPoint(w-10,h-99); upArrow.addPoint(w-30,h-99); // Fill the Arrow Polygons gra.fillPolygon(leftArrow); gra.fillPolygon(rightArrow); gra.fillPolygon(downArrow); gra.fillPolygon(upArrow); // Draw left knob drawKnob(0, h - 80, 80, leftKnobAngle); // Draw right knob drawKnob(w - 80, h - 80, 80, rightKnobAngle); // Print "Jav A sketch" at the top Font JS = new Font("JS", Font.ITALIC, 25); gra.setFont(JS); FontMetrics fm = gra.getFontMetrics(); int sWidth = fm.stringWidth("Jav A Sketch"); gra.drawString("Jav A Sketch",(w - sWidth)/2, 25); // If we didn't just erase then show author info. if(!shaken) { showStatus("Jav A Sketch written by Mark Masse"); } } /** * Clears the JavASketch screen. */ public void shake() { shaken = true; updateSketch = true; up = false; down = false; left = false; right = false; repaint(); } public void drawKnob(int x, int y, int diameter, float startAngle) { Color oldColor = gra.getColor(); // Draw the knob's border gra.setColor(Color.lightGray); gra.fillOval(x, y, diameter, diameter); float radius = (float) diameter/2; int centerX = x + (int) radius; int centerY = y + (int) radius; // Draw the knotches that will "move" gra.setColor(Color.gray); for(float angle = startAngle; angle <= (360.0f + startAngle); angle += 10.0f) { int borderX = centerX + (int) (radius * ((float) Math.cos((double) angle))); int borderY = centerY + (int) (radius * ((float) Math.sin((double) angle))); gra.drawLine(centerX, centerY, borderX, borderY); } gra.setColor(Color.white); gra.fillOval(x + 4, y + 4, diameter - 8, diameter - 8); // Draw a dot in the center gra.setColor(Color.lightGray); gra.fillOval(centerX - 1, centerY - 1, 2, 2); gra.setColor(oldColor); } public void turnLeftKnob(String direction) { if(direction.equalsIgnoreCase("RIGHT")) { leftKnobAngle -= 2.5f; } else { leftKnobAngle += 2.5f; } if(leftKnobAngle >= 360.0f) { leftKnobAngle = 0.0f; } // Draw left knob drawKnob(0, h - 80, 80, leftKnobAngle); } public void turnRightKnob(String direction) { if(direction.equalsIgnoreCase("UP")) { rightKnobAngle -= 2.5f; } else { rightKnobAngle += 2.5f; } if(rightKnobAngle >= 360.0f) { rightKnobAngle = 0.0f; } // Draw right knob drawKnob(w - 80, h - 80, 80, rightKnobAngle); } /** * First checks to make sure the point specified by the parameters x and y * is in the sketching area, and if so it adds the point. If the point is * outside the sketching area, the Applet's x and y values are reset to be * inside the area. * @param x The x coordinate of the point to be added * @param y The y coordinate of the point to be added */ public void checkAndAdd(int X, int Y) { int border = 45; int bottomBorder = 95; if((X > border && X < w - border) && (Y > border && Y < h - bottomBorder)) { addPoint(X, Y); repaint(); } else if(X < border) this.x = border + 2; else if(X > w - border) this.x = w - border - 2; else if(Y < border) this.y = border + 2; else if(Y > h - bottomBorder) this.y = h - bottomBorder - 2; } /** * Adds a "sketch"-point to the JavASketch. * @param x The x coordinate of the point to be added. * @param y The y coordinate of the point to be added. */ public void addPoint(int x, int y) { if(gotFirstPoint) { // "Connect the dots" gra.setColor(Color.black); gra.drawLine(x , y, lastx, lasty); // Draw the cursor as a light gray pixel gra.setColor(Color.lightGray); gra.drawLine(x, y, x, y); } // Set the "last" variables for the next call to this function lastx = x; lasty = y; gotFirstPoint = true; // Set because this function has been called } public void draw(String direction, boolean state) { if(state) { if(direction.equalsIgnoreCase("UP") || direction.equalsIgnoreCase("DOWN")) { if(direction.equalsIgnoreCase("UP")) { up = true; down = false; y = y - 4; turnRightKnob("UP"); } else { down = true; up = false; y = y + 4; turnRightKnob("DOWN"); } if(left) { x = x - 4; turnLeftKnob("LEFT"); } else if(right) { x = x + 4; turnLeftKnob("RIGHT"); } } else if(direction.equalsIgnoreCase("LEFT") || direction.equalsIgnoreCase("RIGHT")) { if(direction.equalsIgnoreCase("LEFT")) { left = true; right = false; x = x - 4; turnLeftKnob("LEFT"); } else { right = true; left = false; x = x + 4; turnLeftKnob("RIGHT"); } if(up) { y = y - 4; turnRightKnob("UP"); } else if(down) { y = y + 4; turnRightKnob("DOWN"); } } checkAndAdd(x, y); } else { if(direction.equalsIgnoreCase("UP")) { up = false; } else if(direction.equalsIgnoreCase("DOWN")) { down = false; } else if(direction.equalsIgnoreCase("LEFT")) { left = false; } else if(direction.equalsIgnoreCase("RIGHT")) { right = false; } } } }