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.