Applet Basics

In this section, we'll go over applet basics. We'll start with a series of simple examples that demonstrate the principles of applet development. We'll use this opportunity to study such diverse but interrelated technologies as HTML files, browsers, Just-in-Time (JIT) compilers, and machine-independent code. We'll expand on this knowledge in later sections of the chapter.

Overview

You can run Visual J Plus Plus v6 .EXE apps on any of the Microsoft Win32 operating systems without the help of external files or tools. By contrast, Java applets exist only in the context of an HTML file. You run an applet by using a Web browser to open an HTML page that is linked to that applet.

The Java Virtual Machine

Normal executable files (.EXE files) such as those generated by Visual C++ contain machine code designed to run on the base processor; in the case of the PC, this code is 80x86 machine code. The Pentium processor uses the same machine instructions as the other members of the 80x86 family.

All Java compilers, including Visual J Plus Plus v6, compile Java source code into a special machine language called Virtual Machine (VM) byte code. This machine language is called virtual because the VM doesn't really exist. Instead, each Java-equipped browser has an interpreter inside it capable of executing VM byte codes on the base machine. In other words, a browser for a PC executes the VM byte codes on an 80x86_equipped machine. A Macintosh browser interprets VM byte codes into PowerPC instructions. A browser on a UNIX workstation interprets VM byte codes into the native machine instructions for the workstation's processor.

The use of VM byte codes is almost a necessity for applets to run on the Web, because the applet programmer never knows what type of browser might access the Web page. Using VM byte codes provides platform independence so that the applet executes in the same way no matter what base machine it's running on. In addition, the format of the VM byte codes provides program integrity. If anyone were to place a virus in a .class file stored on the base machine, the browser would instantly detect the fact that the file had been edited and would refuse to execute it.

Finally, VM-based executables are much smaller than normal .EXE files. You might have noticed how small the Visual J Plus Plus v6_generated .EXE files are compared to conventional .EXE files such as those generated by Visual C++. This size difference is largely because C++ programs link support functions, such as those that make up the standard C++ library, into the .EXE files. By contrast, Java programs leave the standard Java support classes in the VM environment. All that is contained in the .class file are the instructions the programmer writes. This size difference is important when the .class file is being transmitted through a conventional modem.

The downside of using VM byte codes is that interpreting this virtual language is much slower than executing native code. To address this problem, the Microsoft JIT compiler (which is part of the Java VM) compiles the VM byte codes into 80x86 machine code and then executes the native machine code. Although the JIT compilation process takes a small amount of time, the resulting code is about as fast as a conventional (non-Java) .EXE program. (Refer back to Chapter 1, where we compared the execution speed of a Visual J Plus Plus v6 app to that of a C++ program.)

To further enhance the Visual J Plus Plus v6 experience, Microsoft has placed the VM along with the JIT compiler in the Win32 operating system. This allows Visual J Plus Plus v6_generated .EXE files to use the same JIT compiler that applets use.

Let's use the simple "Hello, world" applet to examine the relationship between an HTML page, an applet, and you—the programmer.

"Hello, world" Applet

Our first applet must be the famous "Hello, world" applet. Not only does convention demand this, but also such a simple applet allows us to concentrate on the details of how applets are loaded and executed rather than on how an applet is coded.

It would be easy enough to build the "Hello, world" example using the Visual J Plus Plus v6 Applet Wizard. In fact, it's a little tricky to convince Visual J Plus Plus not to use the Applet Wizard. However, the applet code the Applet Wizard creates is overkill for an applet as simple as this one. Furthermore, I believe that you should learn to do things manually before using automatic tools. (For example, it's a good idea to learn to multiply by hand before using a calculator.) Without this background, you'll find it difficult to get a feel for what the Applet Wizard is doing for you.

Creating the "Hello, world" project

From the File menu, choose New Project. Select Visual J Plus Plus Projects in the left pane of the New Project window to reveal the single option Empty Project in the right pane. Choose Empty Project.

Create a new subdirectory named Applets under the directory in which you're storing your Visual J Plus Plus programs. Enter this directory into the Location edit box. (If you prefer, you can use the Browse feature.) Finally, enter the project name HelloWorld. When your window looks similar to the one shown in Figure 14-1 (depending on the path to your Applets directory), click Open. You now have a solution with a single empty project.

Java Click to view at full size.

Screenshot-1. Creating an empty project.

Adding an applet to the project

Before we can do anything, we need to add an applet to the project. With the HelloWorld project highlighted in Project Explorer, choose Add Item from the Project menu. From the New tab in the Add Item window, select Class and enter the class name HelloWorld. Visual J Plus Plus v6 adds the file HelloWorld.java, which contains an empty class, to the previously empty project.

Enter the following boldface code into the class you've just created:

import java.applet.Applet;
import java.awt.Graphics;
public class HelloWorld extends Applet
{
 public void paint(Graphics g)
 {
 g.drawString("Hello, world", 10, 10);
 }
}


Let's not analyze the code just yet. We'll wait until you've seen it execute.

Creating the "Hello, world" HTML file

To run our new applet, we'll need an HTML file from which it can run. Select Add Item again. This time, select Web Page. Enter HelloWorld.htm in the Name text box, and click Open.

A new HTML file-specific editor appears. This editor looks a little like the Forms Designer we've used in earlier chapters. Notice the three tabs along the bottom of the editor: Design, Source, and Quick View.

The purpose of the Design tab is roughly the same for HTML files as the Forms Designer's purpose is for WFC-based apps. It allows you to drag tools from the HTML section of the Toolbox onto the HTML page. (The tools in the HTML section are not the Java tools we've used up until now.) As you'll see later, certain aspects of the HTML file limit what the HTML Designer can do.

The Source tab plays the role of the Visual J Plus Plus v6 source code editor. It allows you to examine and edit the HTML source statements. And finally, the Quick View tab allows you to view many (but not all) of the features present in the HTML file without the sometimes tedious process of opening a browser.

Notice that in Design view the HTML page appears to be empty. Select Source view, however, and you'll see a series of HTML tags. These default system-generated tags represent merely the framework of an HTML page and have no displayable content.

CAUTION
If you're running Visual J Plus Plus v6 in SDI mode, you might not see the actual features of the applet displayed in the IDE viewers, especially in the file I/O examples later in this chapter. You might have better luck previewing your applets in MDI mode.

Introduction to HTML

Entire tutorials are devoted to HTML. I couldn't possibly cover the entire topic in just a few lines. Fortunately, we need only a few HTML tags for the applets in this chapter. The initial HTML framework Visual J Plus Plus v6 creates for us looks like this:

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
</HEAD>
<BODY>
<P>&nbsp;</P>
</BODY>
</HTML>


All HTML tags are bracketed using angle brackets (<>). In addition, tags that surround a block of information in the HTML file begin with a tag and end with the same tag preceded by a slash. Thus, the <HTML> tag at the beginning of the HTML file is bracketed with the </HTML> tag at the end. (The HTML tags in this example are all uppercase, but HTML tags are not case sensitive.)

Any HTML file has two main sections: the head and the body. The head includes only a few tags that apply to the entire file. The <TITLE> tag defines the name that appears in the browser's title bar when the page is displayed. The browser ignores the <META> tag, which informs you and any HTML editor you might use how the HTML file was created. (You might see <META> tags with attributes other than the NAME attribute shown in this code, but the browser universally ignores them.)

The display tags begin after the <BODY> tag. The tag <P> introduces a paragraph, <BR> breaks a sentence (like a newline character), and <HR> draws a horizontal line across the page. Any text that appears outside angle brackets is displayed in the browser.

The HTML-interpreting browser treats all white space the same. White space includes a space, tab, vertical tab, and a new line. Specifically, entering a newline character at the end of a series of text doesn't force the start of a new line (as in a simple text editor) or a paragraph (as in Microsoft Word).

The following HTML file generates the results shown in Figure 14-2.

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE>Hello, world</TITLE>
</HEAD>
<BODY>
<HR>
Hello, world
<HR>
</BODY>
</HTML>


Java Click to view at full size.

Screenshot-2. The output from a simple HTML file in the Internet Explorer 4 browser.

In the early years of HTML, the <APPLET> tag was used to include calls to applets in an HTML file. Although the <APPLET> tag is still supported, today the more flexible <OBJECT> tag is the preferred way to include applet calls in an HTML file.

To execute our HelloWorld applet, modify the default HTML framework contained in the HelloWorld.htm file so that it looks like the following:

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE>First Applet</TITLE>
</HEAD>
<BODY>
<HR>
<OBJECT CODE="HelloWorld.class"
 HEIGHT=100
 WIDTH=100>
</OBJECT>
<HR>
</BODY>
</HTML>


This <OBJECT> tag specifies that the applet code resides in the file HelloWorld.class. (The name of the .class file is case sensitive because Java is case sensitive.) The HEIGHT and WIDTH attributes specify the initial size in pixels of the window in which the applet is to appear (normally referred to as the applet window). The </OBJECT> tag closes the applet command. Later in this chapter, we'll see the types of commands that can appear between the <OBJECT> and </OBJECT> tags.

Executing the result

To execute the applet, we first need to set the launch properties. From the Project menu, choose HelloWorld Properties. In the When Project Runs, Load drop-down list, select HelloWorld.htm and choose OK. Now compile the project by selecting the Build option from the Debug menu. Click Start in the Debug menu to run the program. Visual J Plus Plus v6 opens the browser to execute the HelloWorld.htm file. The results are shown in Figure 14-3.

Notice the gray box. This is the 100-by-100-pixel applet window specified within the <OBJECT> tags. The Hello, world message appears at the top of this applet window. In addition, the two horizontal lines specified by the <HR> tags in the HTML file surround the applet window.

Screenshot

Screenshot-3. The HelloWorld applet executing within Internet Explorer 4.

Loading an applet

Let's go through the steps involved in loading and executing the HelloWorld applet. First the browser loads the HelloWorld HTML file. The <OBJECT> tag within the HTML file indicates to the browser that it is to load an executable file. The CODE attribute indicates that the name of the file to load is HelloWorld.class and that it contains VM byte codes. Unless told otherwise, the browser assumes that the .class file is located in the same directory on the same server as the HTML file.

Once the HelloWorld.class file is loaded, the browser begins executing it. In Internet Explorer, the .class file is first compiled using the JIT compiler, and the resulting machine code is executed. Other browsers might take the same approach, or they might simply use an interpreter to execute the byte codes directly.

Because the applet refers to other classes, they are loaded as well. The browser begins by looking through the built-in classes that make up the standard Java library. (In the case of machines executing Microsoft VM for Java, these built-in classes include WFC). For example, the Applet class is always present on the client side. If the browser can't find the class among the built-in classes, it then inspects the cached files. If the browser can't find the class there either, it looks back on the server for the .class file.

An interesting property of applets is that classes, especially user-defined classes, aren't loaded until execution absolutely requires it. This minimizes the amount of information being passed over a potentially slow modem—there's no need to pass the byte codes for a class that is never accessed.

Examining the HelloWorld applet code

Let's examine the HelloWorld applet source code to see how it works. The HelloWorld class extends the Applet class. This base class of all applets provides a number of methods that establish the interface between the Java code and the browser.

One of these interface methods is the method paint(). Java invokes this method whenever the browser signals that the applet window needs to be redrawn.

When the browser first displays the HTML page, the applet window is invalid and requires repainting. The Java core within the browser invokes the paint() method to create the display.

A window can be invalidated in other ways, such as when the user minimizes and then restores the browser. Parts of the applet window might be invalidated even if the user simply scrolls the HTML page.

Our version of paint() prints the "Hello, world" message.

NOTE
The paint() method in applets plays the same role as the paint() method in apps, but with applets the browser (instead of Win32) performs the paint() calls .

See Chapter 9, The Graphics Class, for a discussion of overriding the paint() method in WFC apps.

Examining the Visual J Plus Plus v6 HTML editor

Now that our applet is compiled and working, let's return to the applet editor. In Design mode, select within the two horizontal lines. An applet window containing the "Hello, world" message appears.

Now switch to Source mode. You can see the normal HTML tags, but again the <OBJECT> tag is replaced by the applet output, as shown in Figure 14-4. (You can select View Controls As Text from the View menu to force the source code editor to display the <OBJECT> tag rather than the applet output.)

Finally, the Quick View mode displays the HTML output very much like it would look in an Internet browser.

NOTE
The applet window might initially appear as a blank box. You can make the applet appear in the window by clicking inside this box.

Screenshot

Screenshot-4. The HTML editor showing the applet output in Source mode.

Applet Special Methods

All Java apps share one unique method: public void main(String[]). app execution always begins with this method. In effect, this method forms the handoff link from Win32 into the app. (There are many links from the app back into Win32. For example, all the Visual J Plus Plus v6 methods that perform Win32 API calls must call into Win32.)

Rather than having just a single main() method, applets have numerous methods that the browser can use to hand control to the applet. One example is the paint() method we saw in the HelloWorld applet. Four other methods are key to a browser's communication with an applet.

Special methods

The four methods that have particular importance in the birth and death of an applet are init(), start(), stop(), and destroy(). The following sequence demonstrates how the browser uses these methods:

  1. The browser loads the .class file referenced by the HTML file. The class constructor is invoked immediately after the class is loaded.
  2. The browser lays out the objects defined in the HTML file in the browser. This step includes creating the applet window.
  3. The browser invokes init() to allow the applet to initialize any objects that are to appear in the applet window.
  4. The browser invokes start() immediately prior to displaying the HTML file that contains the applet.
  5. The HTML file is displayed.
  6. The browser invokes stop() immediately after the HTML page that contains the applet is replace by a new HTML page. (Generally, this replacement occurs because the user has navigated to a new HTML page.)
  7. The browser invokes the destroy() method prior to stopping the applet and reclaiming the memory occupied by the applet.

At the time the class constructor is invoked, the browser isn't prepared for the program to display any objects. Our applet performs in the init() method much of the work our WFC apps performed in the class constructor through the call to initForm().

The dichotomy between the init()/destroy() and the start()/stop() methods might not be clear. The browser invokes the init() method followed by the start() method when the HTML page is first displayed. As the user moves to the next HTML page, the browser invokes the stop() method to place the applet in a dormant state; however, the actions taken by the init() method remain valid. The browser can hold off calling destroy() as long as the HTML file is still on the "back" list.

If the user returns to the HTML page containing the HTML file by clicking the browser's "back" button, the browser calls the start() method to "reenergize" the applet. This process saves execution time by avoiding unnecessary calls to the relatively expensive init() method.

NOTE
Although recommended, this sequence is not enforced. Some browsers call destroy() whenever the user leaves the HTML page containing the applet, for whatever reason. These browsers must call init() if the user redisplays the HTML page.

Demonstrating the special methods

The use of the special methods init(), start(), stop(), and destroy() is demonstrated in the following SpecialMethods applet. Let's create an applet in the Applets subdirectory using the same technique described for the HelloWorld applet: create an empty project and then add a class named SpecialMethods and an HTML file named SpecialMethods.htm.

code

Edit the SpecialMethods.java file so that it looks like the following:

import java.applet.Applet;
import java.awt.*;
/**
 * Demonstrate the special methods init(),
 * start(), stop(), and destroy().
 */
public class SpecialMethods extends Applet
{
 // declare a counter for each method
 public static int inits = 0;
 public static int starts = 0;
 public static int stops = 0;
 public static int destroys = 0;
 public static int paints = 0;
 /**
 * Display the number of each event.
 */
 public void paint(Graphics g)
 {
 // count the number of paints
 paints++;
 // get the font height
 FontMetrics fm = g.getFontMetrics();
 int height = fm.getHeight();
 // add a tad to the font height and vertically
 // space each line by that much
 height += 5;
 int yOffset = 0;
 yOffset += height;
 g.drawString("inits = " + inits, 10, yOffset);
 yOffset += height;
 g.drawString("starts = " + starts, 10, yOffset);
 yOffset += height;
 g.drawString("stops = " + stops, 10, yOffset);
 yOffset += height;
 g.drawString("destroys = " + destroys, 10, yOffset);
 yOffset += height;
 g.drawString("paints = " + paints, 10, yOffset);
 }
 /**
 * The following methods increment the respective
 * counters.
 */
 public void init()
 {
 inits++;
 invalidate();
 }
 public void start()
 {
 starts++;
 invalidate();
 }
 public void stop()
 {
 stops++;
 invalidate();
 }
 public void destroy()
 {
 destroys++;
 invalidate();
 }
}


You can see that the four methods at the bottom of the class do nothing more than increment their respective counters and then invalidate the applet window. The paint() method displays all these counters and its own counter.

The paint() method begins by incrementing its counter. The paint() method continues by retrieving the FontMetrics object from the Graphics object g passed to it. This FontMetrics object contains an assortment of information about the current font, including its height, width, style (such as italics), and so forth. The paint() method takes the font height and adds 5 pixels. This resulting height value is used as the interline spacing for each line as paint() goes down the list, outputting each counter. (The 5 pixels are added to provide a certain amount of blank space between lines.)

HTML file

Edit the default SpecialMethods.htm file in Source mode to appear as follows:

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
</HEAD>
<BODY>
<P>
<OBJECT CODE = "SpecialMethods.class"
 HEIGHT = 150
 Width = 100>
</OBJECT>
</P>
</BODY>
</HTML>


result

Compile the project, and then view the SpecialMethods.htm file in Internet Explorer 4 or some other browser. The inits, starts, and paints counters are initially displayed as 1, and the stops and destroys counters appear as 0.

You'll find it encouraging that the paint count displays a value of 1 under Internet Explorer 4. This implies that the applet was painted only a single time during the display of the HTML page. Even as you resize the browser, the paints counter value stays at 1, until you resize the browser to the point that the applet window is partially obscured, at which time the paints counter value begins to increase. As soon as you stop resizing, the paints counter immediately stops updating. Throughout the entire resizing exercise, the inits, starts, stops, and destroys counters remain at their initial values.

Navigate to another page and return to the SpecialMethods page using the browser's back button. Figure 14-5 shows the resulting display.

As you can see from the counters, Internet Explorer 4 destroys the applet whenever the user jumps to another page and then restarts the applet when the user returns.

Java Click to view at full size.

Screenshot-5. The SpecialMethods applet displaying the number of times that each special method has been invoked.

Displaying Abstract Windowing Toolkit Objects

In Chapter 4, Generic Windowed apps, you saw how windowed apps can use the machine-independent Abstract Windowing Toolkit (AWT). AWT is also available for applet use. In fact, you might argue that AWT was designed specifically for applets to use. The classes that make up AWT are already present in every Java-enabled browser.

Applets and WFC

Under normal circumstances, you shouldn't access WFC from applets. WFC is not part of the standard Java library that is accessible to all browsers; WFC is accessible only to Internet Explorer version 4 or higher. Thus, if your applet refers to a WFC class, the browser will be forced to load large sections of the WFC library over the Internet (assuming that you placed the WFC classes in a directory on the server where the browser could find them). The time required to perform such a download would be unacceptable to the user.

Internet Explorer 4 does have access to the WFC classes. Thus, if you have complete control of the user community, such as would be the case in a small intranet community, restricting all users to a single version of a single browser might be acceptable. From my experience on the intranet of even a medium-sized company, however, this restriction is impractical.

AWT use in applets isn't that much different from AWT use in apps. The following AWTApplet applet demonstrates the principle. This applet opens two labeled text fields, one above the other. Below the text fields is a button the user can click to transfer the contents of the upper text field to the lower text field. (For now, the button does nothing; we'll add functionality to it in the next section).

code

To create the AWTApplet applet, you begin by creating an empty project named AWTApplet1. (We'll add more features to later versions.) Add a class named AWTApplet and an HTML file named AWTApplet.htm. Update the AWTApplet.java source file as follows:

import java.applet.Applet;
import java.awt.*;
public class AWTApplet extends Applet
{
 TextField tfSource = new TextField();
 TextField tfTarget = new TextField();
 Button button = new Button("Transfer");
 public void init()
 {
 // create two text field panels
 Panel sPanel = createTextFieldPanel(
 "Source",
 tfSource);
 Panel tPanel = createTextFieldPanel(
 "Target",
 tfTarget);
 // and a button panel
 Panel bPanel = createButtonPanel(button);
 // set them in a single-column grid layout
 // (this will lay them out vertically)
 GridLayout gridLayout = new GridLayout();
 gridLayout.setColumns(1);
 gridLayout.setRows(0);
 gridLayout.setVgap(10);
 this.setLayout(gridLayout);
 this.add(sPanel);
 this.add(tPanel);
 this.add(bPanel);
 }
 /**
 * Create a panel with a label and a text field
 * offset from the left and right boundaries.
 */
 Panel createTextFieldPanel(String label, TextField t)
 {
 Panel panel = new Panel();
 panel.setLayout(new BorderLayout());
 Panel subPanel = new Panel();
 subPanel.setLayout(new BorderLayout());
 subPanel.add("North", new Label(label));
 subPanel.add("South", t);
 panel.add("West", new Label(" "));
 panel.add("East", new Label(" "));
 panel.add("Center", subPanel);
 return panel;
 }
 /**
 * Create a panel with a single button in the
 * center.
 */
 Panel createButtonPanel(Button button)
 {
 // establish a 3x3 grid layout
 // (the following is crude, but it does the
 // job without resorting to the more complicated
 // GridBagLayout)
 Panel panel = new Panel();
 panel.setLayout(new GridLayout(3, 3));
 // fill the first row with blanks
 panel.add(new Label(" "));
 panel.add(new Label(" "));
 panel.add(new Label(" "));
 // on the second row, put the button in the center
 panel.add(new Label(" "));
 panel.add(button);
 panel.add(new Label(" "));
 // fill the third row with blanks
 panel.add(new Label(" "));
 panel.add(new Label(" "));
 panel.add(new Label(" "));
 return panel;
 }
}


The code for this applet looks a lot more complicated than it really is. (This seeming complexity is typical of AWT applets.) The init() method begins by creating a panel containing the source TextField object and an identical panel containing the target TextField object. We'll eventually copy the contents of the source field to the target field. Finally, the applet creates a panel containing the Transfer button.

The init() method uses a GridLayout layout manager to create the display. The purpose of this layout manager is to create spreadsheet-like grids with columns of equal width and rows of equal height. The init() method of our AWTApplet applet specifies a single column, and as many rows as are required (designated by the setRows(0) command.). Creating a grid with only a single column creates what is essentially a vertical layout.

The AWTApplet.createTextFieldPanel() method is perhaps the most complicated of the methods in this class. This method creates an inner panel (subpanel) in which it places the label and the TextField object. The method then places this inner panel in the center of an outer panel (panel) that contains an empty label on the left and another label on the right. These empty labels place a small space on the left and right between the applet boundary and the label/text field panel.

The AWTApplet.createButtonPanel() method is crude but effective. This method creates a 3-by-3 grid layout and places the button in the middle. This placement gives the button a pleasing appearance with suitable space around it in the applet window.

HTML file

The HTML file for AWTApplet has the standard features you've seen in other applets:

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
</HEAD>
<BODY>
<P>
<OBJECT CODE = "AWTApplet.class"
 HEIGHT = 200
 WIDTH = 300>
</OBJECT> </P>
</BODY>
</HTML>


result

When viewed from the Designer after compiling, the Source window appears as shown in Figure 14-6.

Java Click to view at full size.

Screenshot-6. The appearance of the Designer's Source window when viewing AWTApplet.

Handling Events

Our AWTApplet applet is fine so far, but is somewhat unimpressive because the Transfer button doesn't do anything. To activate the Transfer button, we must add an event handler, which is what we'll do for the AWTApplet2 project.

code

The code for the event-capable version of the AWTApplet applet is shown below. The majority of the code in this version is the same as that in its predecessor and isn't shown here.

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class AWTApplet extends Applet
{
 TextField tfSource = new TextField();
 TextField tfTarget = new TextField();
 Button button = new Button("Transfer");
 public void init()
 {
 // …the same as previous version…
 // add the transfer button event code
 addTransfer();
 }
 .
 .
 .
 /**
 * Add the transfer capability to the specified event.
 */
 void addTransfer()
 {
 // make the target field read-only
 tfTarget.setEditable(false);
 // now add a transfer action listener to perform
 // the transfer button.addActionListener(new TransferActionListener());
 }
 /**
 * Implement the ActionListener interface.
 */
 class TransferActionListener implements ActionListener
 {
 /**
 * Transfer text from the source text field to
 * the target text field.
 */
 public void actionPerformed(ActionEvent ae)
 {
 String s = tfSource.getText();
 tfTarget.setText(s);
 }
 }
}


The call to AWTApplet.addTransfer() in init() activates the transfer button. The addTransfer() method begins by making the target text field read-only. The method then adds an ActionListener interface to the transfer button. An ActionEvent object is created when the user clicks the button. The ActionListener interface plus the ActionEvent are defined in the java.awt.event package.

The inner class TransferActionListener implements the ActionListener interface by providing an actionPerformed() method. This method reads the text out of the source text field and stores it into the target text field.

result

The AWTApplet2 project uses the same HTML as AWTApplet1. Figure 14-7 shows AWTApplet when viewed from the Quick View mode of the Applet HTML editor. To create this display, I entered text into the source text field and clicked the Transfer button to copy the contents of the source text field to the target text field.

Screenshot

Screenshot-7. The results of the event-capable AWTApplet.

Listeners

The ActionListener approach is a means of event handling we discussed briefly in Chapter 5, Microsoft Windows apps. WFC prefers the easier-to-use delegate approach. However, AWT uses the listener approach introduced in Java 1.1.

In the listener approach, for every action that can befall an AWT control, there is a method with the following syntax:

<control>.add<X>Listener(my<X>Listener)


X represents the name of some action type, and my<X>Listener represents an object of some locally defined class My<X>Listener, which implements the <X>Listener interface. An <X>Listener interface generally defines a single method of the form public void <X>Performed(<X>Event). The most common value of <X> is Action, which is demonstrated in the AWTApplet2 code statement shown here:

button.addActionListener(new TransferActionListener());


The action events are loosely defined as what the control receives when the user activates the control. Thus, the action event for a button is invoked when the user clicks the button.

This approach to event handling is powerful and flexible. The primary disadvantage of this approach compared with the delegate approach is the need to implement a separate class for each event handled. (Refer to for more on delegates.)

Passing Arguments to the Applet

As you saw in Part II, you can pass information to apps in several ways. The most straightforward way is through the array of strings passed to main() via the command line. An applet has no command line. However, you can pass arguments to the applet from the HTML file via the HTML <PARAM> tag. The <PARAM> tag defines a parameter by name and assigns it a string value. The applet can query this parameter by its name to read the value.

To demonstrate the use of the <PARAM> tag, the following ParamDisplay applet displays the name the HTML file passes to it in the TEXT parameter in the font and point size specified in the FONT and SIZE parameters.

code

The key to this applet—and any other applet that reads parameter data from the HTML file—is the getParameter(String name) method. This method accepts the name of the parameter and returns the corresponding value as a String.

If the parameter with the name passed to getParameter() isn't in the HTML file, the method returns null. Because the applet programmer generally has no control over the HTML files that call the applet, the applet must account for the fact that any given parameter might not be present in the HTML file. If a specific parameter is missing from the HTML file, the applet must assign a default value.

The following ParamDisplay applet demonstrates how this works:

import java.applet.Applet;
import java.awt.*;
public class ParamDisplay extends Applet
{
 // define the names of the parameters
 String textName = "TEXT";
 String fontName = "FONT";
 String sizeName = "SIZE";
 // define the default values for each
 String textDefault = "No text";
 String fontDefault = "Courier";
 int sizeDefault = 12;
 // now declare the actual values
 String text;
 String font;
 int size;
 // resulting font
 Font f;
 public void init()
 {
 // get the text to display
 text = this.getParameter(textName);
 if (text == null)
 {
 text = textDefault;
 }
 // next the font
 font = this.getParameter(fontName);
 if (font == null)
 {
 font = fontDefault;
 }
 // finally the size, which must be converted
 // from string to integer
 String sSize;
 sSize = this.getParameter(sizeName);
 size = sizeDefault;
 if (sSize != null)
 {
 size = Integer.parseInt(sSize);
 }
 // create a font using those parameters
 Font f = new Font(font, Font.PLAIN,size);
 }
 /**
 * Paint the text specified in the HTML
 * file with the specified font and size.
 */
 public void paint(Graphics g)
 {
 if (f != null)
 {
 g.setFont(f);
 }
 int yOffset = size + 10;
 g.drawString(text, 10, yOffset);
 }
}


If we take the TEXT parameter as an example, the textName variable is assigned the value TEXT. A default value for this parameter is provided in the string textDefault. The resulting string is stored in text.

As the applet starts, the browser invokes init(). This method calls getParameter() to retrieve the value of the parameter named textName and stores the result in text. If the value returned by getParameter() is null, init() assigns text the default value stored in textDefault.

This pattern is repeated for each parameter. The only complication is that the font size must be converted from a string into an integer using the static method Integer.parseInt().

Once init() has read all the HTML parameters, it creates a Font object using the values in the font and size variables. The paint() method uses this Font object to format the string passed in the text parameter when the string is displayed.

HTML file

To test ParamDisplay, create the following HTML file:

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
</HEAD>
<BODY>
<P>
<OBJECT CODE = "ParamDisplay.class"
 HEIGHT = 100
 WIDTH = 400>
<param name = "TEXT" value = "This is the text param">
<param name = "SIZE" value = "28">
</OBJECT>
</P>
</BODY>
</HTML>


Most of the HTML file is identical to previous versions. The <OBJECT> tag differs in this HTML file, however, with the addition of the <PARAM> tag for TEXT and SIZE. Notice the absence of the FONT parameter.

result

The output from ParamDisplay using the previous HTML file appears in Figure 14-8. Here the string size and font size specified in the HTML file are combined with the default font type of COURIER to create the applet display shown.

Java Click to view at full size.

Screenshot-8. The output from the ParamDisplay applet using specified TEXT and SIZE parameters but default FONT. Comments