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:
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."
|