import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.util.Vector; //---------------------------------------------------- /** Bounce circles around on the screen. * Doesn't use double buffering so has problems * with overlapping circles. Overrides update * to avoid flicker problems. */ public class Bounce extends Applet implements Runnable, ActionListener { private Vector circles; private int width, height; private Button startButton, stopButton; private Thread animationThread = null; public void init() { setBackground(Color.white); width = getSize().width; height = getSize().height; circles = new Vector(); startButton = new Button("Start a circle"); startButton.addActionListener(this); add(startButton); stopButton = new Button("Stop all circles"); stopButton.addActionListener(this); add(stopButton); } //---------------------------------------------------- /** When the "start" button is pressed, start the * animation thread if it is not already started. * Either way, add a circle to the Vector of * circles that are being bounced. * * When the "stop" button is pressed, stop * the thread and clear the Vector of circles. */ public void actionPerformed(ActionEvent event) { if (event.getSource() == startButton) { if (circles.size() == 0) { // Erase any circles from previous run. getGraphics().clearRect(0, 0, getSize().width, getSize().height); animationThread = new Thread(this); animationThread.start(); } int radius = 25; int x = radius + randomInt(width - 2 * radius); int y = radius + randomInt(height - 2 * radius); int deltaX = 1 + randomInt(10); int deltaY = 1 + randomInt(10); circles.addElement(new MovingCircle(x, y, radius, deltaX, deltaY)); } else if (event.getSource() == stopButton) { if (animationThread != null) { animationThread = null; circles.removeAllElements(); } } repaint(); } //---------------------------------------------------- /** Each time around the loop, call paint and then * take a short pause. The paint method will * move the circles and draw them. */ public void run() { Thread myThread = Thread.currentThread(); // Really while animationThread not null while(animationThread==myThread) { repaint(); pause(100); } } //---------------------------------------------------- /** Skip the usual screen-clearing step of update * so that there is no "flicker" between each * drawing step. */ public void update(Graphics g) { paint(g); } //---------------------------------------------------- /** Erase each circle's old position, move it, * then draw it in new location. */ public void paint(Graphics g) { MovingCircle circle; for(int i=0; i