Bookmark and Share

Animation Basics

See the example applet in action in the demo or view the source code.

One common use of applets is to provide animation, a display that updates constantly like individual frames in a movie. This example explains some of the techniques commonly used to produce this effect.

Using Threads

A thread is a single flow of execution in a program. Java provides multi threading where several independent tasks can run concurrently as separate threads. All threads in a program share the same code and memory space.

When performing animation in an applet, it's a good idea to run it in a separate thread. Animation is usually done within some type of loop. If you were to place that loop within the main applet thread, the applet wouldn't be able to process events or perform any other tasks while the loop was executing. That presents a real problem if the animation is to be continuous.

Controlling a Thread

In order to properly use threads, you need to understand the basic program execution flow in an applet.

The applet init() method is called when a page first loads an applet. It's a good place to initialize global variables, process applet parameters, or any other code that should be run only once.

The start() method is also called when the page first loads the applet, after init(). But it's also called whenever the user returns to the page, such as after following a link to another page and hitting the BACK button.

Complimentary to the start() method, the stop() method is called whenever the user leaves the page. It allows you to release any system resources you've allocated so they won't be wasted while the applet isn't being displayed.

Finally, the applet destroy() method is called when the applet is unloaded from the system, such as when the browser is closed.

Usually, when you create a separate thread, you'll want to override the applet start() and stop() methods so you can start (or restart) and stop that thread. This is especially true for animation since you usually only need the thread to run while the applet is being displayed.

Some sample code is shown below. A global thread variable is defined for the applet and started and stopped at the appropriate places in the code.

  Thread animThread;    // Animation thread.

  ...

  public void start() {

    // Start the animation thread.

    if (animThread == null) {
      animThread = new Thread(this);
      animThread.start();
    }
  }

  public void stop() {

    // Stop the animation thread.

    if (animThread != null) {
      animThread.stop();
      animThread = null;
    }
  }

With this in place, you then need add the code to be executed within the new thread.

The Runnable Interface

To execute code inside a thread, you need to override the Thread.run() method. The problem is, applets are derived from the Applet class, not the Thread class. In order to override the Thread.run() method you need to use an interface. This is done when you define the applet class.

public class AnimationExample extends Applet implements Runnable {
  ...
}

Interfaces are common in Java. When you define a new class derived from an existing one, like Applet, you can override any of its methods. But a derived class can only have one parent class. The use of interfaces allows a class to override particular methods from a class other than its parent, like Thread.run() in this case.

Now the thread code can be place in the run() method. Since it's possible to have multiple threads running at the same time, you first need to identify which thread is currently active.

  public void run() {

    // Is this the animation thread?

    while (Thread.currentThread() == animThread) {

      // ... run animation code ...

      // Update the display.

      repaint();

      // Suspend the thread for the specified time (in milliseconds).

      try {
        Thread.currentThread().sleep(50);
      }
      catch (InterruptedException e) {}
    }
  }

In the above sample, when the animation thread is active it does some processing, calls repaint() to force the applet display to update and then suspends itself for a few milliseconds. This gives any other threads, including the main applet thread, a chance to execute.

The amount of time specified in the Thread.sleep() call affects the animation frame rate. Setting it lower makes the animation appear smoother. However, if set too low the display may appear to halt and skip.

Displaying the Animation

The example applet simply draws a square in the center of the display using a basic shape that is rotated by a given angle. That angle is updated in the animation loop every few milliseconds. To display it, the paint() method is used a create copy of the shape, rotate each point and draw it on the screen.

The call to repaint() in the animation loop causes update() to be called. Normally, update() clears the display then calls paint() to rebuild it. This erasing and redrawing can cause the applet display to flicker.