It's a good idea to give the user a way to stop a thread from running. With simple animation threads like this, the custom is that a mouse click stops the animation if it's running and restarts it if it isn't.
To implement this add a boolean field bouncing
that
is true
if and only if the thread is running. Then add
a MouseListener
method which stops the thread if it's
started and starts it if it's stopped. Here's the revised
applet.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.*;
public class FlickBounce extends Applet
implements Runnable, MouseListener {
private Rectangle r;
private int deltaX = 1;
private int deltaY = 1;
private int speed = 30;
private boolean bouncing = false;
private Thread bounce;
public void init () {
r = new Rectangle(37, 17, 20, 20);
addMouseListener(this);
bounce = new Thread(this);
}
public void start() {
bounce.start();
bouncing = true;
}
private Image offScreenImage;
private Dimension offScreenSize;
private Graphics offScreenGraphics;
public final synchronized void update (Graphics g) {
Dimension d = this.getSize();
if((this.offScreenImage == null)
|| (d.width != this.offScreenSize.width)
|| (d.height != this.offScreenSize.height)) {
this.offScreenImage = this.createImage(d.width, d.height);
this.offScreenSize = d;
this.offScreenGraphics = this.offScreenImage.getGraphics();
}
offScreenGraphics.clearRect(0, 0, d.width, d.height);
this.paint(this.offScreenGraphics);
g.drawImage(this.offScreenImage, 0, 0, null);
}
public void paint (Graphics g) {
g.setColor(Color.red);
g.fillOval(r.x, r.y, r.width, r.height);
}
public void run() {
while (true) { // infinite loop
long t1 = (new Date()).getTime();
r.x += deltaX;
r.y += deltaY;
if (r.x >= size().width || r.x < 0) deltaX *= -1;
if (r.y >= size().height || r.y < 0) deltaY *= -1;
this.repaint();
long t2 = (new Date()).getTime();
try {
Thread.sleep(speed - (t2 - t1));
}
catch (InterruptedException ie) {
}
}
}
public void mouseClicked(MouseEvent evt) {
if (bouncing) {
bounce.suspend();
bouncing = false;
}
else {
bounce.resume();
bouncing = true;
}
}
public void mousePressed(MouseEvent evt) {}
public void mouseReleased(MouseEvent evt) {}
public void mouseEntered(MouseEvent evt) {}
public void mouseExited(MouseEvent evt) {}
}