// Harness for doing the various random applets for MAS964 ps9 import java.applet.*; import java.awt.*; import ACG; public class RandomApplet extends DoubleBufferApplet implements Runnable { protected Thread animThread; int frameDelay = 25; int frameNumber = 0; FixedNumberFont font; int fontY; boolean redrawLeft, redrawRight; int leftNumber, rightNumber; ACG rightGen, leftGen; static final int maxUpdateFrequency = 400; int leftUpdateFrequency = 50; int rightUpdateFrequency = 50; public void init() { this.setBackground(Color.white); this.setForeground(Color.black); update(getGraphics()); super.init(); String frameDelayString = getParameter("frameDelay"); try { if (frameDelayString != null) frameDelay = Integer.parseInt(frameDelayString); } catch (Exception e) {} font = new FixedNumberFont(this); redrawLeft = false; redrawRight = false; // create two random number generators int rightSeed, leftSeed; int t = (int)System.currentTimeMillis(); rightSeed = Math.abs(t*t); leftSeed = Math.abs(t*t*t); rightGen = new ACG(24, 55, rightSeed); leftGen = new ACG(11, 37, leftSeed); } // redraw left and right sides. // synchronized with keyDown() public synchronized void redrawImage() { fontY = (imageBufferSize.height - font.getHeight()) / 2; if (redrawLeft) drawLeft(); if (redrawRight) drawRight(); repaint(); } // draw the left side font public void drawLeft() { Graphics g = imageBuffer.getGraphics(); font.drawNumber(g, leftNumber, 0, fontY); } // draw the right side font public void drawRight() { Graphics g = imageBuffer.getGraphics(); font.drawNumber(g, rightNumber, imageBufferSize.width - font.getWidth(), fontY); } // update left and right as appropriate public void run() { while (Thread.currentThread() == animThread) { doFrame(); frameNumber++; try { Thread.sleep(frameDelay); } catch (InterruptedException ex) { System.out.println("Sleep Interrupted??"); } } } public void start() { super.start(); animThread = new Thread(this); animThread.start(); } public void stop() { animThread = null; super.stop(); } public void doFrame() { if (frameNumber % leftUpdateFrequency == 0) updateLeft(); if (frameNumber % rightUpdateFrequency == 0) updateRight(); if (redrawLeft || redrawRight) redrawImage(); } // generate a new number for left public void updateLeft() { redrawLeft = true; leftNumber = leftGen.next() & 0xff; } // generate a new number for right public void updateRight() { redrawRight = true; rightNumber = rightGen.next() & 0xff; } // start/stop threads. Synchronized with redrawImage(), to prevent // this thread from killing the redraw while it's happening public synchronized boolean keyDown(Event e, int key) { if ((char)key == ' ') { if (animThread == null) { animThread = new Thread(this); animThread.start(); } else { animThread = null; } } return true; } // mouse events reset the frequency of left and right // on mouse down, we also muck with the generators a bit public boolean mouseDown(Event e, int x, int y) { recalcFrequency(x, y); if (x < imageBufferSize.width / 2) leftGen.push((int)(e.when * y)); else rightGen.push((int)(e.when * y)); return true; } public boolean mouseDrag(Event e, int x, int y) { recalcFrequency(x, y); return true; } public boolean mouseUp(Event e, int x, int y) { recalcFrequency(x, y); return true; } // frequency varies as the square of the distance from the // mouse click to the center row. public void recalcFrequency(int x, int y) { float where = (float)y / imageBufferSize.height; if (where < 0.5) where = (1 - where); where = 1 - where * 2; int newFreq = (int)(where * where * maxUpdateFrequency) + 1; if (x < imageBufferSize.width / 2) leftUpdateFrequency = newFreq; else rightUpdateFrequency = newFreq; } }