TOC
BACK
FORWARD
HOME

Java 1.1 Unleashed

- 8 -
Introduction to Applet Programming

by Rick Darnell

IN THIS CHAPTER

  • Providing Security
  • Understanding the Basics of Applet Programming
  • Viewing Applets
  • An Example: The ColorCyle Applet
  • Working with the Java AWT
  • Event Handling

Although Java is a general-purpose programming language suitable for a large variety of tasks, the task most people use it for is applet programming. An applet is a Java program that can operate only within a compatible Web browser, such as Netscape Navigator or Microsoft Internet Explorer.

Your first experience with Java may have been one of the demonstration applets released in 1995 with the first Java Development Kit--spinning heads, an animated "Duke" cartoon doing cartwheels, and so on. Today, applets are used to accomplish far more than demonstrative goals. Current uses of applets include these:

  • Tickertape-style news and sports headline updates

  • Animated graphics

  • Video games

  • Student tests

  • Imagemaps that respond to mouse movement

  • Advanced text displays

  • Database reports

For example, the Instant Ballpark applet from Instant Sports (http://www.instantsports.com/ballpark.html) takes real-time data from live baseball games and updates its graphical display to reflect what's happening in the game. Players run the bases, the ball goes to the place it was hit, and sound effects are used for strike calls, crowd noise, and other elements. The program, which was unique enough to qualify for a U.S. patent, is reminiscent of the old-time baseball tradition of presenting the play-by-play for road games by moving metal figures on the side of a building. In addition to the live coverage, Instant Ballpark can be used to review the play-by-play action of past games.

With HTML and some kind of gateway programming language such as Perl, a Web page can offer textual updates to a game in progress. In addition to the text, Instant Ballpark offers a visual presentation of a live game and can respond immediately to user input. This interactive nature of Java is used to provide information to Web users in a more compelling way, which is often the reason site providers offer applets.

With Microsoft's and Apple's encouragement of windowing software in the past five years, users now expect software to make use of graphical window features like buttons and scrollbars. In Java, windows and other graphical user interface functions are handled by the Abstract Windowing Toolkit (AWT).

The AWT is one of the most useful packages included with the Java API, but it is also one of the hardest to become familiar with. The AWT is a set of classes used to build graphical user interfaces for Java applications and applets. It enables programmers to easily create the following features for programs:

  • Windows and dialog boxes

  • Pull-down menus

  • Buttons, labels, checkboxes, and other simple user interface components

  • Text areas, scrollbars, and other more sophisticated user interface components

  • Layout managers to control the placement of user interface components

The AWT also includes classes to handle graphics, fonts, and color, plus an Event class to enable programs to respond to mouse clicks, mouse movements, and keyboard input.

In the early days of Java, the Java Developer's Kit (JDK) and a text editor was the only choice available to programmers for developing applets and applications. Today, there are numerous ways to develop programs with Java, including SunSoft Java WorkShop, Symantec Café and Visual Café, and Rogue Wave JFactory. Java WorkShop, Café, and Visual Café include tools for drag-and-drop development of windows, dialog boxes, and other elements common to windowing systems. JFactory is an interface builder that can be used with different Java programming environments.

Providing Security

Java applets are programs that run on a Web user's machine. As you know, anything that can execute code is a potential security risk because of the damaging things that can occur. Viruses can damage a computer's file system and reproduce onto other disks, Trojan horses can masquerade as helpful programs while doing harmful things, and programs can be written to retrieve private information surreptitiously. Even Microsoft applications such as Word and Access have security risks because of Visual Basic for Applications--an executable programming language that can be used in conjunction with application documents.

Security is one of the primary concerns of Java's developers, and they have implemented safeguards at several levels. Some of these safeguards affect the language as a whole: removal of pointers, verification of bytecodes, and restricted remote and local file access. This means that some of Java's functionality is blocked for applets because of security concerns.

  • Applets cannot read or write files on the Web user's disk. If information must be saved to disk as an applet is executing (as in the case of a video game saving the top 10 scores), the storage of information must be done on the disk from which the Web page is served.

  • Applets cannot make a network connection to a computer other than the one from which the Web page is served, except to direct the browser to a new location.

n Popup windows opened by applets are identified clearly as Java windows. A Java cup icon and text such as Untrusted Applet Window appear in the window's border to prevent a window opened by Java from pretending to be something else, such as a Windows dialog box requesting a user's name and password.

  • Applets cannot use dynamic or shared libraries from any other programming language. Although Java applications can use programs written in languages such as Visual C++, applets cannot make use of this feature because there's no way to adequately verify the security of the nonJava code.

  • Applets cannot run any programs on the Web user's system, including browser plug-ins, ActiveX controls, or other browser-related items.

These restrictions limit Java applets more than standalone Java applications. The loss is a tradeoff for the security that must be in place for the language to run remotely on users' computers. Refer to Chapter 34, "Java Security," for more information about security and Java.

Understanding the Basics of Applet Programming

Now that you understand what applets are, it's time to get out some power tools and see what it takes to put one together. We'll begin with a quick introduction to some basic elements of applet programming.

Each applet starts out with a class definition, like this:

public class LearnPigLatin extends java.applet.Applet {
    // to do
}

In this example, LearnPigLatin is the name of the applet's class. An applet must be declared as a public class. All applets extend the java.applet.Applet class, also referred to simply as the Applet class. Another way to write the class definition is to use import to load the Applet class and simplify the declaration:

import java.applet.Applet
public class LearnPigLatin extends Applet {
    // to do
}

NOTE: Applet extends the java.awt.Panel class, which is a Java container. This evolution enables an applet to hold a physical place on the Web page within the browser's window. For more information, see "Containers: A Place for Your Components," later in this chapter.

The superclasses of Applet give all applets a framework on which you can build user interface elements and mouse events. These superclasses also provide a structure for the applet that must be used when the program is developed.

Applet Methods

The structure of an applet takes its form from four events that take place during the life of an applet. When each stage is reached, a method is automatically called. There are default versions of each of the methods if you choose not to override them:

  • init(): This is the initialization method used to set the stage for the applet's activity; the method usually includes things such as loading graphics, initializing variables, and creating objects.

  • start(): Starting the applet's execution is next on the agenda. This method is where the meat and potatoes of the applet are found. The start() method is the body of the applet; this method is also used to restart the applet after it has stopped.

  • stop(): Stopping an applet interrupts its execution but leaves its resources intact so that it can start again. You should always stop an applet before you destroy it; you can also use the stop() method to stop applet execution when a pause in the flow is needed.

  • destroy(): When an applet is destroyed, all its resources--memory, processor time, swap disk space--are cleared and returned to the system. This method is the last thing that happens when the user leaves the page containing the applet.

Applets and Applications

This chapter focuses on applets, but it's important to make clear the distinction between the two types of Java programs. Applets are programs offered on Web pages that require the use of a Web browser to execute. Applications are everything else: general-purpose programs run by executing the Java interpreter with the name of the Java program as an argument. For example, to run the Java program ReadNews.class, enter the following at a command-line prompt:

java ReadNews

Applications do not have many of the restrictions that are in place for applets, although features such as bytecode verification are still implemented.

Many programmers are initially confused by the lack of a main() method to start applet operation. Understand that the browser provides all the necessary support and responsibility for running the applet. In other words, the browser is the main() method, and the applet is a subroutine running within its context.

For more information on techniques for working with Java programs, see Part VI of this book, "Programming Strategies."

Other important methods--although not directly required for program execution--are paint() and repaint(). These methods apply only to the display in the applet window and occur automatically at certain times, such as when the applet window is redisplayed after being covered or when the applet window is resized. An applet can call repaint() directly to update the window whenever necessary.

Of all the methods, repaint() is the only one that requires a parameter. This parameter is an instance of the Graphics class, as in the following method definition:

public void paint(Graphics g) {
    g.drawString("One moment, please", 5, 50);

}

The Graphics object used as the parameter represents the applet window. The g.drawString() line uses this Graphics object to indicate where a string should be drawn. Every time the repaint() method is called, the applet window is updated with the string One moment, please drawn at the x, y position 5, 50.

Each of these applet methods--init(), destroy(), start(), stop(), and paint()--is inherited by an applet. However, each of the applet methods is empty by default. If something specific is supposed to happen in an applet, some or all of these methods must be overridden. Although you do not have to override any of these methods, as a general rule, you always provide your own start() method.

Viewing Applets

Applets are displayed as a part of a Web page by using the HTML tag <APPLET>. To run an applet, you need a Web browser or some other software that serves the function of a browser, such as the applet viewer program that ships with the Java Development Kit from JavaSoft.

The browser acts as the operating system for the applet--you cannot run an applet as a standalone program in the same way you can run an executable file. The two leading browsers--Netscape Navigator (version 2.02 and later) and Microsoft Internet Explorer (version 3.0 and later)--both support Java applets. A third choice--Sun's HotJava--also handles applets but is not widely used.

These programs load applets from a Web page and run them remotely on the Web user's computer. This arrangement raises security issues that must be handled by the Java language itself and by Java-enabled browsers.

The <APPLET> Tag

Running Java applets on a Web page requires the use of two special HTML tags: <APPLET> and <PARAM>. These tags are included on a Web page along with all other HTML code. In this respect, inserting a Java applet on your Web page is no different than inserting a picture, as the following lines demonstrate:

<APPLET CODE="NowShowing.class" CODEBASE="progdir" WIDTH=376 HEIGHT=104>
<PARAM NAME="speed" value="100">
<PARAM NAME="blink" value="5">
<PARAM NAME="text" value="FREE THE BOUND PERIODICALS!">
<PARAM NAME="fontsize" value="21">
<PARAM NAME="pattern" value="random">
<H5>This applet requires the use of a Java-enabled browser!</H5>
</APPLET>

When included on a Web page, this HTML code causes the following to take place on a Java-enabled browser:

1. An applet called NowShowing.class is loaded from a directory called progdir. The CODE attribute specifies the applet's filename, and the optional CODEBASE attribute refers to a directory where the applet is found.

If the CODEBASE attribute is used without a leading slash (/), it indicates the path from the Web page's directory to the directory containing the applet's class file. For example, CODEBASE="usr" indicates that the applet is in a directory called usr that is a subdirectory of the Web page's directory. CODEBASE can also specify a complete path on the Web site separate from the page's current location.

2. The applet is set to a width of 376 pixels and a height of 104 pixels using the WIDTH and HEIGHT attributes. These attributes work the same with <APPLET> as they do with <IMG>.

The ALIGN attribute used with images also can be used with <APPLET>. The ALIGN attribute determines how the applet is positioned in relation to the other parts of the Web page; it can have the value TOP, MIDDLE, or BOTTOM.

3. A parameter named speed is sent to the applet with a value of 100. Four other parameters are sent to the applet: blink, text, fontsize, and pattern. Parameters are optional; you can include as many as you want. The NAME attribute indicates the name a parameter should be given; the VALUE attribute indicates the value to associate with the parameter.


Why Pass Numbers as Strings?

All parameters passed from an HTML page to an applet are passed as strings, no matter what the parameter is or how it's formatted on the page. Any conversion to other types (such as integer, boolean, or date) must happen within the applet itself.

For example, <PARAM NAME="speed" value=100> and <PARAM NAME="speed" value="100"> both pass the string "100" to the applet. This restriction eliminates a lot of guesswork between the browser and the applet because neither has to guess what kind of value is being sent. Everything is converted to a string, and the programmer can take care of casting the value to a new type after it enters the applet.


4. The line <H5>This applet requires a Java-enabled browser!</H5> is ignored unless the page is loaded by a nonJava browser. An incompatible browser won't recognize the two <APPLET> tags and ignores each line until it reaches the line with the <H5> heading tag. Because the browser knows what to do with this tag, it displays the appropriate text.


TIP: You can insert any standard HTML code before the closing </APPLET> tag. Many page designers include an image or similar item that occupies the same amount of space as the applet. This arrangement helps maintain consistent page layout regardless of the browser being used.

If the applet makes use of class files that are not part of the standard Java API, these class files must be located in the same directory as the applet's class file.

Putting the Applet on the Web

It's easy to make your applet available on the Web after it's created and placed on an HTML page using the <APPLET></APPLET> tags. Put all .class files required by the applet on your Web site, making sure that you put the files in the directory specified by the CODEBASE attribute (if this attribute has been used). If the CODEBASE attribute has not been used, put the .class files in the same directory as the Web page that includes the applet.

That's all it takes. Unlike CGI programming (which requires special access to the computer providing the Web pages), Java applets can be added by anyone who can put pages on a Web site.

More about Using Parameters

As you saw earlier, parameters are sent to an applet using the <PARAM> tag and its attributes of NAME and VALUE. For example, <PARAM NAME="blink" VALUE="100"> sends a parameter named blink with a value of 100 to the applet.


TIP: Unlike everything else relating to Java, the parameter name is not case sensitive. You can send a rose, a Rose, or a ROSE to the applet, and they'll all smell the same.

Parameters are passed to the applet after it's loaded; all parameters are sent as strings whether or not they are encased in quotation marks. All parameters are converted to other data types within the applet. For an applet to use a parameter, the applet must retrieve the parameter using the getParameter() method, which is usually used within the init() portion of applet execution.

For example, use the following line in a Java applet to store the blink parameter in a variable called blinkValue:

String blinkValue = getParameter("blink");

If you want to retrieve the value and convert it to an integer, use the following code:

int blinkValue = -1;
try { blinkValue = Integer.parseInt(getParameter("blink")); }
catch (NumberFormatException e) { }

This example uses the parseInt() method of the java.lang.Integer class to convert a String to an int. The try and catch block is used to trap errors if the String cannot be converted to a number.

An Example: The ColorCycle Applet

In subsequent chapters, you delve into the specific details of programming, including user interface design and event handling. For now, it is worthwhile to take a look at a working example of an applet to get a clearer picture of how applets are constructed.

ColorCycle is a simple applet with one button labeled Next Color. When you click this button with the mouse, the background color of the applet changes. The program demonstrates basic applet structure and a simple bit of event handling. The source code for this applet is shown in Listing 8.1 and can be found on the CD-ROM that accompanies this book.

Listing 8.1. The source code for ColorCycle.java.

1: import java.awt.*;
2:
3: public class ColorCycle extends java.applet.Applet {
4:     float hue = (float).5;
5:     float saturation = (float)1;
6:     float brightness = (float)0;
7:     Button b;
8:
9:     public void init() {
10:         b = new Button("Next Color");
11:         add(b);
12:     }
13:
14:     public void start() {
15:         setBackground(Color.black);
16:         repaint();
17:     }
18:
19:     public boolean action(Event evt, Object o) {
20:         if (brightness < 1)
21:             brightness += .25;
22:         else
23:             brightness = 0;
24:         Color c = new Color(Color.HSBtoRGB(hue, saturation, brightness));
25:         setBackground(c);
26:         repaint();
27:         return true;
28:     }
29: }

Don't worry if some aspects of this program are unfamiliar to you at this point. Several aspects of this applet are discussed later in this chapter, including the creation of user interface components such as buttons and the action() method.

The following things are taking place in the applet:

  • Line 1: The applet imports several classes by using the wildcard character with java.awt.*. The awt stands for Abstract Windowing Toolkit and is a set of classes that handle most visual and interactive aspects of Java programming--graphics, fonts, and keyboard and mouse input.

  • Lines 4 through 6: Three instance variables are created to store the HSB values of the color being displayed. HSB (Hue, Saturation, and Brightness) is a method of describing a color as three numeric values from 0 to 1.

  • Line 7: A Button object is created.

  • Lines 9 through 12: The applet's init() method is called automatically when the applet is first run; this method provides instantiation for Button object b with the label Next Color.

  • Lines 14 through 17: The start() method sets the background color of the applet to black using a constant of the Color class (Color.black). In addition, the repaint() method is called to redraw the applet window because something--the background color--has changed and we want to display that change.

  • Line 19: The action() method is called whenever a user interface component generates an action event. In this applet, an event occurs when the button is clicked. For more information on event handling, see Chapter 7, "Exception Handling," and Chapter 22, "Creating User Interface Components."

  • Lines 20 through 23: The value of brightness is changed to cycle the background color through several shades from black to light blue.

  • Lines 24 through 26: A Color object is created to store the value of the background color, which is created based on the values of the variables hue, saturation, and brightness. The new background color is reflected with another call to repaint().

  • Line 27: The boolean value true is returned at the end of the action() method, indicating that the action event generated by clicking the button was handled.

Notice that there are no stop() or destroy() methods defined in this applet because we have no need to override either one of these method's activities. When the user moves to a different Web page or otherwise dumps this applet page from the viewer, the applet will stop and its resources will be recovered.

Designing the HTML Page for ColorCycle

Once the ColorCycle applet has been written and compiled using your development software, you can put it on a Web page using the HTML tags <APPLET>, </APPLET>, and <PARAM>, described earlier in this chapter.

Listing 8.2 shows the full text of an HTML page that loads the ColorCycle.class applet. (This code can also be found on the CD-ROM that accompanies this book.) Because the CODEBASE attribute is not used with the <APPLET> tag, the .class file must be placed in the same directory as the Web page containing the applet.

Listing 8.2. The source code for ColorCycle.html.

1: <html>
2: <body>
3: <applet code=ColorCycle.class height=250 width=250>
4: </applet>
5: </body>
6: </html>

Although the applet loses something in the translation from color to black and white, Fig- ure 8.1 shows how the ColorCycle applet looks when viewed with the applet viewer provided with the Java Development Kit from Sun.

Figure 8.1.

The ColorCycle applet consists of a square frame whose background color changes when the Next Color button is clicked.

Making ColorCycle an Application

To underscore the difference between applets and applications, let's now turn the ColorCycle applet into an application that can run independently of a browser (see Listing 8.3 and the code on the CD-ROM). Remember that the application must provide the basic framework normally supplied for the applet by the browser, and must also invoke each of the applet methods in turn.

Listing 8.3. The source code for the ColorCycleApplication.java application.

1:  import java.applet.Applet;
2:  import java.awt.*;
3:
4:  public class ColorCycleApplication extends Applet {
5:     float hue = (float).5;
6:     float saturation = (float)1;
7:     float brightness = (float)0;
8:     Panel p;
9:     Button b;
10:
11:    public static void main(String args[]) {
12:         ColorCycleFrame app = new ColorCycleFrame("ColorCycle Application Window");
13:         app.resize(200,200);
14:         app.show();
15:         app.applet.start();
16:    }
17:
18:    public void init() {
19:         b = new Button("Next Color");
20:         add(b);
21:    }
22:
23:    public void start() {
24:         setBackground(Color.black);
25:         repaint();
26:    }
27:
28:    public boolean action(Event event, Object obj) {
29:         if (brightness < 1)
30:             brightness += .25;
31:         else
32:             brightness = 0;
33:         Color c = new Color(Color.HSBtoRGB(hue, saturation, brightness));
34:         setBackground(c);
35:         repaint();
36:         return true;
37:    }
38: }
39:
40: class ColorCycleFrame extends Frame {
41:    ColorCycleApplication applet;
42:
33:    public ColorCycleFrame(String frameName) {
44:         super(frameName);
45:         applet = new ColorCycleApplication();
46:         add("Center",applet);
47:         applet.init();
48:    }
49:
50:    public boolean handleEvent(Event event) {
51:         if(event.id == Event.WINDOW_DESTROY) {
52:              applet.stop();
53:              applet.destroy();
54:              System.exit(0); }
55:         return false;
56:    }

57: }

An extra class and method are added to the ColorCycle applet so that the necessary overhead normally provided by the browser is now supplied by the application itself. This allows the same piece of code to run as an applet or an application (see Figure 8.2).

Figure 8.2.

The ColorCycle applet transformed into a standalone application.

In Listing 8.3, the application begins by importing the classes needed to support both types of operation (lines 1 and 2). The imported classes include the Applet class for the applet and the awt.Frame class for the application.


TIP: Because the Frame class is a part of the AWT, it's easier to import it along with the rest of the AWT classes by using the import java.awt.* statement. You should use this approach (instead of a long list of import statements for each individual item needed) when more than two or three subclasses are used within a program. This results in cleaner code and fewer opportunities for typing mistakes when the code is compiled.

The next step is ensuring that the code can run on a browser: in line 4, the ColorCycleApplication class extends the Applet class. Then the main() method required by an application is placed as the first method within the class. This method creates and displays a frame to hold the program (line 11), which in turn starts the body of the program. If the program is run as an applet, main() is never used and the browser begins with the init() method. If the class runs as an application, the main() method is executed first, which creates a frame to hold the applet functions using the ColorCycleFrame class. After the frame is created, the applet is centered within it.

Remember that a browser normally supplies all the overhead required by an applet; the browser also is responsible for calling each of the four required methods in turn--init(), start(), stop(), and destroy(). However, when the program runs as an application, we must replace this overhead because the browser is not available. These details are handled primarily by the ColorCycleApplication.main() method and the ColorCycleFrame class. Let's look closer at the ColorCycleFrame class.

When an applet runs on a browser, the browser provides a frame for it to reside in. Because the application is not a browser, it doesn't know about this requirement, so the ColorCycleFrame class provides the first bit of necessary overhead. Next, the program has to provide an instance of the application class to use as an applet (line 41). Lines 33 through 46 actually create the physical frame and add an instance of ColorCycleApplication within it. The first method of the applet, init(), is called to prepare the applet for operation.

After the frame and applet are instantiated, control is passed back to the main() method. Lines 13 and 14 set the initial size of the window and force its display on the screen. The main method of the applet, start(), is then called. At this point, the program performs its tricks and functions until the user closes the window.

Any action concerning the frame triggers an event. An event can be moving the mouse into or out of the frame, resizing the frame, or minimizing or maximizing the frame. Each event is handled using ColorCycleFrame.handleEvent() on line 50. Line 51 looks at the event to see whether the user has closed the window. If the window has been closed, the last two applet methods, stop() and destroy(), are called to close program operation and shut down the Java system.


NOTE: You may have noticed that the stop() and destroy() methods are called but not explicitly defined in the ColorCycleApplication class. This is because the Applet class includes default definitions for these two methods. If one of these methods is not included as part of a user-defined class, the Java system automatically invokes the default Applet version.

By adding the frame class and an extra bit of code to virtually any applet, you enable the applet to run on machines that don't have a compatible browser but that do have a Java virtual machine.

Working with the Java AWT

Now that you understand the basic framework in which you develop an applet, it's time to take a closer look at the Abstract Windowing Toolkit (AWT). The AWT is used to build the graphical user interface with standard windowing elements. Each window element is represented by its own component. There are components for buttons you can click, components for text fields you can type into, and components for scrollbars you can control. There also are components for some things you cannot directly manipulate, such as labels.

For more information about the other capabilities and classes within the AWT, see Part IV of this book, "Programming the AWT."

Containers: A Place for Your Components

To use AWT components in a program, you must contain them. After all, buttons floating freely in the computer don't do anyone any good. A Java container is a blank slate that holds the interface components. All containers in Java are subclasses of the Container class.

There are two basic types of containers:

  • The Window class: This class creates popup windows separate from the main program. There are two subclasses of Window: Frame (windows that have a border and a menu bar) and Dialog (a special window used in applications to select a file).

  • The Panel class: A container that represents a section of an existing window. The Applet class is a container that is a subclass of the Panel class. You can place components directly on an applet panel or use additional Panel objects to subdivide the applet into smaller sections.

A Panel container is not visible when it is added to an applet. Its purpose is to provide a way to organize components as they're laid out in a window.

Listing 8.4 is the source code for an applet that has a new Panel added to its surface. The applet is also located on the CD-ROM that accompanies this book. This code does not produce any output other than a blank window. However, it is useful as a template for the components you will learn to add throughout this chapter.

Listing 8.4. The source code for ContainerAndPanel.java.

1: import java.applet.Applet;
2: import java.awt.*;
3: public class ContainerAndPanel extends Applet {
4:     Panel p = new Panel();
5:
6:     public void init() {
7:         add(p);
8:     }

9: }

The statement that puts the instance of panel p in the applet window is add(p) (line 7). The add() method is used whenever a component of any kind is added to a container.


TIP: You can use this source code to test each component by replacing Panel p = new Panel() with declarations for components you need and by updating the line add(p).

By default, components are added to a container in left-to-right, top-to-bottom order. If a component does not fit on a line, it is placed at the leftmost edge of the next line. In addition, there are several layout managers that offer greater control of component placement. Organizing components using layout managers is covered later in this chapter and also in Chapter 14, "The Windowing (AWT) Package."

Now it's time to look at the various components you can add to your applet. Detailed information about the various AWT components can be found in Chapter 22, "Creating User Interface Components," and Chapter 23, "Working with Dialog Boxes."

Labels

The Label component is a string displayed in the container that cannot be modified by the user. Figure 8.3 shows an example of an applet with a label next to a text field.

Figure 8.3.

A Label component to the left of a text field.

The following code is used to create a Label component and add it to an applet window:

Label l = new Label("E-mail address: ");
add(l);

The parameter in the constructor Label("E-mail address: ") identifies the text to be displayed.

Text Fields

The TextField component is an input box in which a user can type a single line of text. The number of characters visible in the text field is configurable. Figure 8.4 shows an example of an applet with a text field.

Figure 8.4.

A TextField component.

Adding a TextField component to a window is the same as adding a button or any other component:

TextField t = new TextField(12);
add(t);

The parameter 12 in the constructor TextField(12) sets up the text field so that the field is limited to displaying approximately 12 characters. The user can type more characters than that, but only some of the characters will be displayed.


NOTE: The actual number of characters displayed depends on which characters are typed. A text field can display more is than ms because the former characters are narrower than the latter.

If a string is specified as a parameter, such as TextField t = TextField("your name"), the text field is created with that string as the default text in the input area of the field.

You can specify default text and a width at the same time by using a statement such as this:

TextField country = new TextField("United States", 20)


TIP: There is no default length for the text field. If you don't supply a length parameter, the result is a one-character-wide text field.

Text Areas

The TextArea component is an extended input box that makes it possible for the user to enter more than one line of text. The number of lines and the number of characters per line visible in the text area are configurable. Figure 8.5 shows an example of an applet with a text area.

Figure 8.5.

A TextArea component.

The following code is used to create a TextArea component and add it to an applet window:

TextArea t = new TextArea(5,20);
add(t);

The parameters 5 and 20 specify the text area's number of lines and the number of characters per line, respectively. If the text extends beyond the borders of the text area, a scrollbar appears to enable the user to scroll to the different sections of the text area.

If a string is specified as a parameter to the constructor, as in the statement TextArea t = TextArea("It was a dark and stormy night.", 7, 25); the text area is created with the string as the default text in the input area of the field. To cause parts of this text to start at the beginning of the next line, use a newline character (\n) in the text of the parameter. For example, to put the text "stormy night" at the beginning of a new line, use the following statement:

TextArea t = TextArea("It was a dark and \nstormy night", 7, 25);

Buttons

The Button component is a rectangular button that can be clicked with a mouse. The ColorCycle applet, earlier in this chapter, used a Button component to change the background color. Creating a Button component and adding it to an applet window requires two lines:

Button b = new Button("Cancel");
add(b);

Because the add(b) method does not refer to a specific container object, it defaults to adding the button to the applet surface. You can also create a new Panel and add a new Button component to that panel:

Panel p = new Panel();
Button b = new Button("Cancel");
p.add(b);

Checkboxes

The Checkbox component is a toggle box that can be either selected or deselected. When selected, the checkbox displays a checkmark. This element usually has a line of text next to it explaining what the box signifies. Figure 8.6 shows an example of an applet with a checkbox.

Figure 8.6.

A Checkbox component.

The following code is used to create a Checkbox component and add it to an applet window:

Checkbox c = new Checkbox("Never Mind");
add(c);

The parameter in the constructor Checkbox("Never Mind") identifies the text to be displayed. If you omit this parameter, a checkbox is displayed without any text next to it.

A checkbox is often used with a group of related checkboxes so that only one of the boxes can be selected at one time. In HTML, such groups of checkboxes are known as radio buttons. To create a group of checkboxes, you use the CheckboxGroup class. The setCheckboxGroup() method associates a checkbox with a particular group. The setCurrent() method of CheckboxGroup is used to make one of the boxes the selected box. Listing 8.5 shows the use of Checkbox and CheckboxGroup; the code is also located on the CD-ROM that accompanies this book.

Listing 8.5. An applet that creates a group of checkboxes similar to an HTML radio button group.

1:  import java.applet.Applet;
2:  import java.awt.*;
3:
4:  public class ContainerAndPanel extends Applet {
5:      CheckboxGroup cbg = new CheckboxGroup();
6:
7:      public void init() {
8:          Checkbox c1 = new Checkbox("I hug trees.");
9:          c1.setCheckboxGroup(cbg);
10:         c1.setState(false);
11:         add(c1);
12:
13:         Checkbox c2 = new Checkbox("I cut trees.",cbg,false);
14:         add(c2);
15:
16:         Checkbox c3 = new Checkbox("I've never seen a tree",cbg,true);
17:         add(c3);
18:     }
19: }

When adding a checkbox to a group, note the difference between lines 8 through 10 and line 13. Line 8 creates the checkbox with its label; line 9 adds it to the group; line 10 sets its initial state to false. Line 13 combines these three operations into a single statement by merging the three parameters into the Checkbox method instantiation. Figure 8.7 shows the checkbox group that results from Listing 8.5.


TIP: By default, all checkboxes are set to false (deselected) when they are instantiated. There is no need to use setState() for a new checkbox unless you want to ensure its state or set it to true.

Figure 8.7.

A group of Checkbox components.

Choice List

The Choice component is a popup list of strings from which a single string can be selected, similar to a group of checkboxes. A choice list provides a group of options and enables selection of one at a time. Figure 8.8 shows an example of an applet with a choice list.

Figure 8.8.

A Choice component.

The addItem() method of the Choice class is used to build the choice list. To create a list, you instantiate the list, add individual items to it, and then add the loaded list to an applet window:

Choice c = new Choice();
c.addItem("Moe");
c.addItem("Larry");
c.addItem("Curly");
add(c);

Scrolling Lists

The List component is a scrolling list of strings from which one or more strings can be selected. Figure 8.9 shows an example of an applet with a scrolling list.

Figure 8.9.

A List component.

The addItem() method of the List class is used to build the scrolling list. The following code is used to create a scrolling list, add items to it, and then add the list to an applet window:

List l = new List(4,true);
l.addItem("Rocky");
l.addItem("Bullwinkle");
l.addItem("Boris");
l.addItem("Natasha");
l.addItem("Dudley Do-Right");
l.addItem("Nell");
add(l);

The List() constructor can be used with no parameters or with two parameters. The List l = new List(4, true) statement uses two parameters; the first parameter indicates the number of list items to display in the list window and the second parameter determines how many list items can be selected. If the second parameter is true, multiple items can be selected. Otherwise, only one choice is allowed at a time, similar to the choice list.

Scrollbars

The Scrollbar component is an up-down or left-right slider that can be used to set a numeric value. You use this component by clicking the mouse on an arrow or by grabbing the box on the slider. Figure 8.10 shows an example of an applet with a scrollbar.

Figure 8.10.

A Scrollbar component.

The first parameter of the Scrollbar constructor determines whether it is a vertical or horizontal scrollbar. If you want the bar to be vertical, use the constant Scrollbar.VERTICAL. Otherwise, use the constant Scrollbar.HORIZONTAL. Four other parameters follow the alignment parameter; these parameters determine the slider's initial setting, the size of the scrollable area, the minimum value, and the maximum value.

Consider the following statement:

Scrollbar sb = new Scrollbar(Scrollbar.HORIZONTAL, 50, 500, 0, 1000);
add(sb);

This code creates a horizontal Scrollbar component with the slider initially set to 50. When the user moves the slider, the scrollable area can return a value from 0 (the minimum value on the left) to 1000 (the maximum value on the right). The value changes in increments of 2 because the overall size of the scrollbar is limited to 500 elements (half the maximum value).

Canvases

The Canvas component is a section of a window used primarily as a place to draw graphics or display images. In that respect, a canvas is more similar to a container than a component--however, a Canvas component cannot be used as a place to put components. The following code creates a Canvas component, resizes it to 50x50 pixels, sets the background of the canvas to the color black, and adds the canvas to an applet window:

Canvas c = new Canvas();
c.resize(50,50);
c.setBackground(Color.black);
add(c);

Figure 8.11 shows the code as it appears to the user: a black area on a white applet background.

Figure 8.11.

A Canvas component.

Organizing the Interface

Up to this point, all the components have been added to a container in a manner similar to the way HTML elements are arranged on a Web page. Things are loosely organized from left to right and from top to bottom; the look of the container is highly dependent on the size of its display area.

This approach is an easy way to implement Java's multiplatform capability. Because the language must work on any system that has a Java implementation, the windowing environment must be flexible. This also means that the same Java applet looks dramatically different when shown on a Windows 95 system, a Macintosh system, and a SPARC workstation, although it works exactly the same.

However, Java's developers understood the need for organizing the components in a user interface. Therefore, they extended Java's capability to customize your applet's interface to work on each of the platforms and to look close enough in appearance on different platforms to ensure cross-platform usability.

The tools added for this purpose are called layout managers. In the preceding sections, when you added components to a container--the main applet window--you were using the default layout manager: a class called FlowLayout. There are four other layout managers you can use as you organize your interface: BorderLayout, GridLayout, GridBagLayout, and CardLayout.

The FlowLayout Class

The FlowLayout class is the default layout manager for all panels, including the Applet class. It's the simplest to use. Components placed under the rules of FlowLayout are arranged in order from left to right. When a component is too big to be added to the current row, a new line of components is begun below the first line.

Each row of components can be aligned to the left, right, or centered. The only parameter used with the add() method is the name of the object to add.

The following setLayout() statement sets up a container to use the FlowLayout manager:

setLayout( new FlowLayout() );

The BorderLayout Class

The BorderLayout class is the default layout manager for all Window, Dialog, and Frame classes. In a border layout, components are added to the edges of the container; the center area is allotted all the space that's left over. The add() method takes an additional parameter--a string that can be North, South, East, West, or Center. This parameter specifies the location in the border layout for the component. For example, the following statements create five buttons and add them to a container laid out with the BorderLayout manager, as shown in Figure 8.12:

Button b1 = new Button("Climb");
Button b2 = new Button("Dive");
Button b3 = new Button("Left");
Button b4 = new Button("Right");
Button b5 = new Button("Fire!");
setLayout( new BorderLayout() );
add("North", b1);
add("South", b2);
add("West", b3);
add("East", b4);
add("Center", b5);

Note the use of the setLayout() method to select a layout manager for the container. Its single parameter is an instance of the desired layout. Remember to capitalize the directional parameter to the add() method. Like many other case-sensitive aspects of the Java language, the BorderLayout manager requires the directions to be capitalized consistently as North, South, East, West, and Center.

The GridLayout Class

The GridLayout class puts each component into a place on a grid that is equal in size to all the other places. The grid is given specific dimensions when created; components are added to the grid in order, starting with the upper-left corner. This is similar to the way components are added with the FlowLayout manager, but with GridLayout, components are given equal amounts of space in the container.

Figure 8.12.

Components arranged by the BorderLayout manager.

Components added to the container with the GridLayout manager are arranged in order from left to right. When there are no more grids remaining on a row, the next component to be added is placed in the leftmost grid on the next line. New rows are added as needed--if you create a three-by-three grid and add a tenth item, a fourth row is added. The only parameter used with the add() method is the name of the object to add.

The following setLayout() statements set up a container to use the GridLayout manager with three rows and two columns and then add a series of buttons:

setLayout( new GridLayout(3, 2));
Button b1 = new Button("Lefty");
Button b2 = new Button("Righty");
Button b3 = new Button("Loosey");
Button b4 = new Button("Tighty");
Button b5 = new Button("White on Right");
Button b6 = new Button("Red on Ribs");
add(b1);
add(b2);
add(b3);
add(b4);
add(b5);
add(b6);

Figure 8.13 shows an example of an applet with all the components arranged according to the rules of the GridLayout manager.

The GridBagLayout Class

The GridBagLayout class is similar to the GridLayout class except that GridBagLayout provides much more control over how the grid is organized and how components are presented. Cells in the grid are not required to take up the same amount of space, and components can be aligned in different ways in each grid cell.

A special GridBagConstraints object is used to determine how a component is placed in a cell and how much space the cell will occupy. Unlike the FlowLayout and GridLayout managers, the GridBagLayout manager permits you to add components to the grid in any order.

Figure 8.13.

Components arranged by the GridLayout manager.


The first step you take to use the GridBagLayout manager is to set up the layout and the GridBagConstraints object, as shown here:

GridBagLayout gl = new GridBagLayout();
setLayout ( gl );
GridBagConstraints gb = new GridBagConstraints();

Before you can add a component to the container, you use instance variables of the GridBagConstraints object to determine the component's location and alignment within its grid cell.

The following GridBagConstraints variables can be set:

  • gridx and gridy: These variables specify the cell in the grid where the component should be placed. gridx represents the rows, and gridy represents the columns. The (1,1) position is the upper-left corner.

  • gridheight and gridwidth: These variables specify the number of cells a component should occupy. gridheight determines the number of rows, and gridwidth determines the number of columns.

  • fill: This variable specifies the directions in which a component should expand if it has room to grow inside its cell. This can happen because of larger components in other cells. The constants GridBagConstraints.HORIZONTAL, GridBagConstraints.VERTICAL, GridBagConstraints.BOTH, and GridBagConstraints.NONE can be used with this variable. This example sets the fill variable to expand in both the horizontal and the vertical directions:

    gb.fill = GridBagConstraints.BOTH;

  • anchor: This variable specifies the way a component should be aligned in its cell. The following GridBagConstraints constants are used: NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST, and CENTER.

Listing 8.6 shows an example of placing a component on a page using the GridBagLayout class. The code can also be found on the CD-ROM that accompanies this book.

Listing 8.6. Placing a component with the GridBagLayout manager.

// declare variables
GridBagLayout gl = new GridBagLayout();
GridBagConstraints gb = new GridBagConstraints();
// choose a layout manager
setLayout ( gl );
// create components
Label l1 = new Label("Full e-mail address:");
Label l2 = new Label("Captain Kirk");
Label l3 = new Label("Crate of oranges");
// set up the constraints and add component
gb.gridx = 1;
gb.gridy = 1;
gb.gridwidth = 2;
gl.setConstraints(l1, gb);
add(l1);
// set up the constraints and add component
gb.gridx = 5;
gb.gridy = 3;
gb.gridwidth = 2;
gl.setConstraints(l2, gb);
add(l2);
// set up the constraints and add component
gb.gridx = 3;
gb.gridy = 5;
gb.gridwidth = 2;
gl.setConstraints(l3, gb);
add(l3);

In this example, the first component is placed in row 1, column 1 of the grid and takes up two cells in width. The second component is placed in row 5, column 3; the third component is placed in row 3, column 5. Figure 8.14 shows an example of an applet with all components arranged according to the rules of the GridBagLayout manager and its GridBagConstraints.

Figure 8.14.

Components arranged by the GridBagLayout manager.

The CardLayout Class

The CardLayout class is a special type of layout organizer. Instead of displaying several panels concurrently, it creates a stack of panels that can then be displayed one at a time, much like the stack of cards in the ubiquitous Solitaire game. The CardLayout class has its own group of methods that are used to control which panel is displayed.

Listing 8.7 uses a series of panels with different-colored canvases to illustrate the CardLayout class. Clicking on the applet area causes the layout manager to load the next panel. If the last panel is already loaded, the CardLayout manager automatically returns to the first panel. This code is also located on the CD-ROM that accompanies this book.

Listing 8.7. Using the CardLayout class to display three panels with different colors.

import java.applet.Applet;
import java.awt.*;

public class cardStack extends Applet {    
     private Panel   canvasCards = new Panel(),
        p1 = new Panel(), p2 = new Panel(), p3 = new Panel();
     private CardLayout cardDeck = new CardLayout();

    public void init() {
        canvasCards.setLayout( cardDeck );

        p1.setLayout (new BorderLayout());
        p2.setLayout (new BorderLayout());
        p3.setLayout (new BorderLayout());

        Canvas c1 = new Canvas(), c2 = new Canvas(), c3 = new Canvas();
        c1.setBackground(Color.black);
        c2.setBackground(Color.red);
        c3.setBackground(Color.green);

        p1.add("Center", c1);
        p2.add("Center", c2);
        p3.add("Center", c3);

        canvasCards.add("p1", p1);
        canvasCards.add("p2", p2);
        canvasCards.add("p3", p3);

        setLayout(new BorderLayout());
        add("Center", canvasCards);
    }

    public boolean mouseDown(Event event, int x, int y) {
        cardDeck.next(canvasCards);
        return true;
    }
}

Combining Layouts with Nested Panels

Although the Abstract Windowing Toolkit offers several different kinds of layout managers, frequently, one specific manager does not fit the user interface you are trying to create.

The solution to this problem is to nest one type of container inside another so that the nested container can have one type of layout manager and the larger container can use another. You can nest containers as many times as necessary because containers can contain other containers; each container can use its own layout manager.

The following code creates a container that uses the BorderLayout manager and then adds a panel of choice boxes to that container. Because no layout manager is specified for the boxes, they default to the FlowLayout manager.

setLayout( new BorderLayout() );
Button b1 = new Button("Purchase");
add("North", b1);
Button b2 = new Button("Exit");
add("West", b2);
Button b3 = new Button("Help");
add("East", b3);
Button b4 = new Button("Browse Catalog");
add("South", b4);
Panel p = new Panel();
// add check boxes to panel
Checkbox c1 = new Checkbox("Brazil: $9.95");
p.add(c1);
Checkbox c2 = new Checkbox("Time Bandits: $12.95");
p.add(c2);
Checkbox c3 = new Checkbox("12 Monkeys: $39.95");
p.add(c3);
// add panel to main container
add("Center",p);

Figure 8.15 shows an applet that uses this code. By using nested panels and different types of layout managers, you can create many different types of user interface windows.

Figure 8.15.

A container organized by the BorderLayout manager with a nested panel in the center organized by the FlowLayout manager.

Event Handling

At this point, you have the tools necessary to build an impressive graphical user interface for a Java applet. You can use text fields to enter characters, click buttons, move scrollbars from side to side, and so on.

However, the interface has no way to respond to any of this user input. In a windowing environment such as the one provided by the Abstract Windowing Toolkit, user input--whether from the mouse, keyboard, or other means--generates an event.

An event is a way for a program to communicate that something has taken place. Events generate automatic calls to methods in the same way that a paint() method can be called automatically when an applet window has to be redrawn, or that an init() method is called automatically when an applet is first run.

Events can involve a user interface element--such as a button that has been clicked. Events can also be something unrelated to the interface--such as an error condition that causes the program to stop execution.

In Java, the class java.awt.Event handles all events related to the user interface.

For the purposes of controlling the user interface components you can create for use with applets, there are two kinds of events to consider: action events and scrollbar events.

Action Events

An action event is generated by most user interface components to signify that something has happened. This means different things depending on the component:

  • For buttons, an event means that the button has been clicked.

  • For checkboxes, an event means that the box has been selected or deselected.

  • For lists or choice lists, an event means that one of the list items has been selected.

  • For text fields, an event means that the Enter key has been pressed to indicate that user input is completed.

The action() method is part of the Event class and follows this syntax:

public boolean action(Event e, Object o) {
// method code here
}

All user interface components that must generate an action event use the action() method. Two parameters to the method determine which component generated the event and gather some other information about what occurred. These two parameters are an instance of an Event and an Object class.

The Event class has several instance variables that provide information about the event that has taken place. The one you use most with action() events is the target variable, which indicates which component generated the event.

The code in Listing 8.8 creates three buttons on an applet window and sets a TextField in response to the button that was pressed, as shown in Figure 8.16. The code can also be found on the CD-ROM that accompanies this book.

Listing 8.8. The full source code of Buttons.java.

1: import java.awt.*;
 2:
 3: public class Buttons extends java.applet.Applet {
 4:     Button b1 = new Button("Swing Away");
 5:     Button b2 = new Button("Bunt");
 6:     Button b3 = new Button("Renegotiate Contract");
 7:     TextField t = new TextField(50);
 8:
 9:     public void init() {
10:         add(b1);
11:         add(b2);
12:         add(b3);
13:         add(t);
14:     }
15:
16:     public boolean action(Event e, Object o) {
17:         if (e.target instanceof Button) {
18:             String s = (String)o;
19:             if ( s.equals("Swing Away") )
20:                 t.setText("A long fly to center ... caught.");
21:             else if ( s.equals("Bunt") )
22:                 t.setText("You reach second base on an  infielder's error!");
23:             else
24:                 t.setText("You're now America's newest multimillionaire!");
25:             return true;
26:         }
27:         return false;
27:     }
28: }

Figure 8.16.

The Buttons applet.

Scrollbar Events

The action() method is generated by every component described in this chapter except for Scrollbar. The Scrollbar component uses the handleEvent() method. Unlike the action() method, handleEvent() takes only one parameter: an instance of the Event class:

public boolean handleEvent(Event e) {
    // method code here
}

Using the target variable of the Event class, you can determine which component generated the event and respond to it. Listing 8.9 sets a value in a text field based on user input to a scrollbar. You can find the code on the CD-ROM that accompanies this book.

Listing 8.9. The full source code of Scroller.java.

1: import java.awt.*;
 2:
 3: public class Scroller extends java.applet.Applet {
 4:     Scrollbar s = new Scrollbar(Scrollbar.HORIZONTAL,
 5:                     50,100,0,100);
 6:     Label l = new Label("Choose Your Own Tax Rate: ");
 7:     TextField t = new TextField("50%", 3);
 8:
 9:     public void init() {
10:         add(s);
11:         add(l);
12:         add(t);
13:     }
14:
15:     public boolean handleEvent(Event e) {
16:         if (e.target instanceof Scrollbar) {
17:             int taxrate = ((Scrollbar)e.target).getValue();
18:             t.setText(taxrate + "%");
19:             return true;
20:         }
21:     return false;
22:     }
23: }

When you use a Web browser or the JDK applet viewer utility to view the completed applet, it should resemble Figure 8.17.

Figure 8.17.

The Scroller applet.

Summary

As you will find when programming your own applets, the Java API has built-in functionality that handles a lot of the work for you. The user interface provides many components such as buttons, text fields, and choice boxes--and subclassing makes it possible to extend these components without requiring a lot of new code.

Tasks that can be arduous in some languages--such as animation and event handling--are relatively easy with Java. One of Java's original design goals was simplicity. Some folks argue that object-oriented programming is never simple. However, applet programming is a good area for novice Java programmers to begin because it can be easy to develop useful Web programs without a lot of coding.

This introduction to applet programming and the Abstract Windowing Toolkit demonstrated a lot of Java's functionality as it's built into the class libraries. For many applets, creating the user interface represents the bulk of the work because a lot of the code required to control the interface has already been written.

Each of the user interface components has methods you can use to retrieve or change their values, enable or disable their operation, and perform other tasks. The full reference to these methods is available in Appendix C, "Java Class Library."

TOCBACKFORWARDHOME


©Copyright, Macmillan Computer Publishing. All rights reserved.