Stopping Animations

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 {

  Rectangle r;
  int deltaX = 1;
  int deltaY = 1;
  int speed = 30;
  boolean bouncing = false;
  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 e) {
  
    if (bouncing) {
      bounce.suspend();
      bouncing = false;
    }
    else {
      bounce.resume();
      bouncing = true;
    }
   
  }
 
  public void mousePressed(MouseEvent e) {}
  public void mouseReleased(MouseEvent e) {}
  public void mouseEntered(MouseEvent e) {}
  public void mouseExited(MouseEvent e) {}

}

Previous | Next | Top
Last Modified August 4, 1999
Copyright 1997, 1999 Elliotte Rusty Harold
elharo@metalab.unc.edu