Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Java Animation Techniques


August 2000 Java Solutions/Java Animation Techniques

Java Animation Techniques

Pat Paternostro

Animation is a standard part of the Java Library, but it takes a bit of organizing to make use of it.


Introduction

"Computer Animation" is a broad term that could mean anything from a simple animated GIF [1] on a website to a full-blown feature-length movie. Java animation falls somewhere between these two extremes. Unlike animated GIFs, Java provides the flexibility to create truly dynamic animations, that is, animations that change in response to external events or user input. Dynamic animation is necessary for things like real-time displays, simulations, and games. Although Java may never be practical for producing feature-length movies, it is very handy for producing animations that are portable, either as web-based applets or stand-alone applications. This article details animation techniques that can be incorporated in a Java program. I show how to apply these techniques both to applets and applications.

Multithreading in Animations

Animation in Java should always occur in a separate thread of execution. This allows users to interact with the Java animation program without perceptibly degrading performance. There are two ways to create threads in Java. The first is to extend the Thread class and provide a specific implementation for the class's run method:

public class MyThread extends Thread
{
   public void run()
   {
      System.out.println
         ("In a separate thread!");
   }
}

To start the thread, simply instantiate the extended class and call the Thread class's start method. The start method is what actually creates the separate thread of execution, which in turn calls the run method. When the run method executes to completion the thread is automatically stopped and its resources are freed.

The second method involves implementing the Runnable interface on a class and providing a specific implementation for the interface's run method. Incidentally, the Thread class employs this technique.

To start a thread with this method, use the Thread class constructor that accepts a Runnable target as a parameter (an instance of a class that implements the Runnable interface) and call the Thread class's start method:

public class MyClass
   implements Runnable
{
   public static void
   main(String args[])
   {
      new Thread
             (new MyClass()).start();
   }

   public void run()
   {
      System.out.println
         ("In a separate thread!");
   }
}

Java-Specific Threading Issues

Animation threads usually run continuously and most often are coded with a while(true) loop construct placed inside the run method. Prior to JDK 1.2.x, a started thread could be prematurely stopped via the Thread class's stop method. However, that method has been deprecated in JDK 1.2.x and above because of its unsafe behavior. (See the JDK 1.2.x javadoc HTML help file on the Thread class's stop method for detailed information concerning deprecation of the method.) The preferred way to prematurely stop a continuously running thread is by setting a boolean flag or simply setting the Thread object reference to null. In this case, the while(true) loop construct changes to a while(condition true) loop construct.

Animation threading is handled differently in a Java applet than in a Java application. In a Java applet, animation threads are normally started in the Applet class's start method and stopped in the Applet class's stop method. The Applet's start method is called whenever a user visits an applet web page. The stop method is called whenever a user leaves the web page. A programmer can override these methods to perform any startup or cleanup actions respectively. In a Java program, animation threads are generally started either in a class's constructor or in response to some user action (i.e., a button press, menu selection, etc.) and are stopped when the program ends or in response to some user action.

Some issues with thread synchronization have been omitted due to limited space in the magazine. See the readme file on the ftp site for this information.

Where to Animate

In Java, you draw on a graphics context; therefore, you should do all the animation within a component class's paint method, because that method is passed a Graphics object by the Java runtime system. The Graphics object represents the component's graphics context.

This implies that you should derive your animation class (directly or indirectly) from the Java Component class, because Component is the ancestor of all graphics components and is the base class that defines the virtual paint method. (If you create an applet, you will automatically be deriving from the Component class.)

You can override paint to perform the desired animation with a multitude of drawing methods from the Graphics class (e.g., drawRect, drawOval, drawImage, etc.). The animation thread's sole responsibility is to effect a change on the drawn image's state (e.g., change coordinates, change image) and to call the Component class's repaint method. Internally, repaint calls the Component class's update method, which clears the drawing area, and in turn calls your component's paint method.

Flicker-Free Animation

An annoying side effect in Java animations is screen flicker. It is caused by clearing the drawing area (in the update method called from repaint) prior to performing any drawing operations. To reduce this flicker, you can create an offscreen image and do all drawing operations on it (including clearing the drawing area). When all the offscreen operations are completed, you then draw the offscreen image to the viewable graphics context. This technique is known as double buffering and involves overriding the Component class's update() method.

To create an offscreen image in Java, call the Component class's version of createImage that accepts two integer parameters. These integers represent the width and height of the drawing area. The createImage method returns an Image object. You then call this object's getGraphics method to retrieve the image's graphics context, which you'll need to perform the drawing operations.

Unlike with most Java objects that are automatically garbage collected, you must explicitly dispose of any graphics context you create. That's because getGraphics allocates system resources that cannot be freed by the garbage collector. To free those resources, call the Graphics class's dispose method when you've finished using the graphics context. In a Java applet you normally call dispose in the applet's destroy method. This method is called by the browser's JVM (Java Virtual Machine) prior to removing an applet from its address space. In a Java application you call dispose when the application exits.

In implementing double buffering, you will usually want to retrieve only one offscreen graphics context and reuse it. The best time to obtain an offscreen graphics context is just after a component has been rendered. A Java applet is fully rendered when its init method is called. However, other Java components (i.e., Frame, Canvas) are not fully rendered until they are displayed; that is, after the Component class's setVisible method is called.

In the case of AWT (Abstract Windowing Toolkit) components, you can override their addNotify method to obtain the offscreen graphics context, as well as other information, such as the component's size and insets. The AWT component's addNotify method actually creates the component's peer, so be sure to call the superclass's addNotify method when overriding this method.

I have included both a Java applet (see Listing 1) and a Java application (see Listing 2) that demonstrate the previously discussed techniques.

Conclusion

Animation is not generally used in real-world applications and is usually associated with applets. However, you can use animation in an About Dialog Box to add a little pizzazz to an otherwise boring display of information. Animation is not difficult to achieve as long as you adhere to the suggestions detailed here.

Note

[1] Animated GIFs are web-based animations that are implemented in the GIF87a and GIF89a file formats. These file formats allow multiple GIF images to be stored within a single GIF file with the help of a GIF animation program (such as the GIF Construction Set available at http://www.mindworkshop.com/alchemy/gifcon.html).

Reference

Paul Tyma. "DEV-X Tip," Multithreading Applets the Right Way. http://www.devx.com/registered/tips/tipview.asp?content_id=663.

Pat Paternostro is an Associate Partner with the Tri-Com Consulting Group located in Rocky Hill, CT. Tri-Com provides programming services for a wide variety of development tasks. You can reach Pat at [email protected].


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.