Step 5: Applet Parameters and Errors

In this final step of the tutorial, you'll add support for applet parameters. Along the way, you'll be introduced to Java's error-handling mechanism.

Applet parameters let the author of a Web page change the way an applet looks and behaves without recompiling the applet. A parameter consists of a name and a value, and are specified like this in HTML:

<PARAM NAME="name" VALUE="value">

An applet designer defines which parameter names the applet will support, and also the meanings for the values assigned to the names. When the applet loads, it reads the values for each parameter and then changes its behavior accordingly.

PaintApp will support three parameters that change its colors: bgcolor (background), fgcolor (foreground), and bordercolor. Each color value must be in the form RRGGBB, where RR, GG, and BB are two-digit hex values from 00 to FF that specify the amount of red, green, and blue respectively. HTML designers should be familiar with this notation.

To test the new functionality, we'll need a new HTML file. The following is the final PaintApp.html file:

<title>PaintApp Java Applet</title>

<div align=center>

<h1>PaintApp</h1>
Scribble in the box below.<br>
Right-click to erase.<p>

<applet code=PaintApp width=200 height=200>
<param name="bgcolor" value="FFFFFF">
<param name="fgcolor" value="0000FF">
<param name="bordercolor" value="808080">
This scribble applet requires a Java-enabled browser.
</applet>

</div>

Note how the three parameters are specified. To test PaintApp, we set the background to white (FFFFFF), the foreground to blue (0000FF), and the border to gray (808080). Also note the text right before the </APPLET> tag. This will be displayed in place of the applet if the browser doesn't support Java. (For information on the other tags, consult an HTML reference.)

Now, let's move on to PaintApp. Make the changes marked blue below to the init() method:

public void init() {
	size = size();

	backColor = initColor("bgcolor", getBackground());
	foreColor = initColor("fgcolor", Color.black);
	borderColor = initColor("bordercolor", Color.black);

	clearImage();
}

Instead of hard-coding the color values, we now call the initColor() method to get the values of the parameters. Add this method right after init():

// Get the color from the applet parameters
private Color initColor(String param, Color defColor) {
	try {
		String s;

		if((s = getParameter(param)) != null)
			defColor = new Color(Integer.parseInt(s, 16));
	}
	catch(Exception e) { }

	return defColor;
}

initColor in Detail

The initColor() method is a private function that takes two arguments, a String and a Color object, and returns a Color object specifying the color to use. The String object, param, holds the parameter name, and the Color object, defColor, is the "default" color to use if the parameter isn't available.

After the opening try statement and brace (explained later), we first declare a String object s to hold the value of the parameter. A string is basically a sequence of characters. For example, "Hello World!" would be a string, as would "1+1=2". The empty string is "", with nothing in between. In Java, as these examples illustrate, strings are enclosed in quotation marks (").

The next if statement is quite terse:

if((s = getParameter(param)) != null)

Let's start from the inside of the expression and work our way out. We first call the getParameter() function to get the value associated with param, and this is assigned to s:

(s = getParameter(param))

Now, we expand this a bit further:

(s = getParameter(param)) != null

What does this mean? How can we test the result of an assignment? The answer is that the equals sign (=) is an assignment operator, and this operator returns the value that was assigned.

If the user didn't supply a parameter, getParameter() lets us know by returning null. So here, we compare s to null, and if they aren't equal—a parameter was supplied—we go on to the next statement:

defColor = new Color(Integer.parseInt(s, 16));

Starting from way inside again, we first extract the hexadecimal value from s using the parseInt() method of the Integer class:

Integer.parseInt(s, 16)

This method takes the string to convert, and also requires the number base to use, which in this case is 16—hexadecimal.

Next, we create a new Color object from our value and assign it to defColor. Finally, regardless of whether the if comparison succeeded in the first place, we return defColor:

return defColor;

Error Handling

All right, we finally get to the strange-looking try and catch statements—Java's error-handling mechanism. There are a few things that could go wrong in this routine. (Assume the worst when dealing with user input!) Both the parseInt() method and the creation of the Color object might fail, since they could be fed bad arguments.

So in an imperfect world, we need to watch for errors and deal with them gracefully. In Java, put everything that could possibly go wrong inside a try block. When something does go wrong, Java (or the program, if you wanted) throws something called an exception. An exception object alerts you that there was, in fact, an error, and it can contain additional information about the error.

Now, when you throw something, you'd better have someone catch it, or there's going to be a mess. In Java, add catch blocks right after the try block. Each catch statement takes an Exception argument. When an exception is thrown, Java will find the catch block that deals with that particular exception.

Different functions throw different exceptions (for example, parseInt() throws a NumberFormatException), so you can deal with them individually. (The Java documentation lists the exceptions each method can throw. Also, you can create your own exception objects and throw them using the throw statement.) All of them, however, extend the basic Exception class. You can handle all exceptions by simply catching the basic Exception object. Our initColor() method does just that, and responds by ignoring the error:

catch(Exception e) { }

That's perfectly all right, since initColor() will just return the default color:

return defColor;

Documentation

PaintApp is now functionally complete. In the interest of documenting the applet though, let's look at a couple of functions that return information about the applet: getAppletInfo() and getParameterInfo(). The first method, getAppletInfo(), should return a String containing information such as author, version, and copyright. The second method, getParameterInfo(), should return a String array containing the name, type, and a description of each parameter the applet supports. (Arrays are discussed in more detail later.) You can see how they're used in the complete listing of PaintApp.

You can also move right on to ClockApplet, our next applet.


1