Previous Page TOC Next Page


— 10 —
Applet Structure and Design

Chapter 9 presented an overview of object-oriented programming and discussed how it applied to Java. The applet is the best example of how object-oriented programming and Java intermix. In terms of functionality, you know that an applet is basically a small, focused application. But what is an applet in terms of programming? An applet is an object class: class java.applet.Applet.

The idea behind applets being objects is really quite simple. An applet as an object inherits the properties of its parent object, the applet template. If you look at the class hierarchy for Java ( see Figure 10.1), you can see how inheritance works to your advantage when programming applets. OOP becomes a practical implementation rather than just theory.


Figure 10.1. The Java class hierarchy.

Take a look at the first line in the HelloWorld applet from Chapter 7:

public class HelloWorld extends java.applet.Applet {

This line establishes the HelloWorld applet. Notice, however, that after the class HelloWorld is declared, the line says extends java.applet.Applet. This phrase is how you specify that your applet is based on the original applet class and therefore will receive all the functionality of that class, which is quite a bit.

This chapter discusses the practical elements of building an applet. This chapter also discusses some of the more advanced programming topics, such as the methods and classes that make up the Java language. By the end of the chapter, you should have a better understanding of how applets are constructed and should finish your second applet, the Speaker applet.

The Applet Package

As you begin to program with Java, you will find that the language has an structure designed around the idea of objects. In keeping with this design strategy, many methods that perform similar functions have been grouped together in packages. For example, the Abstract Window Toolkit as a package of methods that are useful for drawing images on the screen, working with windows, and building user interfaces. The Applet Package is a package that is specifically designed for working with applets.

The Applet Package contains a number of methods that are designed to be used in the construction of applets and in the special circumstances that arise with applets. For example, applets need to be able to load images and audio clips from a server, so the methods getImage() and getAudioClip() are part of the Applet Package.

The Applet Package contains a number of useful methods. As you begin to program your own applets, you will use a number of them to control the applet and its characteristics. Table 10.1 is a summary of the most useful methods in the Applet Package. Remember that you can find the full documentation for the Applet Package on the Javasoft Web site athttp://www.javasoft.com.

Method


Function


public String getAppletInfo()

Returns information about the applet, such as author

public URL getDocumentBase()

Returns the URL of the HTML document

public String getParameter(String name)

Returns the parameters for an applet

public String [][] getParameterInfo()

Returns a summary of what the parameters control

public AudioClip getAudioClip(URL)

Used to load an audio clip

public Image getImage(URL)

Used to load an image file

public void play(URL)

Used to play a previously loaded audio clip

public boolean isActive()

Lets you know whether an applet is active

public void resize(int, int)

Used to resize the applet

public void showStatus(String msg)

Displays a status string in the applet's browser

public void init()

Initializes the applet

public void start()

Starts the applet when it's finished initializing

public void stop()

Stops the applet when you leave the applet's page

public void destroy()

Destroys the applet when you leave the browser

Some of the methods in the Applet Package seem pretty self- explanatory, such as getImage(URL). The getImage() method does just what you would think it would do; it enables you to get an image from the applet's server. The following sections describe a few of the methods in the Applet Package and how they are used.


Reading the API Documentation

As you begin to use the methods in any of the Java packages, you will find that the API documentation is invaluable for showing how those methods are used and what they do. The API does a fair job of explaining the methods, but it is a document written for programmers, so making sense of the API documentation takes some work.

You can find the API documentation at the following URL:

http://www.javasoft.com/JDK-1.0/api/packages.html

This documentation is a general index to all the packages that are part of the Application Programming Interface. You will find a listing of all the packages that contain Java methods, and you can go to specific package documentation. Don't worry about all the packages that you see listed. In general, the ones you will use most often are described in the following list:


When you look up methods in the API documentation, they are listed in the following formats:

getImage(URL, String)

or

public Image getImage(URL)

The name of the method is getImage(), which is also the text you would place in your code to use this method. The terms inside the parentheses are the arguments accepted by the method. The arguments are the information the method needs to perform its task. In this case, getImage() requires both a URL and a string in order to work properly. The URL gives the location of the image files on the server, and the string is the name of the image file. In the second listing example, the words public Image indicate the type of information that is returned by this method. In the case of getImage(), the returned information is a public class, Image. You might also notice something like the following:

public void init()

In this case, the return type for this method is void, which means that the method returns no data at all, it simply performs a task.

A method that doesn't contain anything inside the parentheses, such as

getDocumentBase()

does not require any arguments, but still returns a value. The getDocumentBase() method, for example, returns the URL of the current applet.

The API is the best authority on what methods do and how they are used. So if you have questions about a method, the first place you should look is the API. Now that you can make a little better sense of how information there is organized, you should be able to use the API to your advantage.

getDocumentBase()

Although the getDocumentBase() method simply returns the URL of the document your applet is embedded in, this URL comes in very handy with other methods. For example, the methods discussed in the next two sections take a URL as one of their arguments. Instead of hard coding a URL, you can use the getDocumentBase() method to pass the URL to any methods that require a URL, such as getAudioClip() and getImage(), as in the following example:

graphic = getParameter("graphic");

clip = getParameter("clip");

image = getImage(getDocumentBase(), graphic);

sound = getAudioClip(getDocumentBase(), clip);

getAudioClip(URL, String)

The getAudioClip() method accepts a URL, which specifies the location of sound files on the server, and a string to represent the name of the file. Keep in mind that you can use the getDocumentBase() method to provide the URL, so if you move your applet, you don't have to recode the getAudioClip() method. If you wanted to load an audio file called soundfile.au, you could use the following code:

AudioClip clip;

clip = getAudioClip(getDocumentBase(), "soundfile.au");

This code just defines a variable called clip for the audio file and then makes clip equal to the result of the getAudioClip() method. The getAudioClip() method uses the getDocumentBase() method to supply the URL, and then you give the getAudioClip() method the name of the sound file directly. You could also use a variable for the name of the sound file, which would make the filename a little more flexible.

Audio methods are contained with the Applet Package within the AudioClip interface. An interface is a specification the ensures that certain methods will be defined for a class. For example, the AudioClip interface ensures that the getAudioClip(), play(), and loop() methods will be defined. Table 10.2 summarizes the available audio methods.

Method


Function


getAudioClip()

Loads an audio file from the server

play()

Plays the audio file once through

loop()

Plays the audio file in a continuous loop

stop()

Stops a play() or loop() method that is in progress

getImage(URL, String)

The getImage() method functions identically to getAudioClip(), but it enables you to retrieve an image file rather than a sound file. The image files can be in GIF or JPEG format, and you must first declare an Image variable, with something like the following code:

Image picture;

The preceding code defines an Image variable called picture that you can then load an image file into. As with any method that takes a URL, you can use getDocumentBase() to pass the URL to make your applet more flexible. Because of the nature of image-processing methods, all the image methods are in the AWT except for getImage().

Applet Lifecycles

The Applet Package contains a few methods that have some very special functions. These methods, called the lifecycle methods, control how an applet behaves during the course of execution.

When you load a Web page that contains an applet, the applet goes through several stages during the time you see it on-screen. During each of these stages, the applet performs very different tasks, although most of these tasks are invisible to the end-user. These stages are initialization, running, and exiting.

During the initialization stage, the applet is loading the images, sound clips, and other resources that it needs to run. Sometimes the applet displays messages such as Loading Images. . .to inform you of what might be going on behind the scenes and why you are waiting. When the applet has all the resources it needs to run, the initialization stage is over, and the applet is ready to run.

When the applet is running, it is performing whatever tasks it has been designed to perform. Conversely, when an applet is not running, it is just sitting idle, waiting for a user to re-enter the Web page. For example, a TickerTape applet that scrolls text across the screen would load the text during the initialization stage, and then start scrolling the text when the applet began to run. Because applets start and stop when you enter and leave a Web page, running consists of two distinct states, starting and stopping. These states could really be thought of as two separate stages, and in fact, each has a corresponding lifecycle method. You can control what an applet does during both starting and stopping.

Because applets are loaded into your machine's memory and use CPU time, you wouldn't want the applet to remain in memory once you've left the Web browser. During the final exiting stage, the Java Virtual Machine completes some garbage collecting functions, making sure that the resources the applet used are removed from memory and that the applet is completely destroyed when you quit.

Breaking up applets into these stages has some very distinct advantages. For example, if you were writing an animator that used a large number of images, you would want to make sure the images were loaded before the applet started running. Otherwise, your animation might seem jerky or have frames missing. Manipulating these stages can come in handy, and fortunately the Applet Package contains methods to do just that.

The Applet Package has four lifecycle methods, each of which corresponds directly to the stages of an applet. Figure 10.2 shows how these cycles relate to each other and an applet.

Figure 10.2. The applet lifecycle methods.

Each of these methods is automatically called as the applet loads, runs, and exits, so you might not always use each of these methods in your own applets. Also, you only need to use these methods if you need something specific to occur during a particular stage, like stopping a sound when you leave the page. Often, you will use one or two lifecycle methods, but not all of them. The decision to use a lifecycle method depends largely on what you are trying to do with your applet. You will find that init(), start(), and stop() are all used fairly commonly because these stages each have practical implications for applets. You want to make sure images and sounds load first, you want to make sure sounds stop playing, and so on. Evaluating the need to use one of these methods is a part of the planning process when writing your applets.

init()

The first method called by an applet once it has been loaded by the browser is init(). Because the applet is not running when init() is called, this method is an excellent place to take care of any groundwork that must be laid for the applet to carry out its goals. Some good tasks to take care of during init() include loading images or establishing the user interface. Take, for example, an applet that plays an audio clip at the click of a button. In such an applet, you would need to load the audio clip and set up the button before the applet began to run. You would use the following code to do these tasks:

public void init() {

    clip = getAudioClip(getDocumentBase(), soundfile.au);

    setLayout(new FlowLayout());

    play = new Button("Play Clip");

    add(play);

    } 

This code defines a new audio clip, called clip, and uses another method from the Applet Package, getAudioClip(), to load the audio clip from the server. It then sets up a Play button using some methods for user interface layout in the Abstract Window Toolkit. (Chapter 11 discusses the AWT in more detail.). Now when the applet is loaded into the browser, it establishes the Play button and downloads the audio clip to prepare the applet to play the clip.

start()

After the applet has been loaded into the browser and is ready to begin, the start() method is called automatically. The start() method generally contains the meat of your applets. After all, this method is what you want the applet to do. In most applets, you will define the init() and start() methods. For example, in an applet that plays an audio clip defined as clip, you might have a start() method that looks like the following:

public void start() {

     

        clip.play();

}

Quite simply, this code tells the applet to play the clip sound as soon as it is loaded. You can put any kind of code in the start() method; you could draw images, play sounds, and accept user input, essentially any of the functions you might expect a program to perform.

stop()

The stop() method is the counterpart to the start() method. It is called automatically when an applet should stop execution, when you leave an applet's Web page for example. If you use the start() method to start some functions that need to be stopped before the user moves on, you stop them with the stop() method. For example, if your applet plays a sound file, you would want to make sure the sound file didn't keep playing when someone left the page. You can use the stop() method to stop a sound file that is playing in a loop or to stop any threads that might be executing when the user moves on. A thread is another piece of code outside of the main program that is executed simultaneously with the main program. You can think of threads as an applet within an applet. The following example shows how you could use the stop() method to suspend a playing audio clip:

public void stop() {

        clip.stop();

}

You don't necessarily have to redefine the stop() method in all your applets. If an applet is simple enough, you could let the stop() method automatically terminate any methods that might be running. But if you have any sounds playing, or especially if you have any threads running, it is a good idea to invoke the stop() method on your own to keep your applet under control. For example, if you don't stop an active thread, it may interfere with other applets or cause other strange problems with your machine, such as poor performance.

destroy()

The destroy() method is essentially the death of an applet. When you leave your browser, this method is called automatically to do any cleanup that might be necessary. Just as the name would imply, the destroy() method eliminates any trace of your applet. It purges any memory that was used by your applet, and it stops any running threads or methods. Generally speaking, you do not have to do anything to use the destroy() method, a base destroy() method is predefined and automatically called, so all you have to do is sit back and let it do the dirty work.

Building an Applet

So are you ready to build an applet? You now have all the tools you need to build an applet that you can add to your home pages. This section uses a simple applet, the Speaker applet, to demonstrate the structure of applets.

The Speaker applet is a very straightforward applet that enables you to place an image on the screen and play a sound file at the same time (see Figure 10.3). This applet is a good way to see how the various components from various packages fit together and how a complete applet is constructed.

Figure 10.3. The Speaker applet displays an image and plays a sound file.

An applet is a compiled program based on the source code that you run through the compiler, as discussed in Chapter 7. If you remember, your applet code has to be called something.java in order for it to be compiled correctly, and the resulting file is called something.class. These extensions help you distinguish between code and compiled applets, but they also contribute to class structure. This naming system is yet another result of Java's object-oriented nature. Every applet can function as an object and therefore needs to be structured so that it can be used as an object. That is why a compiled applet has a name in the form of something.class. The .class extension lets the Java compiler know that the information contained in that file is a class definition. That way, if you wanted to include your applet within another applet, you could use it just as you would any other class in the Java language because the compiler would recognize it. Although this system does put some minor restrictions on naming, it is to the benefit of the entire language.

Take look at the first section of code in the Speaker applet:

/*  Speaker

    This Applet displays a gif or jpeg while playing a sound (.au) file.

*/

import java.awt.*;

import java.applet.*;

import java.lang.*;

import java.net.URL;

public class Speaker extends java.applet.Applet {

}

The code starts off with a comment that provides a name and a brief description of what the applet does. It's always a good idea to put some comments in your code so that if you pass it on to others, they can understand it better, or if you need to come back to the code at a later date, you have a refresher.

Next, notice a series of statements in the form of import java.awt.*; These import statements enables you to use methods from various packages within your applet. Remember that different methods in Java are broken up into packages, and you need to tell the compiler what packages you will be using. By using import statements, you can use the entire package with a statement like import java.awt.*; or a single method from a package, such as import java.net.URL;. Generally, if you are only going to use one method from a package, as is the case with URL in the Speaker applet, you can name the method explicitly. However, if you are going to use many methods, you can use the wildcard * to specify the whole package, so you don't have to keep a long list of methods at the beginning of your code.

After instructing the compiler of all the packages you want to include in your applet, you need to set up the applet class itself with the following line:

public class Speaker extends java.applet.Applet {

}

This line states that you want a public class called Speaker that is going to be an extension of the Applet class. Because you've chosen the name Speaker for your class in this definition, the file that you store this applet in will have to be called Speaker.java. Now the naming conventions become a little clearer; you have an applet, class Speaker, in a file called Speaker.java. When it is compiled, the applet will be called Speaker.class. This name allows the compiler to keep track of the new applet as if it were just another class, and find everything by its name. If you try to change the names around, you will probably run into compiling problems. That's the basic framework for your first applet. Now everything that you want the applet to do will need to be added in between the two brackets {}.

You need to declare the variables that you will need to use in this applet. For this applet, you need three types of: Image, AudioClip, and String. Image and AudioClip are very straightforward; these types are the image you display and the audio clip you play. The Strings will be used so that you can set up parameters to allow the user of your applet to change the image and sound file with parameters, without editing the code:

public class Speaker extends java.applet.Applet {

    Image image;

    AudioClip sound;

    String graphic, clip;

}

So now you've told the compiler that you need an Image type called image, an AudioClip type called sound, and two Strings, graphic and clip, which you will use for your parameters.

Parameters

Chapter 6 talks about the HTML <PARAM> tag that allows the user to pass parameters to an applet with the HTML file. Now you are building an applet that could use parameters to add flexibility. Because this applet shows an image and plays a sound file, you could assume that users would want to be able to change the image and the sound file. Otherwise, the applet wouldn't be useful on any pages but your own. So for this applet, you are going to allow the user to specify the graphic and clip parameters.

Applets use parameters by using some special methods to get the parameters from the HTML file, and then assigning values to the parameters based on the information the file provides. You can then use that information in your applet, say in place of an image file name, so that your applet is flexible. The following code establishes the parameters:

public String[][] getParameterInfo() {

    String[][] info = {

        {"graphic",    "string",    "The image file to be displayed."},

        {"clip",       "string",    "The sound file to be played."},

    };

return info;

}

This code is pretty standard for establishing variables. It basically establishes an array that will contain the name of each parameter, what type of parameter it is, and an information string that describes that parameter. For example, the following code defines a parameter that will be called clip, which is a string (the filename of the sound file) and a description of what that parameter controls:

{"clip",    "string",    "The sound file to be played."},

The name of this parameter is the same as the variable clip you declared as a string earlier. Keep in mind that you can use any valid data type here, such as int or float. For example, you could have used the following code to establish a volume parameter that would be an integer number:

{"volume",    "int",    "The volume of the sound from 1-10"},

Parameters can be as flexible and as detailed as you want, but remember that each parameter should perform a specific function in your applet to make it easier to use, not harder.

So now that you've established these parameters, look at how they are used in the applet code:

public void init() {

    graphic = getParameter("graphic");

    clip = getParameter("clip");

    image = getImage(getDocumentBase(), graphic);

    sound = getAudioClip(getDocumentBase(), clip);

}

You can use the init() method to put your parameters into action before your applet fires up. This amounts to a two-step process:

  1. Read the parameter information into your variable.

  2. Use the variable to get your support files.

In the code, you use the getParameter() function to get the value of the parameter from the HTML file:

graphic = getParameter("graphic");

clip = getParameter("clip");

Now the graphic variable is the same as the graphic parameter string. This might seem a bit confusing, but what you are doing is using the getParameter() function to read the HTML file and look for a tag in the following form:

<param name=graphic value="image.gif"> 

The getParameter() function then returns the filename image.gif to your applet, where it is assigned to the graphic variable. Now if you use the graphic variable anywhere in your program, it will be as if you were using image.gif.

So now you have the filenames you need for the image and sound. Now you need to load the image and sound into memory so you can display and play them. Assign the information to your image and sound variables. Keep in mind that up to this point you've only been dealing with the String data type. That's because you haven't been manipulating any files, only the filenames. Now you are ready to use the Image and AudioClip data types to read in the actual files themselves, and then use them in your applet.

The following lines use two methods from the Applet Package, getImage() and getAudioClip(), to read the files into memory:

image = getImage(getDocumentBase(), graphic);

sound = getAudioClip(getDocumentBase(), clip);

If you recall these methods from before, you need to give them a URL for the file and the name of the file. So when you call these methods, substitute getDocumentBase() for the URL and your parameter variables for the filename. Now you have your files in memory and are ready to finish off your applet!

Finishing the Applet

Most of the work in this applet is in the preparation. The code used to complete the applet is pretty small, but it does quite a bit. This code can be broken down into three sections. First, you need to refine the method for painting the applet on-screen. Then you need to display the image and play the sound. And last, you need to make sure your sound stops if the person leaves your page.

To get the image onto the screen, you need to redefine the paint() method that Java provides for you with the following code:

public void paint(Graphics g) {

            g.drawImage(image, 0, 0, this);

}

All you are doing in this code is letting the compiler know that if you use the paint() method, you want it to draw your image on the screen. You start out declaring the paint() method and setting a context (Graphics g) in which this method will perform its task.

The next line of the code uses the g. before drawImage to specify what graphics context (in this case g) you specified earlier. A context specifies where you want these graphics methods to perform their tasks. By providing paint() with the graphics context g, you then need to specify that graphics methods use that context when they are called. Then you let the applet know that you want it to draw image (your image variable) at the coordinates 0,0 . The this at the end of the method specifies a special interface called an image observer. The image observer monitors the image to make sure there aren't any special problems with the image, such as an incomplete file. The keyword this refers to this image observer, as opposed to an image observer defined elsewhere.

Now you are ready to finish off the applet. When the applet is ready to start, you want to draw the image on-screen and play the sound file, so you define the start() method as follows:

public void start() {

    repaint();

    sound.play();

}

The method used to display the image on-screen is a bit odd. Even though you just redefined the paint() method to draw your image on-screen instead of calling the paint() method directly, the code calls the repaint() method. The repaint() method calls the new paint() method, so the end result is the same. This roundabout way of doing things is largely attributed to some quirks in the Java language.

This example also uses the play() method, in the form of sound.play(), to play the audio file. This method is similar in function to the g.drawImage line. The sound.play() method just lets the play() method know what sound file to play, just as the g. lets drawImage know what graphics context to use.

Now that you have your start() method, which displays your image and plays an audio file, it might be a good idea to have a stop() method:

public void stop() {

    sound.stop();

}

The stop() method just makes sure that your sound file stops playing if the user should leave your page. Obviously, if a user leaves the page, the image will vanish, so you don't need to worry about stopping its display.

Putting It All Together

Now you have all the pieces for a completed applet. Your applet fits the following structure:

  1. Comment information, such as author and revision dates

  2. Any import statements to utilize other classes

  3. The Applet class definition, which includes the following:

  4. Variable declarations

  5. Parameter information

  6. The init() method, which defines variables and loads support files

  7. The redefined paint() method

  8. The start() method to perform the applet's tasks

  9. A stop() method to make sure the applet stops properly

Listing 10.1 has the complete code for the applet.

/*    Speaker

    This Applet displays a gif or jpeg while playing a sound (.au) file.

*/

import java.awt.*;

import java.applet.*;

import java.lang.*;

import java.net.URL;

public class Speaker extends java.applet.Applet {

    Image image;

    AudioClip sound;

    String graphic, clip;

    public String[][] getParameterInfo() {

        String[][] info = {

            {"graphic",    "string",    "The image file to be displayed."},

            {"clip",    "string",    "The sound file to be played."},

        };

    return info;

    }

    public void init() {

        graphic = getParameter("graphic");

        clip = getParameter("clip");

        image = getImage(getDocumentBase(), graphic);

        sound = getAudioClip(getDocumentBase(), clip);

    }

    public void paint(Graphics g) {

                g.drawImage(image, 0, 0, this);

        }

    public void start() {

        repaint();

        // This could also be sound.loop(); to loop the sound.

        sound.play();

    }

    public void stop() {

        sound.stop();

    }

}

The HTML file for the Speaker applet contains the following code:

<html>

<applet code=Speaker.class width=100 height=150> 

<param name="graphic" Value="me.gif"> 

<param name="clip" Value="hi.au"> 

</applet> 

</html>

You can now compile this code by using the javac compiler to produce an applet called Speaker.java. You can view this applet using the appletviewer or add it to a Web page.

Summary

This chapter has shown the basic structure of an applet. The Speaker applet is a simple applet, but it does contain many of the basic structure elements that you will find in many applets. All applets contain import statements, variable declarations, and a class structure. Most applets also use parameters to some extent. But there are still many things that this applet doesn't do; it doesn't deal with user input, for example.

The Speaker applet is a good starting point and illustrates the basics of applet construction in the context of a working applet. As you begin to program applets, you will be surprised how common some of these elements are. For example, the parameter code used in this chapter does not usually vary much from applet to applet, and the techniques for assigning variables, using getImage(), and so forth are the same in any applet. These methods provide a solid foundation for more advanced applets, and having a firm grasp of the basics will help you as your applets become more advanced.

Now you are ready to move on to some more functional applets. Chapter 11 discusses some of the issues surrounding user interfaces and how to use the tools in the Abstract Window Toolkit to create user interfaces for your applets. Then you'll have all the tools to create fully functional applets. In Chapters 12 and 13, you will develop a TickerTape applet and a SlideShow applet to understand how some real-world applets function. These chapters also discuss issues of application development in more detail.

Previous Page TOC Next Page