// mas964 ps4 // Base class for animating mouse strokes import java.applet.*; import java.awt.*; import java.lang.Math; import DoubleBufferApplet; public abstract class StrokeAnimator extends DoubleBufferApplet implements Runnable { protected int frameDelay, animationLength; protected long startTime; protected Thread animatorThread; protected boolean threadDebugInfo = false; int x[], y[], numPoints; long t[]; final int maxPoints = 1000; // millisecond timings. Length <= 0 means never stop. // these values are also read from "length" and "delay" properties protected void setTiming(int delay, int length) { frameDelay = delay; animationLength = length; } // this is called with how many milliseconds we are into the animation public abstract void drawFrame(int ms); public boolean mouseDown(Event e, int mouseX, int mouseY) { numPoints = 0; stop(); return true; } public boolean mouseDrag(Event e, int mouseX, int mouseY) { if (numPoints < maxPoints) { x[numPoints] = mouseX; y[numPoints] = mouseY; // t[numPoints] = e.when; numPoints++; } return true; } public boolean mouseUp(Event e, int x, int y) { // should start the animation now drawFrame(0); stop(); start(); return true; } public void start() { if (threadDebugInfo) System.out.println("Start was called " + System.currentTimeMillis()); if (frameDelay == 0) // should throw an exception System.out.println("Start was called with a 0 frame delay!"); if (numPoints > 0) { animatorThread = new Thread(this); animatorThread.start(); } } public void stop() { if (threadDebugInfo) System.out.println("Stop was called " + System.currentTimeMillis()); if (animatorThread != null) { animatorThread.stop(); animatorThread = null; } } public void run() { if (threadDebugInfo) System.out.println("Running." + System.currentTimeMillis()); startTime = System.currentTimeMillis(); while (Thread.currentThread() == animatorThread) { long drawStartTime = System.currentTimeMillis(); drawFrame((int)(drawStartTime - startTime)); if (animationLength > 0 && drawStartTime - startTime >= animationLength) stop(); else { try { // sleep to the next frameDelay'th interval after beginning. int delay = (int)(frameDelay - (System.currentTimeMillis() - drawStartTime)); if (delay < 0) delay = delay % frameDelay + frameDelay; // first postive modulus Thread.sleep(delay); } catch (InterruptedException e) { System.out.println("Sleep interrupted?"); } } } } // read in the frame delay and length parameters. public void init() { String delayString = getParameter("delay"); String lengthString = getParameter("length"); try { if (delayString != null) frameDelay = Integer.parseInt(delayString); } catch (Exception e) {} try { if (lengthString != null) animationLength = Integer.parseInt(lengthString); } catch (Exception e) {} numPoints = 0; x = new int[maxPoints]; y = new int[maxPoints]; t = new long[maxPoints]; super.init(); } }