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 DetailThe 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 equala parameter was suppliedwe 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 16hexadecimal.
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;
All right, we finally get to the strange-looking try
and catch
statementsJava'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;
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.