In this example, each Duke
object represents a seperate
thread that executes its 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 applets 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.
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); } }
|
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 }
|
© 1996-2000 Marty Hall, © 1999-2000 Lawrence M. Brown