Recipe 24.2 Displaying a Moving Image with Animation


Problem

You need to update a graphical display while other parts of the program are running.

Solution

Use a background thread to drive the animation.

Discussion

One common use of threads is an animator, a class that displays a moving image. This "animator" program does just that. It draws a graphical image (see Recipe 13.8) at locations around the screen; the location is updated and redrawn from a Thread for each such image. This version is an applet, so we see it here in the AppletViewer (Figure 24-1).

Figure 24-1. Animator
figs/jcb2_2401.gif


The code for the animator program consists of two classes, Sprite (Example 24-4) and Bounce[3] (Example 24-5). A Sprite is one image that moves around; Bounce is the main program.

[3] The title belies some unfulfilled ambitions to make the animations follow the bouncing curves seen in some flashier animation demonstrations.

Example 24-4. Sprite.java (part of animator applet)
import java.applet.*;  import java.awt.*;  import java.awt.event.*;  import java.util.*;    /** A Sprite is one Image that moves around the screen on its own */  class Sprite extends Component implements Runnable {      protected static int spriteNumber = 0;      protected Thread t;      protected int x, y;      protected Bounce parent;      protected Image img;      protected boolean done = false;        /** Construct a Sprite with a Bounce parent: construct       * and start a Thread to drive this Sprite.       */      Sprite(Bounce parent, Image img) {          super( );          this.parent = parent;          this.img = img;          setSize(img.getWidth(this), img.getHeight(this));          t = new Thread(this);          t.setName("Sprite #" + ++spriteNumber);          t.start( );      }        /** Stop this Sprite's thread. */      void stop( ) {          System.out.println("Stopping " + t.getName( ));          done = true;      }        /**       * Run one Sprite around the screen.       * This version is very stupid, and just moves them around       * at some 45-degree angle.       */      public void run( ) {          int width = parent.getSize( ).width;          int height = parent.getSize( ).height;          // Random location          x = (int)(Math.random( ) * width);          y = (int)(Math.random( ) * height);          // Flip coin for x & y directions          int xincr = Math.random( )>0.5?1:-1;          int yincr = Math.random( )>0.5?1:-1;          while (!done) {              width = parent.getSize( ).width;              height = parent.getSize( ).height;              if ((x+=xincr) >= width)                  x=0;              if ((y+=yincr) >= height)                  y=0;              if (x<0)                  x = width;              if (y<0)                  y = height;              // System.out.println("Move " + t.getName( ) + " from " +              //     getLocation( ) + " to " + x + "," + y);              setLocation(x, y);              repaint( );              try {                  Thread.sleep(250);              } catch (InterruptedException e) {                  return;              }          }          }        /** paint -- just draw our image at its current location */      public void paint(Graphics g) {          g.drawImage(img, 0, 0, this);      }  }    }

Example 24-5. Bounce.java (part of animator applet)
import java.applet.*; import java.awt.*; import java.awt.event.*; import java.util.*; /** This is the Bounce class; create and start Sprites, using Threads. */ public class Bounce extends Applet implements ActionListener {     /** The main Panel */     protected Panel p;     /** The image, shared by all the Sprite objects */     protected Image img;     /** A Vector of Sprite objects. */     protected Vector v;     public void init( ) {         Button b = new Button("Start");         b.addActionListener(this);         setLayout(new BorderLayout( ));         add(b, BorderLayout.NORTH);         add(p = new Panel( ), BorderLayout.CENTER);         p.setLayout(null);         String imgName = getParameter("imagefile");         if (imgName == null) imgName = "duke.gif";         img = getImage(getCodeBase( ), imgName);         MediaTracker mt = new MediaTracker(this);         mt.addImage(img, 0);         try {             mt.waitForID(0);         } catch(InterruptedException e) {             throw new IllegalArgumentException(                 "InterruptedException while loading image " + imgName);         }         if (mt.isErrorID(0)) {             throw new IllegalArgumentException(                 "Couldn't load image " + imgName);         }         v = new Vector( );     }     public void actionPerformed(ActionEvent e) {         System.out.println("Creat-ing another one!");         Sprite s = new Sprite(this, img);         s.start( );         p.add(s);         v.addElement(s);     }     public void stop( ) {         for (int i=0; i<v.size( ); i++) {             ((Sprite)(v.get(i))).stop( );         }         v.clear( );     } }



Java Cookbook
Java Cookbook, Second Edition
ISBN: 0596007019
EAN: 2147483647
Year: 2003
Pages: 409
Authors: Ian F Darwin

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net