Applets

   

Applications aren't the only kind of Java programs that can make use of the JFC. Applets ” Java programs that run in the context of a Web browser ”can also benefit from the JFC APIs. In fact, applets are intimately connected to the JFC, by virtue of inheriting capabilities from important JFC classes.

What Is an Applet?

An applet is a Java program that runs in the context of a Web browser. At various times, the Web browser calls certain applet methods to perform applet-specific tasks , and these methods respond appropriately.

The Web browser reserves a rectangular portion of its main window as a display area for each applet that requires a place in which to draw its output. The Web browser also arranges for an applet to receive input from either the keyboard or the mouse.

The Web browser subjects applets to security restrictions. These restrictions prevent rogue applets from causing damage to a user 's computer (such as stealing passwords or deleting files). For example, an applet is not normally given access to the local file system or printer. It must first be granted access.

Note

The topic of granting access to the file system, printer, and other sensitive aspects of a computer system is beyond the scope of this chapter, and is not covered in this book. For more information, please consult the SDK 1.3 documentation.


Applets and the World Wide Web

When you start your Web browser and select a site to visit, the Web browser attempts to locate this site. If successful, the Web browser will attempt to connect to the server that hosts this site and request that the server send it an HTML document ” a file containing literal text and tags. Tags instruct the Web browser as to what additional files are required and how to render a Web page.

After the Web browser has received this document, it might close its connection to the server, unless it leaves this connection open for performance reasons. It then parses the document in preparation to displaying the resultant Web page. During parsing, the Web browser examines the document for special HTML tags (such as <IMG> or <APPLET> ). For each occurrence of these tags, the Web browser establishes a new connection to the server (unless a persistent connection was established) and requests an appropriate file, such as a GIF/JPEG file in the case of an <IMG> tag or a JAR (Java archive)/class file in the case of an <APPLET> tag.

Caution

Although a JAR file has the same architecture as a ZIP file, this could change in the future. Therefore, it's good to think of JAR and ZIP files as separate entities.


If an <APPLET> tag is encountered , this tag is parsed to identify the JAR file and/or main class file that constitutes an applet. If a JAR file is present, the Web browser requests this file from the server. Otherwise, only the main class file is requested .

Assuming that a JAR file is retrieved, the Web browser makes sure the main class file is extracted from the JAR file. In any event, the Web browser starts the JVM by loading its library into memory. It then passes the main class file to the JVM.

The JVM's class loader loads the class file, and its bytecode verifier ensures that all bytecode instructions are properly formed so that they will not cause problems for the JVM. As the JVM encounters references to other classes, via internal import directives, the JVM makes requests, via the Web browser, to the server for additional class files.

Figure 12.3 illustrates the process by which the Web browser requests class files from a server.

Figure 12.3. The Web browser and server continue to interact until all class files have been obtained.

graphics/12fig03.gif

AWT Applets

An AWT applet inherits capabilities from the AWT's Applet class (located in the java.applet package). Because Applet is ultimately derived from the java.awt.Component class, AWT applets are first-class GUI components . Figure 12.4 shows the PNViewer3 AWT applet ”that mirrors the PNViewer1 AWT application ”running in the Netscape Communicator Web browser. (Although not shown in this chapter, PNViewer3 's source code is included with the rest of this book's source code.)

Figure 12.4. The PNViewer3 applet runs in the Netscape Communicator Web browser.

graphics/12fig04.gif

To illustrate that an AWT applet can be run in multiple Web browsers, Figure 12.5 shows PNViewer3 running in the Internet Explorer Web browser.

Figure 12.5. The PNViewer3 applet runs in the Internet Explorer Web browser.

graphics/12fig05.gif

SDK 1.3 comes with an Applet Viewer program for running AWT applets. This program takes a single argument that identifies an HTML document. For example, the following code fragment shows how to run PNViewer3 with the pnviewer3.html file. (Although not shown in this chapter, pnviewer3.html is included with the rest of this book's files.)

 appletviewer pnviewer3.html 

An AWT applet consists of one or more classes. However, one of these classes (the main class) must be declared public and must extend the Applet class, in the java.applet package. Listing 12.3 shows what this looks like, via an applet called MyApplet1.

Listing 12.3 MyApplet1 ” The World's Simplest AWT Applet
 public class MyApplet1 extends java.applet.Applet { } 

The MyApplet1 applet appears to be a simple applet. After all, it occupies just three lines of source code. However, looks are deceiving. In reality, MyApplet1 is inheriting more than 200 methods and field variables from ancestor classes. The hierarchy of these classes (along with MyApplet1 ) is shown in the following inheritance tree:

 java.lang.Object        +----java.awt.Component                        +----java.awt.Container                                        +----java.awt.Panel                                                        +----java.applet.Applet                                                                        +----MyApplet1 

Because MyApplet1 inherits from Applet, MyApplet1 is an AWT applet. Also, because Applet inherits from Panel, MyApplet1 is a kind of panel. Furthermore, because Panel inherits from Container, MyApplet1 is a kind of container. Finally, because Container inherits from Component, MyApplet1 is a kind of component. You can see that MyApplet1 is deeply connected to the JFC, because of the presence of Component, Container, and Panel in this hierarchy.

See Chapter 14, "Building a GUI: AWT Style" .

Tip

Mastering the JFC requires a time investment to understand the class hierarchies (along with methods and fields) that make up the five major APIs. However, this investment will richly pay off. Not only will this organizational knowledge speed development, it will also help speed the process of debugging faulty JFC programs.


The Applet class contains many useful methods for your applets, and some of these methods are designed to be overridden. You'll have a chance to see some of these methods in action, as you progress through this chapter. To get a head start, check out Table 12.1.

Table 12.1. The Methods in the Applet Class
Method Description
destroy () This method is called by the Web browser prior to reclaiming applet memory. Code would be placed in this method to cleanup global resources.
getAccessibleContext () Returns a reference to an accessible context object. This object is used in conjunction with the Accessibility API (discussed in a later chapter).
getAppletContext () Returns a reference to an object that implements the AppletContext interface. The applet might call methods defined by this interface to query and affect its environment. (Contexts will be discussed later in this chapter.)
getAppletInfo () Returns a reference to a String object containing applet information (such as author name and copyright). Some Web browsers use this information, although many do not.
getAudioClip (URL url) Returns a reference to an object that implements the AudioClip interface. This object is associated with the URL (Uniform Resource Locator) argument url, which specifies the location and name of an audio file. The applet might call methods defined by this interface to play audio. This method returns immediately, regardless of the audio file's existence. The first attempt to play the audio file causes this file to be downloaded.
getAudioClip (URL url, String file) This method concatenates the location of an audio file (specified by url ) and its name (specified by file ) into a single entity, and then calls getAudioClip (URL url).
getCodeBase () Returns a reference to a URL object that identifies the location from which this applet was downloaded.
getDocumentBase () Returns a reference to a URL object that identifies the location from which this applet's HTML document was downloaded.
getImage (URL url) Returns a reference to an Image object. This object is associated with url, which specifies the location and name of an image file. This method returns immediately, regardless of the image file's existence. The first attempt to draw this image will cause this file to be downloaded.
getImage (URL url, String file) This method concatenates the location of an image file (specified by url ) and its name (specified by file ) into a single entity, and then calls getImage (URL url).
getLocale () Returns a reference to the current Locale object. With this object, an applet can tailor its output (such as text, sound, formatting, and so on) to the conventions of a particular country or region.
getParameter (String p) Returns a reference to a String object containing the value of a parameter, whose name is specified by p, or null if this parameter cannot be found. (Parameters will be discussed later in this chapter.)
getParameterInfo () Returns a reference to a three-column by n -row table of String objects, in which each row contains the name, type, and description of a parameter. Some Web browsers use this information, although many do not. However, various Java tools (such as Integrated Development Environments) tend to use this information. (Parameter information helps Web page authors learn how to configure the applet.)
init () This method is called by the Web browser prior to any other method (except setStub ), to give the applet a chance to initialize.
isActive () Returns a Boolean true value if the applet is active. An applet is made active just prior to a call to its start method and inactive just prior to a call to its stop method.
newAudioClip (URL url) Returns a reference to an object that implements the AudioClip interface. This object is associated with url, which specifies the location and name of an audio file. Because newAudioClip is the only static method in Applet, applications can call this method to return objects implementing AudioClip, and then call AudioClip methods through these objects to play audio.
play (URL url) This method plays the audio file whose location and name are specified by url. Nothing happens if this audio file cannot be found.
play (URL url, String file) This method concatenates the location of an audio file (specified by url ) and its name (specified by the file argument) into a single entity, and then calls play (URL url).
resize (Dimension d) This method requests that the applet's display area be resized to the width and height contained in d. This request is typically ignored by Web browsers.
resize (int w, int h) This method requests that the applet's display area be resized to the width and height contained in w and h, respectively. This request is typically ignored by Web browsers.
setStub (AppletStub as) This method is called by a Web browser to set an applet's stub to as. (Stubs will be discussed later in this chapter.)
showStatus (String msg) This method requests that the contents of msg be displayed in the Web browser's status bar window.
start () This method is called by the Web browser to inform the applet that it should start its execution.
stop () This method is called by the Web browser to inform the applet that it should stop its execution.

Troubleshooting Tip

suppose you want to create a simple JFC application that plays an audio clip (audio data stored in a sound file). To see how this task is accomplished, check out "Playing Audio Clips from a JFC Application in the "Troubleshooting" section at the end of this chapter.


AWT Applet HTML

AWT applets are identified to a Web browser by including the HTML <APPLET> tag in an HTML document. Each AWT applet is introduced with its own <APPLET> tag and terminated with a </APPLET> tag. <APPLET> contains several attributes that characterize an applet. These attributes include CODE, WIDTH, and HEIGHT.

The CODE attribute identifies the name of an applet's main class file. The WIDTH attribute identifies the width (in pixels or as a percentage) of the applet's display area. Finally, the HEIGHT attribute identifies the height (in pixels or as a percentage) of the applet's display area. To demonstrate an <APPLET> tag and its attributes, Listing 12.4 presents MyApplet1.html. This HTML document contains an <APPLET> tag for the MyApplet1 applet.

Listing 12.4 MyApplet1.html
 <applet code="MyApplet1.class" width=100 height=100> </applet> 

Caution

As with other HTML tags, the <APPLET> and </APPLET> tags and their attribute names (such as CODE ) are not case sensitive. However, attribute values are. When providing the CODE attribute's value, you must specify the main class file's name using the appropriate case of each letter. For example, the previously presented MyApplet1 class requires an uppercase letter M and an uppercase letter A in its name. All the other letters are required to be lowercase. As a result, an attempt to specify the tag <applet code="MYAPPLET1.class" width=100 height=100> would most likely cause an error, because the Web browser's JVM would probably not be able to find a class file called MYAPPLET1.class.


Although CODE, WIDTH, and HEIGHT are the more commonly specified attributes, <APPLET> supports several additional attributes. All attributes are listed and described in Table 12.2.

Table 12.2. Attributes for the <APPLET> Tag
Attribute Value Description
CODE [1] Class name Defines the name of the class file that extends either java.applet.Applet or javax.swing.JApplet. Note: Either a CODE attribute or an OBJECT attribute must be specified.
WIDTH [2] Number Width (in pixels or a percentage) of the applet's display area.
HEIGHT [1] Number Height (in pixels or a percentage) of the applet's display area.
HSPACE Number Horizontal space (in pixels) between the applet and the rest of the HTML. Behaves identically to the <IMG> tag's HSPACE attribute value.
VSPACE Number Vertical space (in pixels) between the applet and the rest of the HTML. Behaves identically to the <IMG> tag's VSPACE attribute value.
ALIGN Any of LEFT, RIGHT, MIDDLE, ABSMIDDLE, TOP, TEXTTOP, BASELINE, BOTTOM, ABSBOTTOM Indicates the alignment of the applet in relation to the rest of the HTML. These values work the same as their <IMG> tag counterparts.
ALT String Specifies alternate text to be displayed by the browser if it is unable to display the actual applet. This attribute is only used if the browser understands the <APPLET> tag but is unable to display the applet. Otherwise, any HTML between the <APPLET> and </APPLET> tags is displayed.
ARCHIVE Archive list Contains a list of JAR files and other resources that should be "preloaded" by the Web browser before it begins execution.
OBJECT [1] Serialized Contains the name of the file that has a serialized representation of the applet. When reconstituting the applet, the init method will not be called because it is presumed to have been called on the serialized applet. However, the start method will be called. Note: Either a CODE attribute or an OBJECT attribute must be specified.
CODEBASE URL Identifies the directory that contains an applet's class files. If this attribute is not specified, the HTML document's URL is used.

[1] Either attribute (but not both) is required.

[2] Required

Troubleshooting Tip

Suppose you need to design an applet that launches a separate window frame, in response to a button press. Later, you want to be able to close this frame and continue working with the applet. To see how this task is accomplished, check out "Launching a Frame from an Applet" in the "Troubleshooting" section at the end of this chapter.


Swing Applets

A Swing applet inherits capabilities from Swing's JApplet class (located in the javax.swing package). Like Applet, JApplet is ultimately derived from the java.awt.Component class. Therefore, Swing applets are also first-class GUI components. Figure 12.6 shows the PNViewer4 Swing applet ”that mirrors the PNViewer2 Swing application ”running in the Netscape Communicator Web browser. (Although not shown in this chapter, PNViewer4 's source code is included with the rest of this book's source code.)

Figure 12.6. The PNViewer4 applet runs in the Netscape Communicator Web browser.

graphics/12fig06.gif

To illustrate that a Swing applet can be run in multiple Web browsers, Figure 12.7 shows PNViewer4 running in the Internet Explorer Web browser.

Figure 12.7. The PNViewer4 applet runs in the Internet Explorer Web browser.

graphics/12fig07.gif

SDK 1.3's Applet Viewer program can also be used to run Swing applets. For example, the following code fragment shows how to run PNViewer4 with the pnviewer4IE.html file. (Although not shown in this chapter, pnviewer4IE.html is included with the rest of this book's files.)

 appletviewer pnviewer4IE.html 

As with AWT applets, a Swing applet consists of one or more classes. However, one of these classes (the main class) must be declared public and must extend the JApplet class, in the javax.swing package. Listing 12.5 shows what this looks like, via an applet called MyApplet2.

Listing 12.5 MyApplet2 ” The World's Simplest Swing Applet
 public class MyApplet2 extends javax.swing.JApplet { } 

As with MyApplet1, the MyApplet2 applet appears to be a simple applet. However, it also inherits more than 200 methods and field variables from ancestor classes. The hierarchy of these classes (along with MyApplet2 ) is shown in the following inheritance tree:

 java.lang.Object        +----java.awt.Component                        +----java.awt.Container                                        +----java.awt.Panel                                                        +----java.applet.Applet                                                                        +----javax.swing.JApplet                                                                                        +----MyApplet2 

The only difference between this and the previous inheritance trees is the presence of the javax.swing.JApplet class. MyApplet2 inherits JApplet methods that establish a Swing-based GUI environment for the Swing applet. This involves using different kinds of panes. Until panes are discussed in a later chapter, it's sufficient to think of panes as being analogous to the AWT's panels.

One item to note in the preceding inheritance tree is that JApplet inherits from Applet. This means that all of Applet 's methods (described in Table 12.1) are available to Swing applets.

Unlike AWT applets, Swing applets can use menu bars with drop-down menus . This is accomplished by constructing a JMenuBar object, constructing one or more JMenu objects, constructing one or more JMenuItem objects for each JMenu object, adding the JMenuItem objects to the appropriate JMenu objects, adding the JMenu objects to the JMenuBar object, and finally calling JApplet 's setJMenuBar method to establish the menu bar. To demonstrate this concept, Listing 12.6 shows the source code to the Swing-based MenuApplet.

Listing 12.6 The MenuApplet Applet Source Code
 // MenuApplet.java import javax.swing.*; public class MenuApplet extends JApplet {    public void init ()    {       JMenuBar menubar = new JMenuBar ();       JMenu menuFile = new JMenu ("File");       JMenuItem openItem = new JMenuItem ("Open");       menuFile.add (openItem);       JMenuItem saveItem = new JMenuItem ("Save");       menuFile.add (saveItem);       menubar.add (menuFile);       JMenu menuHelp = new JMenu ("Help");       JMenuItem aboutItem = new JMenuItem ("About");       menuHelp.add (aboutItem);       menubar.add (menuHelp);       setJMenuBar (menubar);    } } 

Don't worry about understanding Swing menus, because they will be discussed in a later chapter.

See Chapter 16, "Building a GUI: Swing Style" .

For now, note the setJMenuBar (menubar) method call. This method call is responsible for adding the menu bar to MenuApplet.

Listing 12.7 presents the HTML code for the MenuApplet applet. (Keep in mind that a Web browser will not properly run MenuApplet using this tag, because current Web browser implementations of JVMs do not recognize Swing. However, you can use Applet Viewer to run MenuApplet with this HTML.)

Listing 12.7 The MenuApplet Applet HTML Code
 <applet code="MenuApplet.class" width=275 height=100> </applet> 

Now that you've seen MenuApplet 's source and HTML code, check out Figure 12.8. As you can see, it's possible for Swing applets to contain menu bars with drop-down menus.

Figure 12.8. Menu bars with drop-down menus are possible with Swing applets.

graphics/12fig08.gif

Swing Applet HTML

In the early days of Java and Web browsers, Sun would release a new version of Java and vendors would continually play catch-up by incorporating this version in the next release of their Web browsers. Because of the time lag between the release of a new Java version and the next release of Web browsers supporting this version, developers were often inconvenienced. They had to wait before they could take advantage of new Java features (or even use features that were previously bug-ridden but now fixed). And if developers were inconvenienced, users relying on the work of those developers were also inconvenienced. This problem reached its climax when Microsoft decided not to completely support Java 1.1 in Version 4 of its Internet Explorer Web browser.

Sun remedied this problem by creating a product called Java Plug-in. Java Plug-in takes advantage of a Web browser's plug-in architecture and serves as a bridge between the Web browser and Java runtime software. As a result, it is possible to run more advanced AWT applets and Swing applets in a Web browser environment.

Java Plug-in works in partnership with Netscape's <EMBED> tag and Microsoft's <OBJECT> tag. These tags make it possible to embed either an advanced AWT applet or a Swing applet in the context of the appropriate Web browser.

Listing 12.8 shows the HTML code required to run the PNViewer4 applet in the Netscape Communicator Web browser. This code makes use of Netscape's <EMBED> tag.

Listing 12.8 The PNViewer4 Applet Netscape Communicator HTML Code
 <html>   <head>     <title>Planetary Nebula Viewer - NC Version</title>   </head>   <body>     <embed code="PNViewer4.class"        height=450        width=450        pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html"        type="application/x-java-applet;version=1.3">     <noembed>   </body> </html> 

Listing 12.9 shows the HTML code required to run the PNViewer4 applet in the Internet Explorer Web browser. This code makes use of Microsoft's <OBJECT> tag.

Listing 12.9 The PNViewer4 Applet Internet Explorer HTML Code
 <html>   <head>     <title>Planetary Nebula Viewer - IE Version</title>   </head>   <body>     <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"             height=450             width=450             codebase="http://java.sun.com/products/plugin/1.3/                       jinstall-12-win32.cab@Version=1,3,0,0">       <param name="code" value="PNViewer4.class">       <param name="type" value="application/x-java-applet;version=1.3">     </object>   </body> </html> 

If you want to learn more about Java Plug-in (including the <EMBED> and <OBJECT> tags), check out the JavaWorld article "Plug into Java with Java Plug-in." This article is located at http://www.javaworld.com/javaworld/jw-06-1999/jw-06-plugin.html.

Netscape Communicator does not recognize the <OBJECT> tag and Internet Explorer does not recognize the <EMBED> tag. To create an HTML document that supports both Web browsers, you might think it a simple matter to specify both tags and let each Web browser ignore the inappropriate tag. Unfortunately, it's not a simple thing to support both tags. In fact, Sun has created a utility called HTML Converter to facilitate supporting multiple tags. For more information, visit Sun's HTML Converter Web page at http://java.sun.com/products/plugin/1.3/features.html.

SDK 1.3's Applet Viewer program can run Swing applets, as well as AWT applets, via an HTML document that contains an <APPLET> tag. Furthermore, because Applet Viewer "understands" several tags in addition to <APPLET>, you can take the HTML from either Listing 12.8 or 12.9 and run it using Applet Viewer.

Tip

It's a good idea to test your applet in both the Internet Explorer and Netscape Communicator Web browsers. This ensures that people viewing your applet in either Web browser will share the same experience ”and guarantees correct HTML.


Architecture

By now, you probably realize that AWT and Swing applets share a common architecture. The only real difference is the JApplet class ”inherited by Swing applets. In this section, we'll take a look at some of this commonality .

Stubs and Contexts

How does the Web browser create a working applet from the MyApplet1 class? Internally, the Web browser begins by creating an object from this class, as follows :

 // Create an AWT applet. MyApplet1 someName1 = new MyApplet1 (); 

Note

Although someName1 is shown for illustrative purposes, the Web browser is free to choose an appropriate name for the applet objects.


If you recall, no constructor was declared in the MyApplet1 class. Instead, a default no-argument constructor is created by the compiler. This MyApplet1 () constructor calls the Applet () constructor to initialize the applet object. (This constructor call is not the same as calling the init method.) After the applet object is created, the Web browser calls the applet's setStub method, passing a reference to a stub (that is, an object that implements the AppletStub interface). The stub provides the means by which an applet interfaces with the Web browser. Several Applet methods (such as isActive and getDocumentBase ) call corresponding AppletStub methods, via this stub.

One of AppletStub 's methods is getAppletContext. This method returns an applet's context (that is, a reference to an object that implements the AppletContext interface). This context corresponds to the HTML document that contains the applet. As with AppletStub, some of Applet 's methods (such as getAudioClip and getImage ) call corresponding AppletContext methods.

After the stub has been set, the applet's life cycle begins.

Life Cycle

Each AWT and Swing applet has a life cycle. The applet is initialized , started and stopped one or more times, and finally destroyed . The Web browser controls this life cycle by calling four methods (inherited from Applet and usually overridden): init, start, stop, and destroy.

The init method is called immediately after setStub and prior to any other method, and gives an applet a chance to initialize itself. init is the perfect place for the applet to construct its GUI. It will never again be called during the life of the applet.

The start method is called immediately after init and each time a Web page containing the applet is revisited. This method is the perfect place to start threads.

The stop method is called whenever a Web page containing the applet is replaced by another Web page, or just prior to a call to the destroy method. This method is the perfect place to stop threads.

The destroy method is called when a Web browser is terminating. This method is the perfect place to clean up any resources acquired during the init method call. Obviously, destroy will never again be called.

To demonstrate an applet's life cycle, Listing 12.10 provides the source code to an applet called LifeCycle.

Listing 12.10 The LifeCycle Applet Source Code
 // LifeCycle.java public class LifeCycle extends java.applet.Applet {    public void init ()    {       System.out.println ("init () called");    }    public void start ()    {       System.out.println ("start () called");    }    public void stop ()    {       System.out.println ("stop () called");    }    public void destroy ()    {       System.out.println ("destroy () called");    } } 

LifeCycle overrides Applet 's four life cycle methods. When each method is called, a string is sent to the standard output device. Depending on where this applet is run, this device corresponds to either a Web browser's Java console (a special window that is accessed from a Web browser's menu and displays any information sent to the standard output device) or an OS-specific command window.

Note

The LifeCycle class has been placed in a file called LifeCycle.java, and the spelling of the filename is identical to the spelling of the class name. This is no accident . Whenever source code specifies a public class, this source code must be saved to a file with the same name (including uppercase/lowercase sensitivity). Otherwise, the Java compiler will report an error. (Only one public class can be specified in any given source file.)


Before you can run LifeCycle (or any other applet), its source code must be compiled. Compiling applets is identical to compiling applications.

You will need some HTML code to "glue" this applet to a Web browser. Listing 12.11 shows a simple <APPLET> tag for running LifeCycle. The width and height of this applet have been set to zero because this applet does not output anything to its display area. (The standard output device, to which strings are sent, does not correspond to the applet's display area.)

Listing 12.11 The LifeCycle Applet HTML Code
 <applet code="LifeCycle.class" width=0 height=0> </applet> 

Figure 12.9 shows Applet Viewer running LifeCycle and LifeCycle 's output being sent to a Windows 98 command window.

Figure 12.9. The LifeCycle applet output is sent to the Windows 98 command window.

graphics/12fig09.gif

You don't see the string destroy () called in the command window because Applet Viewer is still running. As soon as it terminates, destroy () called will be output to the command window.

Configuring Applets

The Planetary Nebula Viewer programs ( PNViewer1, PNViewer2, PNViewer3, and PNViewer4 ) have a design problem. The names of the images and image files are hard-wired into the source code. To view arbitrary images, you must make changes to each program's code and recompile.

As far as the Planetary Nebula Viewer applets ( PNViewer3 and PNViewer4 ) are concerned , it would be much better to specify the image descriptions and filenames using HTML, and allow the applet to dynamically load these descriptions and their associated image files. In other words, it should be possible to dynamically configure an applet.

The <APPLET> and <OBJECT> tags support dynamic configuration, via the optional <PARAM> tag. Each <PARAM> tag denotes a single parameter to the applet. (The <EMBED> tag does not make use of <PARAM> tags. Instead, parameters are treated as <EMBED> tag attributes.) If present, <PARAM> is situated between <APPLET> and </APPLET> or <OBJECT> and </OBJECT>.

The format of the <PARAM> tag is

 <param name="some name" value="some value"> 

The name of the parameter is identified by some name and the value is identified by some value. (The double quote characters surrounding some value are not required if some value is a number.) For example, <param name="image" value="orion.jpg"> specifies a parameter called image with a value set to orion.jpg whereas <param name="age" value=23> specifies a parameter called age with a value set to 23.

If you recall from Table 12.1, the Applet class contains a method called getParameter. This method's String argument corresponds to the value of the NAME attribute in a <PARAM> tag. If a <PARAM> tag exists whose NAME attribute matches this argument, the value of the VALUE attribute is returned. Otherwise, null is returned. For example, using <param name="image" value="orion.jpg">, getParameter ("image") would return orion.jpg, whereas getParameter ("image1") would return null.

To get a feel for parameters, Listing 12.12 shows the source code to a ShowPage applet. When run, this applet causes the Web browser to load a Web page from a server located at the specified URL.

Listing 12.12 The ShowPage Applet Source Code
 // ShowPage.java import java.applet.Applet; import java.net.*; public class ShowPage extends Applet {    public void init ()    {       String defaultURL = "http://www.javajeff.com";       String url = getParameter ("url");       if (url == null)           url = defaultURL;       try       {          getAppletContext ().showDocument (new URL (url));       }       catch (MalformedURLException e)       {          System.out.println ("DEBUG: " + url + " is malformed.");       }    } } 

The init method calls getParameter ("url") to obtain the value of a <PARAM> tag whose name matches url. If not found, null is returned and the default URL is used.

Earlier, you were introduced to the AppletContext interface and the getAppletContext method. (To recap, this method returns an object that implements AppletContext. ) AppletContext 's showDocument method attempts to redirect the applet's Web page to the Web page associated with its URL argument. If this URL is not properly formed, showDocument throws a MalformedURLException object.

Listing 12.13 shows the HTML code for this applet.

Listing 12.13 The ShowPage Applet HTML Code
 <applet code="ShowPage.class" width=0 height=0>   <param name="URL" value="http://www.cnn.com"> </applet> 

Note the value of the <PARAM> tag's NAME attribute: URL. This value is specified in uppercase, whereas the argument passed to getParameter ”url ” is specified in lowercase. This isn't a problem because getParameter treats URL and url as the same parameter.

Applets Versus Applications

Many people associate applets with Java. They see graphical (and possibly audible) applets and conclude that this is what Java is all about. Nothing could be further from the truth. As useful and interesting as applets are, they are by no means all there is to Java. Java applications are just as important as applets. In fact, for many situations, applications are even more important.

When you plan to deploy a JFC-based program, you'll be faced with a major decision: Should this program be deployed as an applet or as an application? Understanding the architectural differences between these program categories can simplify this decision. And knowing how to convert between applications and applets can make this decision seem like child's play.

Architectural Differences

Applications and applets have many differences. Applications are designed as standalone programs, whereas applets are designed to rely exclusively on a Web browser.

Note

Sun's HotJava Web browser is a Java application that's capable of running applets.


Some of the differences between application and applet architectures include the following:

  • An application's main class contains a special static method called main. This main method serves as the execution entry point for applications. Applets do not normally have a main method.

  • When an application starts to run, no application object exists. In contrast, an applet cannot run until an applet object has been created.

  • An applet's main class contains inherited or overridden life cycle methods. These methods are called by the Web browser at various times during an applet's life. Applications have no notion of a life cycle.

  • By default, applications are not subjected to security restrictions, although a security manager can be installed. In contrast, applets are at the "mercy" of a Web browser's security manager. They can only carry out tasks that the security manager allows.

  • Unlike applets, applications do not require an HTML document.

Converting Between Applets and Applications

Due to architectural differences, the task of converting between applets and applications is not trivial. There are many things to think about. To assist you in this undertaking, take a look at the hybrid applet/application that's shown in Listing 12.14.

Listing 12.14 The AppletAndApp Applet Source Code.
 // AppletAndApp.java import java.applet.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.*; public class AppletAndApp extends Applet implements ActionListener {    static AppletAndApp aa;    static Stub s;    Image im;    public void init ()    {       System.out.println ("Code base = " + getCodeBase ());       System.out.println ("Document base = " + getDocumentBase ());       System.out.println ("\ ninit () called");       System.out.println ("isActive () returns " + isActive ());       // Create simple GUI.       Button b = new Button ("Visit CNN");       b.addActionListener (this);       add (b);       b = new Button ("Audio");       b.addActionListener (this);       add (b);       // Obtain an Image object in preparation for loading.       String imageName = getParameter ("image");       if (imageName != null)           im = getImage (getCodeBase (), imageName);    }    public void start ()    {       System.out.println ("start () called");       System.out.println ("isActive () returns " + isActive ());    }    public void paint (Graphics g)    {       // Load and draw an image.       if (im != null)           g.drawImage (im, 0, 0, this);    }    public void actionPerformed (ActionEvent e)    {       if (e.getActionCommand ().equals ("Audio"))       {           String soundName = getParameter ("audio");           if (soundName != null)           {               AudioClip ac = getAudioClip (getDocumentBase (),                                            soundName);               ac.play ();           }           return;       }       try       {           URL u = new URL ("http://www.cnn.com");           getAppletContext ().showDocument (u);       }       catch (MalformedURLException exc) {  System.out.println (e); }    }    public void stop ()    {       System.out.println ("stop () called");       System.out.println ("isActive () returns " + isActive ());    }    public void destroy ()    {       System.out.println ("destroy () called");       System.out.println ("isActive () returns " + isActive ());    }    public static void main (String [] args)    {       Frame frame = new Frame ("AppletAndApp as an Application");       aa = new AppletAndApp ();       frame.add (new Panel ().add (aa));       // Create the frame's peer.  Peer is not visible.       frame.addNotify ();       aa.setStub (s = new Stub (args));       aa.init ();       frame.setSize (300, 200);       frame.setVisible (true);       s.setActive (true);       aa.start ();       frame.addWindowListener (new WindowAdapter ()                                {                                    public void windowClosing                                                        (WindowEvent w)                                    {                                       s.setActive (false);                                       aa.stop ();                                       aa.destroy ();                                       System.exit (0);                                    }                                });    } } // The Stub class provides a mechanism for obtaining information from // the run-time environment. Typically, this environment is maintained // by a Web browser.  For this program, a Web browser environment is // being simulated. class Stub implements AppletStub {    private boolean active = false;    private Hashtable ht = new Hashtable ();    private Context c;    // Create a new Stub object.  The application's array of command    // arguments are passed to this constructor, where they are saved    // in a Hashtable object, for later retrieval by the getParameter    // method.    Stub (String [] args)    {       c = new Context (); // Create an applet context.       // Make sure an even number of arguments has been passed.       if ((args.length & 1) != 0)           return;       for (int i = 0; i < args.length; i += 2)            ht.put (args [i], args [i + 1]);    }    // Return the current state of an applet.  During initialization,    // the applet is not active (and this method returns false).  The    // applet's active state is set to true just before the start    // method is called.    public boolean isActive ()    {       return active;    }    // Return the complete URL of the HTML document containing the    // applet.  This URL includes the name of the document's file.    // NOTE: The code in this method could be improved.    public URL getDocumentBase ()    {       URL u = null;       try       {          u = new URL ("file:///" + (new File (".").getAbsolutePath ()) +                       "/x.html"); // Use a fake document.       }       catch (MalformedURLException e) { }       return u;    }    // Return the complete URL of the applet's .class file(s).  This    // method is often used with the getImage and getAudioClip    // methods to load image/audio files relative to the .class files.    // NOTE: The code in this method could be improved.    public URL getCodeBase ()    {       URL u = null;       try       {           u = new URL ("file:///" + new File (".").getAbsolutePath ());       }       catch (MalformedURLException e) { }       return u;    }    // Return the value of the applet parameter, identified by the    // name argument.  If not present, null is returned.  The Applet    // class contains a getParameter method that calls this method.    public String getParameter (String name)    {       return (String) ht.get (name);    }    // Return a reference to the applet's context.  The Applet class    // contains a getAppletContext method that calls this method.    public AppletContext getAppletContext ()    {       return c; // Return current applet context.    }    // Resize the applet.  The Applet class contains a pair of resize    // methods that call this method. Note: Web browsers don't permit    // applets from being resized.    public void appletResize (int width, int height)    {    }    // The following method is an extra method that is called to set    // the value of the private active variable.    public void setActive (boolean active)    {       this.active = active;    } } // The Context class provides a mechanism to control the environment // in which the program is running.  Typically, this environment is // maintained by a Web browser.  For this program, a Web browser // environment is being simulated. class Context implements AppletContext {    // Load the file located by the url argument.  The Applet    // class contains a pair of getAudioClip methods that call    // this method.    public AudioClip getAudioClip (URL url)    {       return Applet.newAudioClip (url);    }    // Prepare to load the image located by the url argument.  The    // image is loaded when needed (by one of Graphics'drawImage    // methods).  The Applet class contains a pair of getImage    // methods that call this method.    public Image getImage (URL url)    {       Toolkit tk = Toolkit.getDefaultToolkit ();       return tk.getImage (url);    }    // Fetch the Applet (identified by name) from the current HTML    // document.    public Applet getApplet (String name)    {       return null;    }    // Return an enumeration to all Applets located on the current HTML    // page.    public Enumeration getApplets ()    {       return null;    }    // Show the HTML document, located by the url argument, in the    // current Web browser window.    public void showDocument (URL url)    {       System.out.println ("Showing document " + url);    }    // Show the HTML document, located by the url argument, in the    // Web browser window, identified by the frame argument.    public void showDocument (URL url, String frame)    {       try       {          showDocument (new URL (url.toString () + frame));       }       catch (MalformedURLException e) { }    }    // Show a status message, identified by the message argument, in    // the Web browser's status bar.  The Applet class contains a    // showStatus method that calls this method.    public void showStatus (String message)    {       System.out.println (message);    } } 

AppletAndApp is designed to run in one of two modes. It runs in applet mode when run from either a Web browser or the Applet Viewer and it runs in application mode when run from the Java interpreter program.

AppletAndApp consists of three classes: AppletAndApp, Stub, and Context. Apart from the main method and a pair of field variables, all the logic in AppletAndApp is what you would expect from an applet. The Stub and Context classes support this logic when AppletAndApp is run in application mode. (Although functionality has been added to the Stub and Context classes, more work is required.)

If you want to experiment with this applet, you'll need an HTML document ”for use with applet mode. Listing 12.15 shows the HTML code for AppletAndApp.

Listing 12.15 The AppletAndApp Applet HTML Code
 <applet code="AppletAndApp.class" width=300 height=200>   <param name="image" value="shuttle.jpg">   <param name="audio" value="landing.au"> </applet> 

To run AppletAndApp in applet mode, use the Applet Viewer AppletAndApp.html command. However, if you want to run this program in application mode, use java AppletAndApp image shuttle.jpg audio landing.au. (The image and sound files are included with the rest of this book's files.)

Note

When you run this program from Applet Viewer, pressing the button doesn't do anything. However, if you press this button from a Web browser, it takes you to the CNN Web site. (Applet Viewer is not a Web browser for viewing Web pages.)


Figure 12.10 shows AppletAndApp being run as an application.

Figure 12.10. The AppletAndApp program displays an image of the space shuttle, along with a pair of buttons .

graphics/12fig10.gif

When you run AppletAndApp in either mode, you'll notice a curious thing. The isActive method does not always work as expected. In application mode, isActive follows the behavior specified in the SDK documentation. However, in applet mode, this method does not work as advertised: It never seems to return a true value. (This strange behavior appears to be the result of a bug in the Netscape Communicator/Applet Viewer implementation of isActive, although there might be some other reason.)

Note

Further research into the isActive problem has led to the discovery of an entry in Sun's Bug database (located at http://developer.java.sun.com/developer/bugParade/ bugs /4179136.html) for this method. This entry suggests that the SDK documentation should be modified to state "An applet is marked active just AFTER its start method is called. It becomes inactive just before its stop method is called." It would appear that either the documentation or the Netscape Web browser/Applet Viewer code for the isActive method should be changed. I'll leave it up to you to decide how you feel isActive should work in AppletAndApp.


   


Special Edition Using Java 2 Standard Edition
Special Edition Using Java 2, Standard Edition (Special Edition Using...)
ISBN: 0789724685
EAN: 2147483647
Year: 1999
Pages: 353

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net