Multiple-Thread Animation

1. Idea

In this example, each Duke object represents a seperate thread that executes it’s own run method to facilitate the amimation, versus each Duke thread executing the same run method in the applet. For each thread to have knowledge of the applet’s repaint method, a reference to the parent applet is passed in the constructor. The method setState is available in the Duke thread as a public service to allow the applet to communicate with the thread and request termination of the thread.

2.  AnimationTwoThread.java: (Download Source)

import java.applet.Applet;
import java.awt.*;

public class AnimationTwoThread extends Applet {

//----------------------------------------------------
/** Sequence through an array of 15 images to perform
 *  the anmimation. A seperate Thread controls each
 *  tumbling Duke. The Applet's stop method calls a
 *  public service of the Duke class to terminate
 *  the thread. Override update to avoid flicker
 *  problems.
 */

  private static final int NUMIMAGES = 15;
  private static final int NUMDUKES  = 2;
  private Image[] images;
  private Duke[]  dukes;


  public void init() {
    dukes = new Duke[NUMDUKES];
    images = new Image[ NUMIMAGES ];
    for (int i=0; i<NUMIMAGES; i++)
      images[i] = getImage(getCodeBase(),
                           "images/T" + i + ".gif");
    setBackground(Color.white);
  }

  //--------------------------------------------------
  /** Start each thread, specifing a direction to
   *  sequence through the array of images.
   */
  public void start() {
    int tumbleDirection = 1;        
    for (int i=0; i<NUMDUKES ; i++) {
      if (i%2 == 1) tumbleDirection = -1;
        dukes[i] = new Duke(tumbleDirection, 
                               NUMIMAGES, this);
      dukes[i].start();
    }
  }

  //----------------------------------------------------
  /** 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);
  }
    
  public void paint(Graphics g) {
    if (dukes[0] != null)
      g.drawImage(images[ dukes[0].getIndex() ],
                                          0, 0, this);
    if (dukes[1] != null)
      g.drawImage(images[ dukes[1].getIndex() ],
                                        200, 0, this);
  }

  //----------------------------------------------------
  /** When the Applet's stop method is called, use the
   *  public service, setState, of the Duke class
   *  to set a flag and terminate run method of the 
   *  thread.
   */
  public void stop() {
    for (int i=0; i<NUMDUKES ; i++) 
      if (dukes[i] != null)
        dukes[i].setState(Duke.STOP);
  }
}

 

3. Duke.java: (Download Source)

import java.applet.Applet;

public class Duke extends Thread {

//----------------------------------------------------
/** Duke is a Thread that has knowledge of the parent
 *  applet (highly coupled) and thus, may call the
 *  parent's repaint method.  Duke is mainly
 *  responsible for changing an index value into an
 *  image array.
 */

  public static final int SUSPEND = 1;
  public static final int STOP    = 2;
  public static final int RUN     = 0;
  private int state = RUN;
  private int tumbleDirection;
  private int index = 0;
  private int numImages;  
  private Applet parent=null;

  public Duke(int tumbleDirection, int numImages,
                                     Applet parent) {
    this.tumbleDirection = tumbleDirection;
    this.numImages = numImages;
    this.parent = parent;    
  }
    
  public int getIndex() { return index; }
    
  //--------------------------------------------------
  /** Public method to permit setting a flag to 
   *  stop or suspend the thread. State is monitored
   *  through corresponding checkState method.
   */    
  public synchronized void setState(int state) {
    this.state = state;
    if (state==RUN)
      notify();
  }
    
  //--------------------------------------------------
  /** Returns the desired state (RUN, STOP, SUSPEND) 
   *  of the thread.  If the thread is to be 
   *  suspended, then the thread method wait is 
   *  continuously called until the state is changed
   *  through the public method setState.
   */ 
  private synchronized int checkState() {
   	while (state==SUSPEND) {
      try { wait(); }
    	catch (InterruptedException e) {}
    }
    return state;
  }

  //----------------------------------------------------
  /** The variable index (into image array) is
   *  incremented once each time through the while
   *  loop, call repaint, and pauses for a moment. Each
   *  time through the loop the state (flag) of the 
   *  thread is checked.
   */    			
  public void run() {
    while ( checkState()!=STOP) { 
      index += tumbleDirection;
      if (index < 0) index = numImages - 1;
      if (index >= numImages) index = 0;

      parent.repaint();

      try { Thread.sleep(100); }
      catch (InterruptedException e)
      { break; }  // break while loop
    }
  } // end run
}

 

4. Result (Download Source)

Multiple Thread Animation

Error! You must use a Java enabled browser.

© 1996-2000 Marty Hall, © 1999-2000 Lawrence M. Brown