Beginning Java 2- JDK 1.3 Version
Images and Animation
Let's start with the init() method and the data members in the
Applet class. The loading of the image will be identical to
the previous example, so we need the image and
tracker members too. After the image has been loaded, we will
calculate the scaling and translation that is necessary.
Here's the applet class with its data members and the init()
method:
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import java.net.*;
import java.awt.geom.*; // For AffineTransform
public class WhirlingLogo extends JApplet
implements Runnable
{
// This method is called when the applet is loaded
public void init()
{
tracker = new MediaTracker(this);
Image image = null;
try
{
// Image from a file specified by a URL
image = getImage(new URL(getCodeBase(),"Images/wrox_logo.gif"));
}
catch(MalformedURLException e)
{
System.out.println("Failed to create URL:\n" + e);
}
tracker.addImage(image,0); // Load image
try
{
tracker.waitForAll(); // Wait for image to load
if(tracker.isErrorAny()) // If there is an error
return; // give up
Dimension size = getSize(); // Get applet size
imageWidth = image.getWidth(this); // Get image width
imageHeight = image.getHeight(this); // and its height
// Calculate scale factor so diagonal of image fits width and height
double diagonal = Math.sqrt(imageWidth*imageWidth + imageHeight*imageHeight);
double scaleFactor = Math.min(size.width/diagonal, size.height/diagonal);
// Create a transform to translate and scale the image
at.setToTranslation((size.width-imageWidth*scaleFactor)/2,
(size.height-imageHeight*scaleFactor)/2);
at.scale(scaleFactor,scaleFactor);
imagePanel = new ImagePanel(image); // Create panel showing the image
getContentPane().add(imagePanel); // Add the panel to the content pane
}
catch(InterruptedException e)
{
System.out.println(e);
}
}
// Plus the rest of the applet
Thread whirler; // Animation thread
boolean whirling = false; // Animation control
MediaTracker tracker; // Tracks image loading
ImagePanel imagePanel;
AffineTransform at = new AffineTransform();
int imageWidth, imageHeight; // Image dimensions
double angle; // Rotation angle
final int INTERVAL = 50; // Time interval msec
final int ROTATION_TIME = 2000; // Complete rotation time msec
final int STEPS_PER_ROTATION = ROTATION_TIME/INTERVAL;
int stepCount; // Total number of steps
}
The unshaded code is exactly the same as in the previous method. The
AffineTransform member, at, stores a transform
that scales and translates the image. The angle member will
store the rotation angle in radians that will be calculated in the
run() method for the whirler thread, and applied
in the paint() method for the imagePanel object.
We have made this is a member of the class rather than declare it as a
local variable in the run() method so we can pick up the value
when the applet is stopped and restarted. The other fields that follow
angle are all concerned with orienting and drawing the image.
The constant, INTERVAL, stores the time interval between one
instance of drawing the image and the next. We store the time for a complete
rotation of the image through 360 degrees, which is 2ϖ radians, in ROTATIONTIME.
The variable STEPS_PER_ROTATION
holds the number of steps for a complete rotation, so with the values we have
set for the previous two variables, this will be 40. Finally, the variable, stepCount,
will accumulate the total number of steps modulo STEPS_PER_ROTATION. The
methods to start and stop the animation thread are the same as in the previous
example, apart from the new names for the thread and the control variable:
// This method is called when the browser starts the applet
public void start()
{
if(tracker.isErrorAny()) // If any image errors
return; // don't create the thread
whirler = new Thread(this); // Create the animation thread
whirling = true;
whirler.start(); // and start it
}
// This method is called when the browser want to stop the applet
// when is it not visible for example
public void stop()
{
whirling = false; // Stop the animation loop
whirler = null; // Discard the thread
}
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.