Previous | Next | Trail Map | Creating a User Interface | Working with Graphics


Creating the Animation Loop

Every program that performs animation needs an animation loop. Generally, this loop should be in its own thread. It should never be in the paint() or update() method, since that would take over the main AWT thread, which is in charge of all drawing and event handling. [Check. True for applications, too?]

This page provides two templates for performing animation, one for applets and another for applications. The applet version is running just below. (You can click on it to stop the animation. Click again to restart it.)


Your browser can't run 1.0 Java applets, so here is a snapshot of what you'd see:


Here is the code for the applet animation template. Here is the code for the equivalent application animation template. The rest of this page will explain the templates' code.

Initializing Instance Variables

The animation templates use three instance variables. The first instance variable (frameNumber) represents the current frame. It's initialized to 0.

The second instance variable (delay) is the number of milliseconds between frames. It's initialized using a frames per second number provided by the user. If the user provides no valid number, then the templates default to 10 frames per second. The following code converts frames per second into the number of milliseconds between frames:

delay = (fps > 0) ? (1000 / fps) : 100;

The third instance variable (animatorThread) is a Thread object, representing the thread in which the animation loop will run.

Note: If you're not familiar with threads, see [somewhere else] for an overview of their use.

The Animation Loop

The animation loop (the while loop in the animation thread) does the following, over and over again:
  1. Calls the repaint() method to request that the paint() method be called. (The paint() method draws the graphic that corresponds to the current frame number.)
  2. Sleeps for up to delay milliseconds (more on this later).
  3. Advances the frame number.

Ensuring a Constant Frame Rate

The most obvious way to implement the sleep in the animation loop is to sleep for delay milliseconds. This can cause the thread to sleep too long, however, since you lose a certain amount of time just by executing the animation loop.

The solution to this problem is to remember when the animation loop starts, add delay milliseconds to arrive at a wakeup time, and then sleep until the wakeup time. Here's the code that implements this:

long startTime = System.currentTimeMillis();
while (/* animation thread is still running */) {
    . . . 
    startTime += delay;
    Thread.sleep(Math.max(0, startTime-System.currentTimeMillis()));
    . . . 
}

Behaving Politely

Two more features of the animation templates belong in the category of polite behavior. The first feature applies only to applets: suspending the applet's execution when the user leaves the page. This is achieved by reimplementing the Applet stop() method so that it prevents the animation thread from performing. When the user revisits the page, the start() method restarts the animation thread.

The second feature is allowing the user to explicitly stop (and restart) the animation, while the applet or application is still visible. Animation can be quite distracting, and it's a good idea to give the user the power to stop the animation so that the user can concentrate on something else. This feature is implemented by overriding the mouseDown() method so that it stops or starts the animation thread, depending on the thread's current state.


Previous | Next | Trail Map | Creating a User Interface | Working with Graphics