Many forms of animation are possible in Java. What all of them have in common is that they create some kind of motion on the screen by drawing successive frames at a relatively high speed (usually about 10-20 times per second).
We will start by creating a simple template applet for doing animations and slowly elaborate it until we arrive at a fairly complete applet.
To update the screen multiple times per second, you need to create a new Java thread that contains an animation loop. The
animation loop is responsible for keeping track of the current frame and for requesting periodic screen updates. To implement
a thread, you must either create a subclass of Thread or adhere to the Runnable interface.
A common mistake is to put the animation loop in the paint() method of an applet. Doing so will have strange side effects because it holds up the main AWT thread, which is in charge
of all drawing and event handling.
As an example I have written a small template applet, called Example1Applet, that illustrates the general outline of an animation
applet. Example1Applet shows how to create a thread and call the repaint() method at fixed intervals. The number of frames per second is specified by passing in an applet parameter. Here is an example
of what you would put in your HTML document:
<applet code=Example1Applet.class width=200 height=200>
<param name=fps value=20>
</applet>
Note:
This applet doesn't actually draw anything on the screen yet. Drawing to the screen is explained later. Note also that the
applet destroys its animation thread whenever the user leaves the page (which results in the applet's stop() method being called). This ensures that the applet won't waste CPU time while its page isn't visible.
In the example above, the applet simply sleeps for a fixed amount of time between frames. This has the drawback that you sometimes wait too long. To get 10 frames per second you should not wait 100 milliseconds between frames, because you lose some time just running the thread.
The following applet, Example2Applet, shows how to keep better time. It simply computes the correct delay between frames by keeping track of the starting time. It computes the estimated required delay between frames based on the current time.
What remains is to paint each frame. In the previous examples, we call repaint() for each frame, which causes the applet's paint() method to be called. The Example3Applet has a paint() method that draws the number of the current frame to the screen.
Here is Example3Applet in action, followed by a code listing.
Note:
If you specify the frame rate to be very high (say 100 frames per second), the run() method will call repaint() 100 times per second. However, this will not always result in 100 calls to paint() per second because when you issue repaint request too quickly they will be collapsed into a single screen update. This is
why we keep track of the current frame number in the run() method rather then in the paint() method.
Now let's animate something that is a little harder to draw. The Example4Applet draws a combination of sine waves. For each x coordinate, it draws a short vertical line. All these lines together form a simple graph that changes for each frame. Unfortunately, you will find that this approach causes a lot of flashing. We'll explain the cause of the flashing and some remedies in the next section.
Here is Example4Applet in action, followed by a code listing.
The flashing you see in Example4Applet has two causes: painting each frame takes too long (due to the amount of computation
that is required during the repaint) and the entire background is cleared before paint() is called. While the computation of the next frame is going on, the user is seeing the background of the animation.
This short time between the clearing of the background and the painting of the sine wave is seen as a flash. On some platforms like the PC, the flashing is more obvious then it is on X Windows. The reason is that the X Windows graphics are buffered, which makes the flash a little shorter.
You can reduce flashing greatly using two simple tricks: implementing the update() method and using double buffering (sometimes known as using a backbuffer).
When the AWT receives a repaint request for an applet, it calls the applet's update() method. By default, the update() method clears the applet's background and then calls the paint() method. By overriding the update() method to include the drawing code that used to be in the paint() method, we avoid having the applet's entire area cleared with every repaint.
Now that the background is no longer cleared automatically, we need to do it ourselves in the update() method. We can now erase each vertical line of the graph individually before drawing the new line, eliminating the flashing
completely. This effect is shown in Example5Applet.
Here is Example5Applet in action, followed by a code listing.
Note:
Whenever you override the update() method, you still need to implement paint(). This is because the paint() method is called directly by the AWT drawing system whenever "damage" occurs to the applet's drawing area -- for example,
when a window obscuring part of the applet's drawing area is removed from the screen. Your paint() implementation can simply call update().
Another way of reducing the flashing between frames is to use double buffering. This technique is used in many animation applets.
The general principle is that you create an offscreen image, you draw a frame into the image, and then you slap the entire
image onto the screen with one call to drawImage(). The advantage is that most of the drawing is done offscreen. The final painting of the offscreen image onto the screen is
usually much more efficient than painting the frame directly to the screen.
The sine wave applet with double buffering is shown in Example6Applet. You will see that the animation is pretty smooth and you don't need any special tricks when drawing the frame. The only disadvantage is that you have to allocate an offscreen image that is as large as the drawing area. If the drawing area is very large, this may demand quite a lot of memory.
Very Useful ArticleBy Anonymous on November 2, 2009, 4:46 amThank you, Van Hoff. Your article is the shortest path to help me to fix my problem.
Reply | Read entire comment
AppletBy Anonymous on October 7, 2009, 12:58 pmIs there any another more comprehensive tag than applet..?.. Please let me know..
Reply | Read entire comment
Nice !!!!By Anonymous on September 24, 2009, 10:35 amIt's very nice ty for this help !!!!!!!!!!!!
Reply | Read entire comment
Great ArticleBy Anonymous on September 9, 2009, 10:12 pmThis article opened my eyes to many aspect of java animation I needed. I will be implementing many of these methods as I am beginning my first Java Animation as...
Reply | Read entire comment
WANKER!!!By Anonymous on August 21, 2009, 12:09 amWANKER!!!
Reply | Read entire comment
View all comments