CLIK HERECLICK HERECLICK HERE  
CLICK HERECLICK HERE CLICK HERECLICK HERE

Java Applet Basics

  • Java Applet Basics
    • How Applets and Applications Are Different
    • Creating Applets
      • Major Applet Activities
        • Initialization
        • Starting
        • Stopping
        • Destroying
        • Painting
      • A Simple Applet
    • Including an Applet on a Web Page
      • The <APPLET> Tag
      • Testing the Result
      • Making Java Applets Available to the Web
    • More About the <APPLET> Tag
      • ALIGN
      • HSPACE and VSPACE
      • CODE and CODEBASE
    • Passing Parameters to Applets
    • Summary
    • Q&A


Java Applet Basics

by Laura Lemay
Much of Java's current popularity has come about because of Java-capable World Wide Web browsers and their support for applets: small programs that run inside a Web page and can be used to create dynamic, interactive Web designs. Applets, as I noted at the beginning of this book, are written in the Java language, and can be viewed in any browser that supports Java, including Sun's HotJava and Netscape's Navigator 2.0. Learning how to create applets is most likely the reason you bought this book, so let's waste no more time.
Last week, you focused on learning about the Java language itself, and most of the little programs you created were Java applications. This week, now that you have the basics down, you move on to creating and using applets, which includes a discussion of many of the classes in the standard Java class library.
Today, you'll start with the basics:
  • A small review of differences between Java applets and applications
  • Getting started with applets: the basics of how an applet works and how to create your own simple applets
  • Including an applet on a Web page by using the <APPLET> tag, including the various features of that tag
  • Passing parameters to applets

How Applets and Applications Are Different

Although you explored the differences between Java applications and Java applets in the early part of this book, let's review them.
In short, Java applications are stand-alone Java programs that can be run by using just the Java interpreter, for example, from a command line. Most everything you've used up to this point in the book has been a Java application, albeit a simple one.
Java applets, however, are run from inside a World Wide Web browser. A reference to an applet is embedded in a Web page using a special HTML tag. When a reader, using a Java-enabled browser, loads a Web page with an applet in it, the browser downloads that applet from a Web server and executes it on the local system (the one the browser is running on).
Because Java applets run inside a Java browser, they have the advantage of the structure the browser provides: an existing window, an event-handling and graphics context, and the surrounding user interface. Java applications can also create this structure, but they don't require it (you'll learn how to create Java applications that use applet-like graphics and UI features on Day 14).
The convenience that applets have over applications in terms of structure and UI capabilities, however, is hampered by restrictions on what applets can do. Given the fact that Java applets can be downloaded from anywhere and run on a client's system, restrictions are necessary to prevent an applet from causing system damage or security breaches. Without these restrictions in place, Java applets could be written to contain viruses or trojan horses (programs that seem friendly but do some sort of damage to the system), or be used to compromise the security of the system that runs them. The restrictions on what an applet can do include the following:
  • Applets can't read or write to the reader's file system, except in specific directories (which are defined by the user through an access control list that, by default, is empty). Some browsers may not even allow an applet to read or write to the file system at all, or at the same time as using the network.
  • Applets can't usually communicate with a server other than the one that had originally stored the applet. (This may be configurable by the browser; however, you should not depend on having this behavior available.)
  • Applets can't run any programs on the reader's system. For Unix systems, this includes forking a process.
  • Applets can't load programs native to the local platform, including shared libraries such as DLLs.
In addition, Java itself includes various forms of security and consistency checking in the Java compiler and interpreter to prevent unorthodox use of the language (you'll learn more about this on Day 21). This combination of restrictions and security features make it more difficult for a rogue Java applet to do damage to the client's system.
Note: These restrictions prevent all of the traditional ways of causing damage to a client's system, but it's impossible to be absolutely sure that a clever programmer cannot somehow work around these restrictions, violate privacy, use CPU resources, and be annoying. Sun has asked the Net at large to try to break Java's security and to create an applet that can work around the restrictions imposed on it. You'll learn about more issues in Java security on Day 21.

Creating Applets

For the most part, all the Java programs you've created up to this point have been Java applications—simple programs with a single main() method that created objects, set instance variables, and ran methods. Today and in the days following, you'll be creating applets exclusively, so you will need a good grasp of how an applet works, the sorts of features an applet has, and where to start when you first create your own applets. Without further ado, let's get on with it.
To create an applet, you create a subclass of the class Applet, in the java.applet package. The Applet class provides behavior to enable your applet not only to work within the browser itself, but also to take advantage of the capabilities of AWT to include UI elements, to handle mouse and keyword events, and to draw to the screen. Although your applet can have as many "helper" classes as it needs, it's the main applet class that triggers the execution of the applet. That initial applet class always has a signature like this:
public class myClass extends java.applet.Applet {

    ...

}
Note the public keyword. Java requires that your applet subclass be declared public. Again, this is true only of your main applet class; any helper classes you create can be public or private as you wish. Public, private, and other forms of access control are described on Day 15.
When Java encounters your applet in a Web page, it loads your initial applet class over the network, as well as any other helper classes that first class uses. Unlike with applications, where Java calls the main() method directly on your initial class, when your applet is loaded, Java creates an instance of that class, and a series of Applet methods are called on that instance. Different applets that use the same class use different instances, so each one can behave differently from the other applets running in the same browser.

Major Applet Activities

To create a basic Java application, your class has to have one method, main(), with a specific signature. Then, when your application starts up, main() is executed, and from main() you can set up the behavior that your program needs. Applets are similar but more complicated. Applets have many different activities that correspond to various major events in the life cycle of the applet—for example, initialization, painting, or mouse events. Each activity has a corresponding method, so when an event occurs, the browser or other Java-capable tool calls those specific methods.
The default implementations of these activity methods do nothing; to provide behavior for an event you must override the appropriate method in your applet's subclass. You don't have to override all of them, of course; different applet behavior requires different methods to be overridden.
You'll learn about the various important methods to override as the week progresses, but, for a general overview, here are five of the more important methods in an applet's execution: initialization, starting, stopping, destroying, and painting.
Initialization
Initialization occurs when the applet is first loaded (or reloaded). Initialization might include creating the objects it needs, setting up an initial state, loading images or fonts, or setting parameters. To provide behavior for the initialization of your applet, override the init() method:
public void init() {

    ...

}
Starting
After an applet is initialized, it is started. Starting can also occur if the applet was previously stopped. For example, an applet is stopped if the reader follows a link to a different page, and it is started again when the reader returns to this page. Note that starting can occur several times during an applet's life cycle, whereas initialization happens only once. To provide startup behavior for your applet, override the start() method:
public void start() {

    ...

}
Functionality that you put in the start() method might include starting up a thread to control the applet, sending the appropriate messages to helper objects, or in some way telling the applet to begin running. You'll learn more about starting applets on Day 10.
Stopping
Stopping and starting go hand in hand. Stopping occurs when the reader leaves the page that contains a currently running applet, or you can stop the applet yourself by calling stop(). By default, when the reader leaves a page any threads the applet had started will continue running. You'll learn more about threads in Day 10. By overriding stop(), you can suspend execution of these threads and then restart them if the applet is viewed again:
public void stop() {

    ...

}
Destroying
Destroying sounds more violent than it is. Destroying enables the applet to clean up after itself just before it is freed or the browser exits—for example, to kill any running threads or to release any other running objects. Generally, you won't want to override destroy() unless you have specific resources that need to be released—for example, threads that the applet has created. To provide clean up behavior for your applet, override the destroy() method:
public void destroy() {

    ...

}

Technical Note: How is destroy() different from finalize(), which was described on Day 7? First, destroy() applies only to applets. finalize() is a more general-purpose way for a single object of any type to clean up after itself.
Painting
Painting is how an applet actually draws something on the screen, be it text, a line, a colored background, or an image. Painting can occur many hundreds of times during an applet's life cycle—for example, once after the applet is initialized, if the browser is placed behind another window on the screen and then brought forward again, if the browser window is moved to a different position on the screen, or perhaps repeatedly in the case of animations. You override the paint() method for your applet to have an actual appearance on the screen. The paint() method looks like this:
public void paint(Graphics g) {

    ...

}
Note that unlike the other major methods in this section, paint() takes an argument, an instance of the class Graphics. This object is created and passed to paint by the browser, so you don't have to worry about it. However, you will have to make sure that the Graphics class (part of the java.awt package) gets imported into your applet code, usually through an import statement at the top of your Java file:
import java.awt.Graphics;

A Simple Applet

On Day 2, you created a simple applet called HelloAgainApplet (this was the one with the big red Hello Again). There, you created and used that applet as an example of creating a subclass. Let's go over the code for that applet again, this time looking at it slightly differently in light of the things you just learned about applets. Listing 8.1 shows the code for that applet.
    Listing 8.1. The Hello Again applet.
1:  import java.awt.Graphics;

 2:  import java.awt.Font;

 3:  import java.awt.Color;

 4:

 5:  public class HelloAgainApplet extends java.applet.Applet {

 6:

 7:     Font f = new Font("TimesRoman", Font.BOLD, 36);

 8:

 9:     public void paint(Graphics g) {

10:        g.setFont(f);

11:        g.setColor(Color.red);

12:        g.drawString("Hello again!", 5, 50);

13:     }

14: }
This applet overrides paint(), one of the major methods described in the previous section. Because the applet doesn't actually do much (all it does is print a couple of words to the screen), and there's not really anything to initialize, you don't need a start() or a stop() or an init() method.
The paint method is where the real work of this applet (what little work goes on) really occurs. The Graphics object passed into the paint() method holds the graphics state—that is, the current features of the drawing surface. Lines 10 and 11 set up the font and color for this graphics state (here, the font object held in the f instance variable, and an object representing the color red that's stored in the Color class's variable red).
Line 12 then draws the string "Hello Again!" by using the current font and color at the position 5, 50. Note that the 0 point for x, y is at the top left of the applet's drawing surface, with positive y moving downward, so 50 is actually at the bottom of the applet. Figure 8.1 shows how the applet's bounding box and the string are drawn on the page.

Figure 8.1. Drawing the applet.

Including an Applet on a Web Page

After you create a class or classes that contain your applet and compile them into class files as you would any other Java program, you have to create a Web page that will hold that applet by using the HTML language. There is a special HTML tag for including applets in Web pages; Java-capable browsers use the information contained in that tag to locate the compiled class files and execute the applet itself. In this section, you'll learn about how to put Java applets in a Web page and how to serve those files to the Web at large.
Note: The following section assumes you have at least a passing understanding of writing HTML pages. If you need help in this area, you may find the book Teach Yourself Web Publishing with HTML in 14 Days useful. It is also from Sams.Net (and also written by one of the authors of this book).

The <APPLET> Tag

To include an applet on a Web page, use the <APPLET> tag. <APPLET> is a special extension to HTML for including applets in Web pages. Listing 8.2 shows a very simple example of a Web page with an applet included in it.
    Listing 8.2. A simple HTML page.
1:  <HTML>

 2:  <HEAD>

 3:  <TITLE>This page has an applet on it</TITLE>

 4:  </HEAD>

 5:  <BODY>

 6:  <P>My second Java applet says:

 7:  <BR>

 8:  <APPLET CODE="HelloAgainApplet.class" WIDTH=200 HEIGHT=50>

 9:  There would be an applet here if your browser

10:  supported Java.

11:  </APPLET>

12:  </BODY>

13:  </HTML>
There are three things to note about the <APPLET> tag in this page:
  • The CODE attribute indicates the name of the class file that contains this applet, including the .class extension. In this case, the class file must be in the same directory as this HTML file. To indicate applets are in a specific directory, use CODEBASE, described later today.
  • WIDTH and HEIGHT are required and are used to indicate the bounding box of the applet—that is, how big a box to draw for the applet on the Web page. Be sure you set WIDTH and HEIGHT to be an appropriate size for the applet; depending on the browser, if your applet draws outside the boundaries of the space you've given it, you may not be able to see or get to those parts of the applet outside the bounding box.
  • The text between the <APPLET> and </APPLET> tags is displayed by browsers that do not understand the <APPLET> tag (which includes most browsers that are not Java-capable). Because your page may be viewed in many different kinds of browsers, it is a very good idea to include alternate text here so that readers of your page who don't have Java will see something other than a blank line. Here, you include a simple statement that says There would be an applet here if your browser supported Java.
Note that the <APPLET> tag, like the <IMG> tag, is not itself a paragraph, so it should be enclosed inside a more general text tag, such as <P> or one of the heading tags (<H1>, <H2>, and so on).

Testing the Result

Now with a class file and an HTML file that refers to your applet, you should be able to load that HTML file into your Java-capable browser (using either the Open File... menu item or a file URL, or by indicating the filename on a command line). The browser loads and parses your HTML file, and then loads and executes your applet class.
Figure 8.2 shows the Hello Again applet, in case you've forgotten what it looks like.

Figure 8.2. The Hello Again applet.

Making Java Applets Available to the Web

After you have an applet and an HTML file, and you've verified that everything is working correctly on your local system, the last step is making that applet available to the World Wide Web at large so that anyone with a Java-capable browser can view that applet.
Java applets are served by a Web server the same way that HTML files, images, and other media are. You don't need special server software to make Java applets available to the Web; you don't even need to configure your server to handle Java files. If you have a Web server up and running, or space on a Web server available to you, all you have to do is move your HTML and compiled class files to that server, as you would any other file.
If you don't have a Web server, you have to rent space on one or set one up yourself. (Web server setup and administration, as well as other facets of Web publishing in general, are outside the scope of this book.)

More About the <APPLET> Tag

In its simplest form, by using CODE, WIDTH, and HEIGHT, the <APPLET> tag merely creates a space of the appropriate size and then loads and runs the applet in that space. The <APPLET> tag, however, does include several attributes that can help you better integrate your applet into the overall design of your Web page.
Note: The attributes available for the <APPLET> tag are almost identical to those for the HTML <IMG> tag.

ALIGN

The ALIGN attribute defines how the applet will be aligned on the page. This attribute can have one of nine values: LEFT, RIGHT, TOP, TEXTTOP, MIDDLE, ABSMIDDLE, BASELINE, BOTTOM, and ABSBOTTOM.
In the case of ALIGN=LEFT and ALIGN=RIGHT, the applet is placed at the left or right margins of the page, respectively, and all text following that applet flows in the space to the right or left of that applet. The text will continue to flow in that space until the end of the applet, or you can use a line break tag (<BR>) with the CLEAR attribute to start the left line of text below that applet. The CLEAR attribute can have one of three values: CLEAR=LEFT starts the text at the next clear left margin, CLEAR=RIGHT does the same for the right margin, and CLEAR=ALL starts the text at the next line where both margins are clear.
For example, here's a snippet of HTML code that aligns an applet against the left margin, has some text flowing alongside it, and then breaks at the end of the paragraph so that the next bit of text starts below the applet:
<P><APPLET CODE="HelloAgainApplet" WIDTH=300 HEIGHT=200

ALIGN=LEFT>Hello Again!</APPLET>

To the left of this paragraph is an applet. It's a

simple, unassuming applet, in which a small string is

printed in red type, set in 36 point Times bold.

<BR CLEAR=ALL>

<P>In the next part of the page, we demonstrate how

under certain conditions, styrofoam peanuts can be

used as a healthy snack.
Figure 8.3 shows how this applet and the text surrounding it might appear in a Java-capable browser.
Figure 8.3. An applet aligned left.
For smaller applets, you may want to include your applet within a single line of text. To do this, there are seven values for ALIGN that determine how the applet is vertically aligned with the text:
  • ALIGN=TEXTTTOP aligns the top of the applet with the top of the tallest text in the line.
  • ALIGN=TOP aligns the applet with the topmost item in the line (which may be another applet, or an image, or the top of the text).
  • ALIGN=ABSMIDDLE aligns the middle of the applet with the middle of the largest item in the line.
  • ALIGN=MIDDLE aligns the middle of the applet with the middle of the baseline of the text.
  • ALIGN=BASELINE aligns the bottom of the applet with the baseline of the text. ALIGN=BASELINE is the same as ALIGN=BOTTOM, but ALIGN=BASELINE is a more descriptive name.
  • ALIGN=ABSBOTTOM aligns the bottom of the applet with the lowest item in the line (which may be the baseline of the text or another applet or image).
Figure 8.4 shows the various alignment options, where the line is an image and the arrow is a small applet.
Figure 8.4. Applet alignment options.

HSPACE and VSPACE

The HSPACE and VSPACE attributes are used to set the amount of space, in pixels, between an applet and its surrounding text. HSPACE controls the horizontal space (the space to the left and right of the applet). VSPACE controls the vertical space (the space above and below). For example, here's that sample snippet of HTML with vertical space of 50 and horizontal space of 10:
<P><APPLET CODE="HelloAgainApplet" WIDTH=300 HEIGHT=200

ALIGN=LEFT VSPACE=50 HSPACE=10>Hello Again!</APPLET>

To the left of this paragraph is an applet. It's a

simple, unassuming applet, in which a small string is

printed in red type, set in 36 point Times bold.

<BR CLEAR=ALL>

<P>In the next part of the page, we demonstrate how

under certain conditions, styrofoam peanuts can be

used as a healthy snack.
The result in a typical Java browser might look like that in Figure 8.5.
Figure 8.5. Vertical and horizontal space.

CODE and CODEBASE

CODE is used to indicate the name of the class file that holds the current applet. If CODE is used alone in the <APPLET> tag, the class file is searched for in the same directory as the HTML file that references it.
If you want to store your class files in a different directory than that of your HTML files, you have to tell the Java-capable browser where to find those class files. To do this, you use CODEBASE. CODE contains only the name of the class file; CODEBASE contains an alternate pathname where classes are contained. For example, if you store your class files in a directory called /classes, which is in the same directory as your HTML files, CODEBASE is the following:
<APPLET CODE="myclass.class" CODEBASE="classes"

    WIDTH=100 HEIGHT=100></APPLET>

Passing Parameters to Applets

With Java applications, you can pass parameters to your main() routine by using arguments on the command line. You can then parse those arguments inside the body of your class, and the application acts accordingly based on the arguments it is given.
Applets, however, don't have a command line. How do you pass in different arguments to an applet? Applets can get different input from the HTML file that contains the <APPLET> tag through the use of applet parameters. To set up and handle parameters in an applet, you need two things:
  • A special parameter tag in the HTML file
  • Code in your applet to parse those parameters
Applet parameters come in two parts: a name, which is simply a name you pick, and a value, which determines the value of that particular parameter. So, for example, you can indicate the color of text in an applet by using a parameter with the name color and the value red. You can determine an animation's speed using a parameter with the name speed and the value 5.
In the HTML fie that contains the embedded applet, you indicate each parameter using the <PARAM> tag, which has two attributes for the name and the value, called (surprisingly enough), NAME and VALUE. The <PARAM> tag goes inside the opening and closing <APPLET> tags:
<APPLET CODE="MyApplet.class" WIDTH=100 HEIGHT=100>

<PARAM NAME=font VALUE="TimesRoman">

<PARAM NAME=size VALUE="36">

A Java applet appears here.</APPLET>
This particular example defines two parameters to the MyApplet applet: one whose name is font and whose value is TimesRoman, and one whose name is size and whose value is 36.
Parameters are passed to your applet when it is loaded. In the init() method for your applet, you can then get hold of those parameters by using the getParameter() method. getParameter() takes one argument—a string representing the name of the parameter you're looking for—and returns a string containing the corresponding value of that parameter. (Like arguments in Java applications, all the parameter values are strings.) To get the value of the font parameter from the HTML file, you might have a line such as this in your init() method:
String theFontName = getParameter("font");

Note: The names of the parameters as specified in <PARAM> and the names of the parameters in getParameter() must match identically, including having the same case. In other words, <PARAM NAME="name"> is different from <PARAM NAME="Name">. If your parameters are not being properly passed to your applet, make sure the parameter cases match.
Note that if a parameter you expect has not been specified in the HTML file, getParameter() returns null. Most often, you will want to test for a null parameter and supply a reasonable default:
if (theFontName == null)

    theFontName = "Courier"
Keep in mind that getParameter() returns strings—if you want a parameter to be some other object or type, you have to convert it yourself. To parse the size parameter from that same HTML file and assign it to an integer variable called theSize, you might use the following lines:
int theSize;

String s = getParameter("size");

if (s == null)

    theSize = 12;

else theSize = Integer.parseInt(s);
Get it? Not yet? Let's create an example of an applet that uses this technique. You'll modify the HelloAgainApplet so that it says hello to a specific name, for example "Hello Bill" or "Hello Alice". The name is passed into the applet through an HTML parameter.
Let's start by copying the original HelloAgainApplet class:
import java.awt.Graphics;

import java.awt.Font;

import java.awt.Color;

public class MoreHelloApplet extends java.applet.Applet {

    Font f = new Font("TimesRoman", Font.BOLD, 36);

    public void paint(Graphics g) {

        g.setFont(f);

        g.setColor(Color.red);

        g.drawString("Hello Again!", 5, 50);

    }

}
The first thing you need to add to this class is a place for the name. Because you'll need that name throughout the applet, let's add an instance variable for the name, just after the variable for the font:
String name;
To set a value for the name, you have to get the parameter. The best place to handle parameters to an applet is inside an init() method. The init() method is defined similarly to paint() (public, with no arguments, and a return type of void). Make sure when you test for a parameter that you test for a value of null. The default, in this case, if a name isn't indicated, is to say hello to "Laura":
public void init() {

name = getParameter("name");

    if (name == null)

        name = "Laura";

    }
One last thing to do now that you have the name from the HTML parameters is to modify the name so that it's a complete string—that is, to tack "Hello " onto the beginning, and an exclamation point onto the end. You could do this in the paint method just before printing the string to the screen. Here it's done only once, however, whereas in paint() it's done every time the screen is repainted—in other words, it's slightly more efficient to do it inside init() instead:
name = "Hello " + name + "!";
And now, all that's left is to modify the paint() method. The original drawString() method looked like this:
g.drawString("Hello Again!", 5, 50);
To draw the new string you have stored in the name instance variable, all you need to do is substitute that variable for the literal string:
g.drawString(name, 5, 50);
Listing 8.3 shows the final result of the MoreHelloApplet class. Compile it so that you have a class file ready.
    Listing 8.3. The MoreHelloApplet class.
1:  import java.awt.Graphics;

 2:  import java.awt.Font;

 3:  import java.awt.Color;

 4:

 5:  public class MoreHelloApplet extends java.applet.Applet {

 6:

 7:     Font f = new Font("TimesRoman", Font.BOLD, 36);

 8:     String name;

 9:

10:     public void init() {

11:         name = getParameter("name");

12:         if (name == null)

13:             name = "Laura";

14:

15:         name = "Hello " + name + "!";

16:     }

17:

18:     public void paint(Graphics g) {

19:         g.setFont(f);

20:         g.setColor(Color.red);

21:         g.drawString(name, 5, 50);

22:     }

23: }
Now, let's create the HTML file that contains this applet. Listing 8.4 shows a new Web page for the MoreHelloApplet applet.
    Listing 8.4. The HTML file for the MoreHelloApplet applet.
1:  <HTML>

 2:  <HEAD>

 3:  <TITLE>Hello!</TITLE>

 4:  </HEAD>

 5:  <BODY>

 6:  <P>

 7:  <APPLET CODE="MoreHelloApplet.class" WIDTH=300 HEIGHT=50>

 8:  <PARAM NAME=name VALUE="Bonzo">

 9:  Hello to whoever you are!

10: </APPLET>

11: </BODY>

12: </HTML>
Note the <APPLET> tag, which points to the class file for the applet with the appropriate width and height (300 and 50). Just below it (line 8) is the <PARAM> tag, which you use to pass in the name. Here, the NAME parameter is simply name, and the VALUE is the string "Bonzo".
Loading up this HTML file produces the result shown in Figure 8.6.

Figure 8.6. The result of MoreHelloApplet, first try.
Let's try a second example. Remember that in the code for MoreHelloApplet, if no name is specified, the default is the name "Laura". Listing 8.5 creates an HTML file with no parameter tag for name.
    Listing 8.5. Another HTML File for the MoreHelloApplet applet.
1: <HTML>

 2: <HEAD>

 3: <TITLE>Hello!</TITLE>

 4: </HEAD>

 5: <BODY>

 6: <P>

 7: <APPLET CODE="MoreHelloApplet.class" WIDTH=300 HEIGHT=50>

 8: Hello to whoever you are!

 9: </APPLET>

10: </BODY>

11: </HTML>
Here, because no name was supplied, the applet uses the default, and the result is what you might expect (see Figure 8.7).
Figure 8.7. The result of MoreHelloApplet, second try.

Summary

Applets are probably the most common use of the Java language today. Applets are more complicated than many Java applications because they are executed and drawn inline within Web pages, but they can access the graphics, user interface, and event structure provided by the Web browser itself. Today, you learned the basics of creating applets, including the following things:
  • All applets you develop using Java inherit from the Applet class, part of the java.applet package. The Applet class provides basic behavior for how the applet will be integrated with and react to the browser and various forms of input from that browser and the person running it. By subclassing Applet, you have access to all that behavior.
  • Applets have five main methods, which are used for the basic activities an applet performs during its life cycle: init(), start(), stop(), destroy(), and paint(). Although you don't need to override all these methods, these are the most common methods you'll see repeated in many of the applets you'll create in this book and in other sample programs.
  • To run a compiled applet class file, you include it in an HTML Web page by using the <APPLET> tag. When a Java-capable browser comes across <APPLET>, it loads and runs the applet described in that tag. Note that to publish Java applets on the World Wide Web alongside HTML files you do not need special server software; any plain old Web server will do just fine.
  • Unlike applications, applets do not have a common line on which to pass arguments, so those arguments must be passed into the applet through the HTML file that contains it. You indicate parameters in an HTML file by using the <PARAM> tag inside the opening and closing <APPLET> tags. <PARAM> has two attributes: NAME for the name of the parameter, and VALUE for its value. Inside the body of your applet (usually in init()), you can then gain access to those parameters using the getParameter() method.

Q&A

Q: In the first part of today's lesson, you say that applets are downloaded from random Web servers and run on the client's system. What's to stop an applet developer from creating an applet that deletes all the files on that system, or in some other way compromises the security of the system? A: Recall that Java applets have several restrictions that make it difficult for all of the more obvious malicious behavior to take place. For example, because Java applets cannot read or write files on the client system, they cannot delete files or read system files that might contain private information. Because they cannot run programs on the client's system without your express permission, they cannot, for example, run system programs pretending to be you. Nor can they run so many programs that your system crashes.
In addition, Java's very architecture makes it difficult to circumvent these restrictions. The language itself, the Java compiler, and the Java interpreter all have checks to make sure that no one has tried to sneak in bogus code or play games with the system itself. You'll learn more about these checks at the end of this book.

Of course, no system can claim to be 100% secure, and the fact that Java applets are run on your system should make you suspicious—see Day 21 for more on security.
Q: Wait a minute. If I can't read or write files or run programs on the system the applet is running on, doesn't that mean I basically can't do anything other than simple animations and flashy graphics? How can I save state in an applet? How can I create, say, a word processor or a spreadsheet as a Java applet? A: For everyone who doesn't believe that Java is secure enough, there is someone who believes that Java's security restrictions are too severe for just these reasons. Yes, Java applets are limited because of the security restrictions. But given the possibility for abuse, I believe that it's better to err on the side of being more conservative as far as security is concerned. Consider it a challenge.
Keep in mind, also, that Java applications have none of the restrictions that Java applets do, but because they are also compiled to bytecode, they are portable across platforms. It may be that the thing you want to create would make a much better application than an applet.
Q: I have an older version of HotJava. I followed all the examples in this section, but HotJava cannot read my applets (it seems to ignore them). What's going on? A: You most likely have an alpha version of HotJava. Recall that significant changes were made to the Java API and how Java applets are written between alpha and the 1.0 release. The results of these changes are that browsers that support alpha applets cannot read beta applets, and vice versa. The HTML tags are even different, so an older browser just skips over newer applets, and vice versa.
By the time you read this, there may be a new version of HotJava with support for 1.0. If not, you can use Netscape 2.0 or the JDK's applet viewer to view applets written to the beta specification.
Q: I noticed in my documentation that the <APPLET> tag also has a NAME attribute. You didn't discuss it here. A: NAME is used when you have multiple applets on a page that need to communicate with each other. You'll learn about this on Day 12. Q: I have an applet that takes parameters and an HTML file that passes it those parameters. But when my applet runs, all I get are null values. What's going on here? A: Do the names of your parameters (in the NAME attribute) match exactly with the names you're testing for in getParameter()? They must be exact, including case, for the match to be made. Make sure also that your <PARAM> tags are inside the opening and closing <APPLET> tags, and that you haven't misspelled anything.

More About Methods

  • More About Methods
    • Creating Methods with the Same Name, Different Arguments
    • Constructor Methods
      • Basic Constructors
      • Calling Another Constructor
      • Overloading Constructors
    • Overriding Methods
      • Creating Methods that Override Existing Methods
      • Calling the Original Method
      • Overriding Constructors
    • Finalizer Methods
    • Summary
    • Q&A


More About Methods

by Laura Lemay Methods are arguably the most important part of any object-oriented language. Whereas classes and objects provide the framework, and class and instance variables provide a way of holding that class or object's attributes and state, it is the methods that actually provide an object's behavior and define how that object interacts with other objects in the system.
Yesterday, you learned a little about defining methods. With what you learned yesterday, you could create lots of Java programs, but you'd be missing some of the features of methods that make them really powerful, that make your objects and classes more efficient and easier to understand. Today, you'll learn about these additional features, including the following:
  • Overloading methods—that is, creating methods with multiple signatures and definitions but with the same name
  • Creating constructor methods—methods that enable you to initialize objects to set up their initial state when created
  • Overriding methods—creating a different definition for a method that has been defined in a superclass
  • Finalizer methods—a way for an object to clean up after itself before it is removed from the system

Creating Methods with the Same Name, Different Arguments

Yesterday, you learned how to create methods with a single name and a single signature. Methods in Java can also be overloaded—that is, you can create methods that have the same name, but different signatures and different definitions. Method overloading enables instances of your class to have a simpler interface to other objects (no need for entirely different methods that do essentially the same thing) and to behave differently based on the input to that method.
When you call a method in an object, Java matches up the method name and the number and type of arguments to choose which method definition to execute.
To create an overloaded method, all you need to do is create several different method definitions in your class, all with the same name, but with different parameter lists (either in number or type of arguments). Java allows method overloading as long as each parameter list is unique for the same method name.
Note that Java differentiates overloaded methods with the same name, based on the number and type of parameters to that method, not on its return type. That is, if you try to create two methods with the same name, same parameter list, but different return types, you'll get a compiler error. The variable names you choose for each parameter to the method are irrelevant—all that matters is the number and the type.
Here's an example of creating an overloaded method. Listing 7.1 shows a simple class definition for a class called MyRect, which defines a rectangular shape. The MyRect class has four instance variables to define the upper left and lower right corners of the rectangle: x1, y1, x2, and y2.

Note: Why did I call it MyRect? Java's awt package has a class called Rectangle that implements much of this same behavior. I called this class MyRect to prevent confusion between the two classes.
    Listing 7.1. The MyRect class.
class MyRect {

    int x1 = 0;

    int y1 = 0;

    int x2 = 0;

    int y2 = 0;

}
When a new instance of the myRect class is initially created, all its instance variables are initialized to 0. Let's define a buildRect() method that takes four integer arguments and "resizes" the rectangle to have the appropriate values for its corners, returning the resulting rectangle object (note that because the arguments have the same names as the instance variables, you have to make sure to use this to refer to them):
MyRect buildRect(int x1, int y1, int x2, int y2) {

    this.x1 = x1;

    this.y1 = y1;

    this.x2 = x2;

    this.y2 = y2;

    return this;

}
What if you want to define a rectangle's dimensions in a different way—for example, by using Point objects rather than individual coordinates? You can overload buildRect() so that its parameter list takes two Point objects (note that you'll need to import the Point class at the top of your source file so Java can find it):
MyRect buildRect(Point topLeft, Point bottomRight) {

    x1 = topLeft.x;

    y1 = topLeft.y;

    x2 = bottomRight.x;

    y2 = bottomRight.y;

    return this;

}
Perhaps you want to define the rectangle using a top corner and a width and height. Just create a different definition for buildRect():
MyRect buildRect(Point topLeft, int w, int h) {

    x1 = topLeft.x;

    y1 = topLeft.y;

    x2 = (x1 + w);

    y2 = (y1 + h);

    return this;

}
To finish up this example, let's create a method to print out the rectangle's coordinates, and a main() method to test it all (just to prove that this does indeed work). Listing 7.2 shows the completed class definition with all its methods.
    Listing 7.2. The complete MyRect class.
import java.awt.Point;

class MyRect {

    int x1 = 0;

    int y1 = 0;

    int x2 = 0;

    int y2 = 0;

    MyRect buildRect(int x1, int y1, int x2, int y2) {

        this.x1 = x1;

        this.y1 = y1;

        this.x2 = x2;

        this.y2 = y2;

        return this;

    }

    MyRect buildRect(Point topLeft, Point bottomRight) {

        x1 = topLeft.x;

        y1 = topLeft.y;

        x2 = bottomRight.x;

        y2 = bottomRight.y;

        return this;

    }

    MyRect buildRect(Point topLeft, int w, int h) {

        x1 = topLeft.x;

        y1 = topLeft.y;

        x2 = (x1 + w);

        y2 = (y1 + h);

        return this;

    }

    void printRect(){

        System.out.print("MyRect: <" + x1 + ", " + y1);

        System.out.println(", " + x2 + ", " + y2 + ">");

    }

    public static void main(String args[]) {

        MyRect rect = new MyRect();

        System.out.println("Calling buildRect with coordinates 25,25 50,50:");

        rect.buildRect(25, 25, 50, 50);

        rect.printRect();

        System.out.println("—————");

        System.out.println("Calling buildRect w/points (10,10), (20,20):");

        rect.buildRect(new Point(10,10), new Point(20,20));

        rect.printRect();

        System.out.println("—————");

        System.out.print("Calling buildRect w/1 point (10,10),");

        System.out.println(" width (50) and height (50)");

        rect.buildRect(new Point(10,10), 50, 50);

        rect.printRect();

        System.out.println("—————");

    }

}
Here's the output of this Java program:
Calling buildRect with coordinates 25,25 50,50:

MyRect: <25, 25, 50, 50>

—————

Calling buildRect w/points (10,10), (20,20):

MyRect: <10, 10, 20, 20>

—————

Calling buildRect w/1 point (10,10), width (50) and height (50)

MyRect: <10, 10, 60, 60>

—————
As you can see from this example, all the buildRect() methods work based on the arguments with which they are called. You can define as many versions of a method as you need to in your own classes to implement the behavior you need for that class.

Constructor Methods

In addition to regular methods, you can also define constructor methods in your class definition.
A constructor method is a special kind of method that determines how an object is initialized when it's created.
Unlike regular methods, you can't call a constructor method by calling it directly; instead, constructor methods are called by Java automatically. Here's how it works: when you use new to create a new instance of a class, Java does three things:
  • Allocates memory for the object
  • Initializes that object's instance variables, either to their initial values or to a default (0 for numbers, null for objects, false for booleans, '\0' for characters)
  • Calls the class's constructor method (which may be one of several methods)
If a class doesn't have any special constructor methods defined, you'll still end up with an object, but you might have to set its instance variables or call other methods that object needs to initialize itself. All the examples you've created up to this point have behaved like this.
By defining constructor methods in your own classes, you can set initial values of instance variables, call methods based on those variables or call methods on other objects, or calculate initial properties of your object. You can also overload constructors, as you would regular methods, to create an object that has specific properties based on the arguments you give to new.

Basic Constructors

Constructors look a lot like regular methods, with two basic differences:
  • Constructors always have the same name as the class.
  • Constructors don't have a return type.
For example, Listing 7.3 shows a simple class called Person, with a constructor that initializes its instance variables based on the arguments to new. The class also includes a method for the object to introduce itself, and a main() method to test each of these things.
    Listing 7.3. The Person class.
class Person {

    String name;

    int age;

    Person(String n, int a) {

        name = n;

        age = a;

    }

    void printPerson() {

        System.out.print("Hi, my name is " + name);

        System.out.println(". I am " + age + " years old.");

    }

    public static void main (String args[]) {

        Person p;

        p = new Person("Laura", 20);

        p.printPerson();

        System.out.println("————");

        p = new Person("Tommy", 3);

        p.printPerson();

        System.out.println("————");

    }

}
Here's the output for this example program:
Hi, my name is Laura. I am 20 years old.

————

Hi, my name is Tommy. I am 3 years old.

————

Calling Another Constructor

Some constructors you write may be a superset of another constructor defined in your class; that is, they might have the same behavior plus a little bit more. Rather than duplicating identical behavior in multiple constructor methods in your class, it makes sense to be able to just call that first constructor from inside the body of the second constructor. Java provides a special syntax for doing this. To call a constructor defined on the current class, use this form:
this(arg1, arg2, arg3...);
The arguments to this are, of course, the arguments to the constructor.

Overloading Constructors

Like regular methods, constructors can also take varying numbers and types of parameters, enabling you to create your object with exactly the properties you want it to have, or for it to be able to calculate properties from different kinds of input.
For example, the buildRect() methods you defined in the MyRect class earlier today would make excellent constructors, because what they're doing is initializing an object's instance variables to the appropriate values. So, instead of the original buildRect() method you had defined (which took four parameters for the coordinates of the corners), you can create a constructor instead. Listing 7.4 shows a new class, called MyRect2, that has all the same functionality of the original MyRect, except with overloaded constructor methods instead of the buildRect() method.
    Listing 7.4. The MyRect2 class (with constructors).
import java.awt.Point;

class MyRect2 {

    int x1 = 0;

    int y1 = 0;

    int x2 = 0;

    int y2 = 0;

    MyRect2(int x1, int y1, int x2, int y2) {

        this.x1 = x1;

        this.y1 = y1;

        this.x2 = x2;

        this.y2 = y2;

    }

    MyRect2(Point topLeft, Point bottomRight) {

        x1 = topLeft.x;

        y1 = topLeft.y;

        x2 = bottomRight.x;

        y2 = bottomRight.y;

    }

    MyRect2(Point topLeft, int w, int h) {

        x1 = topLeft.x;

        y1 = topLeft.y;

        x2 = (x1 + w);

        y2 = (y1 + h);

    }

    void printRect() {

        System.out.print("MyRect: <" + x1 + ", " + y1);

        System.out.println(", " + x2 + ", " + y2 + ">");

    }

    public static void main(String args[]) {

        MyRect2 rect;

        System.out.println("Calling MyRect2 with coordinates 25,25 50,50:");

        rect = new MyRect2(25, 25, 50,50);

        rect.printRect();

        System.out.println("—————");

        System.out.println("Calling MyRect2 w/points (10,10), (20,20):");

        rect= new MyRect2(new Point(10,10), new Point(20,20));

        rect.printRect();

        System.out.println("—————");

        System.out.print("Calling MyRect2 w/1 point (10,10),");

        System.out.println(" width (50) and height (50)");

        rect = new MyRect2(new Point(10,10), 50, 50);

        rect.printRect();

        System.out.println("—————");

    }

}
Here's the output for this example program (it's the same output from the previous example; only the code to produce it has changed):
Calling MyRect2 with coordinates 25,25 50,50:

MyRect: <25, 25, 50, 50>

—————

Calling MyRect2 w/points (10,10), (20,20):

MyRect: <10, 10, 20, 20>

—————

Calling MyRect2 w/1 point (10,10), width (50) and height (50)

MyRect: <10, 10, 60, 60>

—————

Overriding Methods

When you call a method on an object, Java looks for that method definition in the class of that object, and if it doesn't find one, it passes the method call up the class hierarchy until a method definition is found. Method inheritance enables you to define and use methods repeatedly in subclasses without having to duplicate the code itself.
However, there may be times when you want an object to respond to the same methods but have different behavior when that method is called. In this case, you can override that method. Overriding a method involves defining a method in a subclass that has the same signature as a method in a superclass. Then, when that method is called, the method in the subclass is found and executed instead of the one in the superclass.

Creating Methods that Override Existing Methods

To override a method, all you have to do is create a method in your subclass that has the same signature (name, return type, and parameter list) as a method defined by one of your class's superclasses. Because Java executes the first method definition it finds that matches the signature, this effectively "hides" the original method definition. Here's a simple example; Listing 7.5 shows a simple class with a method called printMe(), which prints out the name of the class and the values of its instance variables.
    Listing 7.5. The PrintClass class.
class PrintClass {

    int x = 0;

    int y = 1;

    void printMe() {

        System.out.println("X is " + x + ", Y is " + y);

        System.out.println("I am an instance of the class " +

        this.getClass().getName());

    }

}
Listing 7.6 shows a class called PrintSubClass that is a subclass of (extends) PrintClass. The only difference between PrintClass and PrintSubClass is that the latter has a z instance variable.
    Listing 7.6. The PrintSubClass class.
class PrintSubClass extends PrintClass {

    int z = 3;

    public static void main(String args[]) {

        PrintSubClass obj = new PrintSubClass();

        obj.printMe();

    }

}
Here's the output from PrintSubClass:
X is 0, Y is 1

I am an instance of the class PrintSubClass
In the main() method of PrintSubClass, you create a PrintSubClass object and call the printMe() method. Note that PrintSubClass doesn't define this method, so Java looks for it in each of PrintSubClass's superclasses—and finds it, in this case, in PrintClass. Unfortunately, because printMe() is still defined in PrintClass, it doesn't print the z instance variable.
Now, let's create a third class. PrintSubClass2 is nearly identical to PrintSubClass, but you override the printMe() method to include the z variable. Listing 7.7 shows this class.
    Listing 7.7. The PrintSubClass2 class.
class PrintSubClass2 extends PrintClass {

    int z = 3;

    void printMe() {

        System.out.println("x is " + x + ", y is " + y +

               ", z is " + z);

        System.out.println("I am an instance of the class " +

               this.getClass().getName());

    }

    public static void main(String args[]) {

        PrintSubClass2 obj = new PrintSubClass2();

        obj.printMe();

    }

}
Now, when you instantiate this class and call the printMe() method, the version of printMe() you defined for this class is called instead of the one in the superclass PrintClass (as you can see in this output):
x is 0, y is 1, z is 3

I am an instance of the class PrintSubClass2

Calling the Original Method

Usually, there are two reasons why you want to override a method that a superclass has already implemented:
  • To replace the definition of that original method completely
  • To augment the original method with additional behavior
You've already learned about the first one; by overriding a method and giving that method a new definition, you've hidden the original method definition. But sometimes you may just want to add behavior to the original definition rather than erase it altogether. This is particularly useful where you end up duplicating behavior in both the original method and the method that overrides it; by being able to call the original method in the body of the overridden method, you can add only what you need.
To call the original method from inside a method definition, use the super keyword to pass the method call up the hierarchy:
void myMethod (String a, String b) {

    // do stuff here

    super.myMethod(a, b);

    // maybe do more stuff here

}
The super keyword, somewhat like the this keyword, is a placeholder for this class's superclass. You can use it anywhere you can use this, but to refer to the superclass rather than to the current class.
For example, Listing 7.8 shows those printMe() methods used in the previous example.
    Listing 7.8. The printMe methods.
// from PrintClass

void printMe() {

        System.out.println("X is " + x + ", Y is " + y);

        System.out.println("I am an instance of the class" +

               this.getClass().getName());

    }

}

//from PrintSubClass2

    void printMe() {

        System.out.println("X is " + x + ", Y is " + y + ", Z is " + z);

        System.out.println("I am an instance of the class " +

               this.getClass().getName());

    }
Rather than duplicating most of the behavior of the superclass's method in the subclass, you can rearrange the superclass's method so that additional behavior can easily be added:
// from PrintClass

void printMe() {

    System.out.println("I am an instance of the class" +

                 this.getClass().getName());

    System.out.println("X is " + x);

    System.out.println("Y is " + y);

}
Then, in the subclass, when you override printMe, you can merely call the original method and then add the extra stuff:
// From PrintSubClass2

void printMe() {

    super.printMe();

    System.out.println("Z is " + z);

}
Here's the output of calling printMe() on an instance of the subclass:
I am an instance of the class PrintSubClass2

X is 0

Y is 1

Z is 3

Overriding Constructors

Constructors cannot technically be overridden. Because they always have the same name as the current class, you're always creating new constructors instead of inheriting the ones you've got. Much of the time, this is fine, because when your class's constructor is called, the constructor with the same signature for all your superclass is also called, so initialization of all the parts of a class you inherit can happen.
However, when you're defining constructors for your own class, you may want to change how your object is initialized, not only by initializing new variables your class adds, but also to change the contents of variables that are already there. You do this by explicitly calling your superclass's constructors, and then changing whatever you like.
To call a regular method in a superclass, you use super.methodname(arguments). Because with constructors you don't have a method name to call, however, you have to use a different form:
super(arg1, arg2, ...);
Similar to using this(...) in a constructor, super(...) calls the constructor method for the immediate superclass (which may, in turn, call the constructor of its superclass, and so on).
For example, Listing 7.9 shows a class called NamedPoint, which extends the class Point from Java's awt package. The Point class has only one constructor, which takes an x and a y argument and returns a Point object. NamedPoint has an additional instance variable (a string for the name) and defines a constructor to initialize x, y, and the name.
    Listing 7.9. The NamedPoint class.
1: import java.awt.Point;

2: class NamedPoint extends Point {

3:     String name;

4:

5:     NamedPoint(int x, int y, String name) {

6:        super(x,y);

7:         this.name = name;

8:     }

9: }
The constructor defined here for NamedPoint (lines 6 through 8) calls Point's constructor method to initialize Point's instance variables (x and y). Although you can just as easily initialize x and y yourself, you may not know what other things Point is doing to initialize itself, so it's always a good idea to pass constructors up the hierarchy to make sure everything is set up correctly.

Finalizer Methods

Finalizer methods are like the opposite of constructor methods; whereas a constructor method is used to initialize an object, finalizer methods are called just before the object is garbage-collected and its memory reclaimed.
The finalizer method is simply finalize(). The Object class defines a default finalizer method, which does nothing. To create a finalizer method for your own classes, override the finalize() method using this signature:
protected void finalize() {

    ...

}
Inside the body of that finalize() method, include any cleaning up you want to do for that object. You can also call super.finalize() to allow your class's superclasses to finalize your object, if necessary.
You can always call the finalize() method yourself at any time; it's just a plain method like any other. However, calling finalize() does not trigger an object to be garbage-collected. Only removing all references to an object will cause it to be marked for deleting.
Finalizer methods are best used for optimizing the removal of an object—for example, by removing references to other objects, by releasing external resources that have acquired, or for other behaviors that may make it easier for that object to be removed. In most cases, you will not need to use finalize() at all. See Day 21 for more about garbage collection and finalize().

Summary

Today, you learned all kinds of techniques for using, reusing, defining, and redefining methods. You learned how to overload a method name so that the same method can have different behaviors based on the arguments with which it's called. You learned about constructor methods, which are used to initialize a new object when it's created. You learned about method inheritance and how to override methods that have been defined in a class's superclasses. Finally, you learned about finalizer methods, that can be used to clean up after an object just before that object is garbage-collected and its memory reclaimed.
Congratulations on completing your first week of Teach Yourself Java in 21 Days! Starting next week, you'll apply everything you've learned this week to writing Java applets and to working with more advanced concepts in putting together Java programs and working with the standard Java class libraries.

Q&A

Q: I created two methods with the following signatures:
int total(int arg1, int arg2, int arg3) {...} float total(int arg1, int arg2, int arg3) {...}
The Java compiler complains when I try to compile the class with these method definitions. But their signatures are different—what have I done wrong? A: Method overloading in Java works only if the parameter lists are different—either in number or type of arguments. Return type is not relevant for method overloading. Think about it—if you had two methods with exactly the same parameter list, how would Java know which one to call? Q: Can I overload overridden methods (that is, can I create methods that have the same name as an inherited method, but a different parameter list)? A: Sure! As long as a parameter lists vary, it doesn't matter whether you've defined a new method name or one that you've inherited from a superclass.