Chapter 23
Spicing Up a Web Page
When Java was released to the public in late 1995, its creators had some lofty
intentions for the programming language. It was going to revolutionize the way software
was produced and distributed, remove the need to write versions of a program for
different operating systems, and take full advantage of the Internet as a place to
run programs. (They probably wanted to make some money, too.) Although some notable
projects created since then with Java advance those goals, many Java programmers
worked under somewhat less noble motivation: show-and-tell.
For every human who gets a kick out of advancing the causes of humankind, bettering
society, and being the wind beneath someone's wings, there's another who did something
because it looked cool. Animated Java applets are a case in point. There are dozens
of different special-effects applets on the Web that do interesting things with text
and graphics. During this hour you'll set aside the greater good of Javakind and
create one of your own.
The following topics will be covered:
- Controlling an applet with parameters
- Loading images from parameters
- Using off-screen areas for drawing
- Using transparent .GIF files
- Drawing images off the screen's edges
The Pan Applet
One of the common uses for Java applets has been to animate text or images on
a World Wide Web page. This kind of animation can be done as an attention-getting
move; an online catalog might use moving text to inform visitors of sale items, for
example. It also can be done to provide information in a more dynamic way. Several
media organizations, such as CNN and ESPN, have used Java applets as a way to provide
constant news and sports updates.
A lot of these applets move graphics or text over a static background to produce
an interesting effect. You're going to take the opposite tack with the Pan
applet. It will keep something in the foreground still while the background moves.
The effect could be useful to draw attention to text or create an interesting logo
for a company.
The Pan applet uses the same threaded applet structure that you have
used in several of the past hours. A thread called runner is created in
the applet's start() method and destroyed in the stop() method.
The runner object calls the run() method of the program, which
loops continuously while the program runs.
Three Image objects are used in the program: back, fore,
and workspace. The first two objects hold the background image and foreground
image that will be displayed. The third is used as an off-screen work area to make
the animation appear more smoothly, a trick called double-buffering that you learned
during Chapter 18, "Creating Animation."
In addition to displaying the background and foreground images, the applet can
display a line of text. This text and both images are specified in parameters on
the Web page that runs the applet. You can use the following parameters:
- background: This parameter is the file name of the background image
that will pan across the applet window from right to left. This image file must be
in .GIF or .JPG format and must be located in the same place as
the .class file of the applet.
- foreground: This parameter is the file name of the foreground image
that will be displayed as the background image moves behind it. This file should
be in .GIF format and must have a transparent color. Otherwise, nothing
will be visible behind the image. This parameter is optional, so you can choose not
to display a foreground image at all.
- text: This parameter is the line of text to display in front of all
images that are being displayed. If this parameter is omitted, no text will be shown.
- fontname: This parameter is the name of the font that the text should
be displayed in. Arial is the default.
- fontsize: This parameter is the size of the text's font, which defaults
to 24.
Displaying the Images
All text and images are displayed in the paint() method of the Pan
applet. An off-screen Graphics object is used for all drawing methods, and
when everything has been drawn, the off-screen area is copied to the applet window.
Using double-buffering produces much better results than displaying each image and
string in the window individually.
If a line of text is specified as a parameter, the applet will center it horizontally
and vertically on-screen. This is done using a class called FontMetrics,
which reports on how large a line of text will be if displayed in a specific font,
size, and style. The following statements create a Font object and set up
a FontMetrics object that is linked to it:
Font f = new Font(fontName, Font.BOLD, fontSize);
FontMetrics fm = getFontMetrics(f);
The Font object is used as an argument to the getFontMetrics()
method. Once you create the FontMetrics object, you can use two of its methods
to help you determine how to center a line of text in that font. These methods are
stringWidth(), which indicates how wide the text will be, and getHeight(),
which reveals how tall anything in the font will be. In the Pan applet you're
going to create, the following statements use these methods:
int xStart = (size().width - fm.stringWidth(text)) / 2;
int yStart = size().height/2 + fm.getHeight()/4;
offscreen.drawString(text, xStart, yStart);
The size().width and size().height statements are the dimensions
of the applet window itself. By using these statements with the FontMetrics
methods, the program can determine the right location for the text.
Figure 23.1 shows the Pan applet with a line of text centered in the
applet window. It's a little harder to distinguish in black and white, but the text
is drawn twice--once in black and again in white. The text is drawn at a slightly
different place the second time, as shown in the following statement:
offscreen.drawString(text, xStart-2, yStart-2);
This statement creates a shadow effect that makes the text easier to see over
the background.
Figure
23.1. The output of the Pan applet
running on the Web page Pan.asp.
Workshop: Drawing
Images Over a Screens Edges
To create the effect of an image panning from right to left, the Pan
applet takes advantage of the way images are displayed with Java. Before taking a
look at this applet, you should get Pan running. Create a new file in your
word processor called Pan.java, and enter Listing 23.1 into the file. Save
it when you're done.
Listing 23.1. The
full text of Pan.java.
1: import java.awt.*;
2:
3: public class Pan extends java.applet.Applet implements Runnable {
4: Thread runner;
5: Image back, fore, workspace;
6: Graphics offscreen;
7: String text;
8: String fontName;
9: int fontSize = 24;
10: int x1 = 0;
11: int x2;
12:
13: public void init() {
14: workspace = createImage(size().width, size().height);
15: offscreen = workspace.getGraphics();
16: // get parameters
17: String imageBack = getParameter("background");
18: if (imageBack != null)
19: back = getImage(getDocumentBase(), imageBack);
20: String imageFore = getParameter("foreground");
21: if (imageFore != null)
22: fore = getImage(getDocumentBase(), imageFore);
23: x2 = size().width;
24: text = getParameter("text");
25: fontName = getParameter("font");
26: if (fontName == null)
27: fontName = "Arial";
28: String param = getParameter("fontsize");
29: if (param != null)
30: fontSize = Integer.parseInt("0" + param);
31: }
32:
33: public void start() {
34: if (runner == null) {
35: runner = new Thread(this);
36: runner.start();
37: }
38: }
39:
40: public void stop() {
41: if (runner != null) {
42: runner.stop();
43: runner = null;
44: }
45: }
46:
47: public void run() {
48: while (true) {
49: repaint();
50: try { Thread.sleep(200); }
51: catch (InterruptedException e) {}
52: x1 = x1 - 1;
53: x2 = x2 - 1;
54: if (x1 <= (size().width * -1))
55: x1 = size().width;
56: if (x2 <= (size().width * -1))
57: x2 = size().width;
58: }
59: }
60:
61: public void paint(Graphics screen) {
62: offscreen.drawImage(back, x1, 0, null);
63: offscreen.drawImage(back, x2, 0, null);
64: if (fore != null)
65: offscreen.drawImage(fore, 0, 0, null);
66: if (text != null) {
67: offscreen.setColor(Color.black);
68: Font f = new Font(fontName, Font.BOLD, fontSize);
69: FontMetrics fm = getFontMetrics(f);
70: offscreen.setFont(f);
71: int xStart = (size().width - fm.stringWidth(text)) / 2;
72: int yStart = size().height/2 + fm.getHeight()/4;
73: offscreen.drawString(text, xStart, yStart);
74: offscreen.setColor(Color.white);
75: offscreen.drawString(text, xStart-2, yStart-2);
76: }
77: screen.drawImage(workspace, 0, 0, this);
78: }
79:
80: public void update(Graphics screen) {
81: paint(screen);
82: }
83: }
Compile this file with the javac compiler tool, and then return to the word
processor to create a Web page that contains the Pan applet. Enter Listing
23.2 and save it as Pan.asp. Note that the width and height
attributes of the <APPLET> tag should be the same dimensions as the
background image to achieve the best results.
Listing 23.2. The
full text of Pan.asp.
1: <applet code="Pan.class" width=460 height=43>
2: <param name="background" value="patch.gif">
3: <param name="font" value="Helvetica">
4: <param name="fontsize" value="25">
5: <param name="text" value="FRED'S APPETITE SUPPRESSANTS">
6: </applet>
Before you can see this applet running on a page, you need to put a copy of the image
file patch.gif in the same directory as Pan.asp. You can find
this file on the guide's CD-ROM in the Win95nt4/guide/Source/Hour23 directory.
You also can retrieve a copy from the guide's official Web site at http://www.prefect.com/java24.
Take the link from the site's front page labeled Chapter 23's Moving Images,
and you'll be able to download patch.gif. Get a copy of two other image
files called samsback.gif and samslogo.gif also to save time later.
When you use appletviewer to load this Web page, you will see the Fred's
Appetite Suppressants banner shown in Figure 23.1. No foreground element is
specified on the page, so the text appears over a moving background.
By using parameters to load all images and text, the Pan applet is able
to vary its performance greatly. You can create a new Web page by using different
images and different parameters. Return to your word processor and create a new file
called Sams.asp. Enter the text of Listing 23.3 and save the file.
Listing 23.3. The
full text of Sams.asp.
1: <applet code="Pan.class" width=229 height=166>
2: <param name="background" value="samsback.gif">
3: <param name="foreground" value="samslogo.gif">
4: </applet>
As with the previous example, you need to copy some image files before loading this
Web page into appletviewer. The files are samsback.gif and samslogo.gif.
As shown in Figure 23.2, this applet shows a moving background underneath a static
logo of Sams.net Publishing. The Sams logo makes use of transparency so that the
background image can be seen.
The panning effect used by this applet is possible because of the way the drawImage()
method can be drawn to off-screen coordinates. Normally, when you draw an image to
an applet window or a workspace, the (x, y) coordinates that you specify are within
the display area of the program. Otherwise, the graphics can't be seen. However,
there's no prohibition against drawing to coordinates that make most of an image
appear off-screen. The drawImage() method will display the portion of the
image that does appear on-screen and disregard the rest.
Figure
23.2. The output of the Pan applet
running on the Web page Sams.asp.
By drawing the background image twice at different positions, the Pan
program makes the image seem to move. The exact positions of the images vary as the
program runs, which creates the animation effect, but they always are shown right
next to each other. Figure 23.3 shows how this happens with the Sams.asp
page. Black borders have been drawn around the background image so that you can see
that it is being drawn twice. The thick black border indicates the visible display
area of the applet--everything outside of it would not be seen.
Figure
23.3. Two copies of the background image
partially displayed in the applet window.
The Pan applet uses the integer variables x1 and x2
to determine the two x coordinates where the background should be drawn. The images
do not move up and down, so no y coordinates are needed. The x1 variable
begins with the value of 0, and x2 starts out at the width of the applet:
229. The first time that the images are displayed, one copy will be shown at (0,0),
filling the entire window, and the other will begin at (229,0), one pixel off the
right edge.
In Lines 52-53 of the program, both x1 and x2 are reduced by
1. When the repaint() method is called next, each image is displayed one
pixel to the left of its last position. Lines 54-56 make sure that neither of the
images goes so far to the left that none of it is displayed. If the image moves too
far to the left, the x coordinate is set to the width of the applet.
Summary
The Pan applet is an example of producing an interesting visual effect
with a few lines of programming. Most of the statements in the program are used to
load parameters, store images, and handle the display of nonmoving graphics and text.
Less than a dozen lines control the values of x1 and x2, and these
are all that's needed to move the two copies of the background image and produce
the animation.
As you create your own programs and start looking at the programs that others
make available on the World Wide Web, you'll pick up more of these tricks. Many of
them will probably be used more for the grown-up version of show-and-tell--the home
page--than any higher purpose.
However, you might find some practical uses for these programs in unexpected places.
Using some of the same logic that was needed for the Pan applet, you could
write an applet that displays a small section of a large map and enables users to
interactively pan to other places on the map. It isn't an achievement on par with
the polio vaccine or interleague play in Major League Baseball, but a map applet
of that kind could be useful to many people browsing the World Wide Web. Because
it works fully in conjunction with Web pages, Java makes some types of information
more accessible than they would be otherwise. And that's something to get animated
about.
Q&A
- Q What is the update() method accomplishing in the Pan applet?
A This method is included in the applet to override its existing behavior. The
update() method automatically is called each time the screen needs to be
redisplayed, either due to a repaint() statement or some other cause. Normally,
update() clears the screen by filling it with the background color, and
then calls the paint() method. This screen-clearing causes a large amount
of flickering in an animation program, so update() is overridden to prevent
it from occurring.
Q None of the graphics programs that I use has a feature for transparency in .GIF
files. How is this established for an image such as samslogo.gif?
A Transparency was introduced with a version of the .GIF file format
called 89a. In order to use it, you must find a graphics program that can
load, edit, and save .GIF 89a files. If you don't have one of these
programs and you save a .GIF file, you will wipe out its transparency information.
Quiz
Don't pan past this section of the guide without testing your know-how by answering
the following questions.
Questions
- 1. Why are threads helpful in controlling an animated program in Java?
(a) They give other programs that are running more time to operate.
(b) You can use the Thread.sleep method to pause between screen updates.
(c) Loop statements don't work with animation.
2. Why is a Graphics object sent to the paint() method of an
applet?
(a) This object contains the necessary information to display something on-screen
or on a component.
(b) The method was set up to take an argument.
(c) The object signifies that graphics will be used in the method.
3. What method of the Integer class is used to convert a string into
an integer value?
(a) getInt()
(b) load()
(c) parseInt()
Answers
- 1. b. Threads have the built-in ability to start, stop, and pause--abilities
that correspond well with what an animation program needs to do as it runs.
2. a. The methods of the Graphics object must be used to display text,
polygons, and image files on-screen.
3. c.
Activities
Unless you're ready to Pan this hour's subject matter, do the following
activities: