Chapter 14
Writing an Applet

by Joseph Weber

In the beginning there was FTP, and then came Telnet, and years later Telnet begot the Web. The Web was static and without life, until there came CGI, but CGI required a submit button and whole new pages to be downloaded, and the world saw that this was not good. Then a few visionaries saw a product called Oak lying in the ashes and, like a phoenix, they resurrected it to make the Web dynamic and client-server, and they renamed this product and called it Java with children they called Applets. The world paused and saw that it was good.

If you're new to Java, one of the things you're probably dying to learn how to do is write applets. Applets are those Java programs you have seen running all over the World Wide Web. They provide a fascinating layer on top of the already dynamic Java language which extends far beyond traditional programming architecture and methodology. When you write an applet you create a program that can not only be run on just about any computer but also can be included in a standard HTML page. Now that you've learned the Java language, you are no doubt excited and jumping to start creating applets, those dynamic creatures you see all over the Internet. In this chapter you will learn to apply your new knowledge toward writing Java applets.

Applets and HTML

Because you're interested in writing Java applets, you're probably already pretty familiar with using HTML (Hypertext Markup Language) to create Web pages. If not, it's probably not a bad idea to pick up a book on HTML such as Que's Special Edition Using HTML to get some idea of how that markup language actually works.

As you now know, Java can be used to create two types of programs: applets and stand-alone applications. An applet must be included as part of a Web page, like an image or a line of text. When your Java-capable Web browser loads an HTML document containing a reference to an applet, the applet is also loaded and executed. (See Chapter 1, "What Java Can Do for You," for more information.)

Quickly review how an applet's code comes to run on your computer. When the browser detects an <Applet> tag in an HTML file, it will retrieve the class files for the applet from the server. The bytecode verifier then determines if the class is a legitimate one. Assuming that it is, it will start to process the class file. As the VM detects import statements, it will continue to go back to the server for more class files until it has managed to download all of the code for the applet. For a visual depiction of this cycle, see Figure 14.1.

FIG. 14.1
The bytecode verifier will continue to return to the server until all of the applet code has been downloaded.

Including a Java Applet in an HTML Page

If your primary goal with this chapter is to be able to display the "Java Compliant" logo on your pages, this section is for you. The simplest means to obtain a Java applet is to obtain one that has already been built, or that you contract to have built for you. If you have not had time to read the rest of this book and learn to program in Java yourself, this is probably the direction you will take. Look at how to include a simple applet from MagnaStar, Inc. called Muncher. You can obtain a copy of Muncher from:

http://www.magnastar.com/applets/games/muncher

FIG. 14.2
Muncher is a shareware applet available on the Internet.

Look at how to include Muncher in a Web page. Listing 14.1 shows the simplest version of an HTML file which could be used to display Muncher.

Listing 14.1An HTML File Which Includes the Muncher Applet

<HTML>
<BODY>
<APPLET  CODE="gobLoader.class" height=0 width=0></APPLET>
</BODY>
</HTML>

Notice the new <APPLET> tag on the third line. The <APPLET> tag is used to indicate to the browser you would like it to include an applet on your page. In many ways the <APPLET> tag is very similar to the <IMG> tag. There are three key attributes to notice about the <APPLET> tag: CODE, HEIGHT, and WIDTH.


NOTE: Like most HTML tags, the <APPLET> tag is mostly case-insensitive. In other words, all three of the following tags perform the same thing:

<APPLET  CODE="gobLoader.class" height=0 width=0></APPLET>
<Applet  code="gobLoader.class" HEIGHT=0 WIDTH=0></Applet>
<apPlEt  cOdE="gobLoader.class" height=0 width=0></ApPlET>


However, there is an important distinction that needs to be made. While the<APPLET> tag itself is case-insensitive, its attribute values are not. This means that you cannot enter gobLoader as gobloader or GOBLOADER.


The first attribute of the <APPLET> tag is the CODE statement. The CODE value of <APPLET> is very similar to the SRC value of <IMG>. In the case of <APPLET>, the CODE value must be set to the name of the main class file of the applet. In the case of Gobbler there are a number of classes, but the only one you should include in the HTML file is gobLoader.class. This is very important to realize; including the wrong class name can cause some strange and disastrous problems. It's also important to remember that having a CODE value is a required portion of an <APPLET> tag, unless an alternative OBJECT attribute is not present.


NOTE: Most applets come with either a description of which class file to include, or an example HTML file you can look at to find this answer. Alternatively, the class name is the one thing you can see when viewing the HTML document source on another site.


The second and third attributes to notice are the HEIGHT and WIDTH attributes. These are identical to those in the <IMG> tag. There is one unique thing about an applet, though, that is not exactly the same as an image. Some applets, such as Muncher, don't actually take up any space on the Web page. Instead they create their own window. This means that the size should be set to 0. In addition, unlike images for almost all applets, the HEIGHT and WIDTH attributes should be set. With images, if you do not specify the height and width, the browser can figure them out on its own eventually. With applets this is usually not the case.

The final thing to notice about the <APPLET> tag is the closing </APPLET> tag. The ending tag is required for an applet. In addition, as you will see in Listing 14.3, since the <APPLET> tag does not have an ALT attribute like <IMG>, the space before the </APPLET> tag can be used to include alternate information.

Including Alternative Information

Look at Listing 14.2, which shows a more complete version of the HTML for Gobbler:

Listing 14.2An HTML File Which Includes an Applet Plus Alternative Information for Non-Java Browsers

<HTML>
<BODY>
<applet code="gobLoader.class" height=0 width=0>
Warning: You are not using a Java browser.  There is an applet on this page you cannot see.
If you had a Java-enabled browser you would see something similar to the picture below<br>
<img src="gobbler.gif" alt="Game Picture">
</applet>
</BODY>
</HTML>

As you can see, you can include any standard HTML between the <APPLET> and </APPLET> tag. A non-Java browser will ignore the <APPLET> tag and only read this information.

The <PARAM> Tag
Java applets have added one additional tag in addition to <APPLET>. This HTML tag is <PARAM>. Many applets use the parameter tag to specify additional information about the applet's behavior. Take a look at another applet which does this. GrayButton, also from MagnaStar, Inc., provides a simple means of adding some interaction to your Web pages (see Figure 14.3).

FIG. 14.3
The GrayButton applet is used on this page to provide some limited interaction.

You can obtain GrayButton from:

http://www.magnastar.com/applets/misc/gray

The complete listing for including GrayButton on your Web page is shown in Listing 14.3.

Listing 14.3An HTML File for an Applet Which Uses <PARAM> Tags

<HTML>
<BODY>
<APPLET CODE="gray.class"  WIDTH=300 HEIGHT=300>
<PARAM NAME="graphic" VALUE ="http://www.magnastar.com/NOW.GIF">
<PARAM NAME ="link" VALUE="http://www.magnastar.com/GrayButton/license.html">
<A HREF="license.html"><IMG SRC="NOW.GIF"></a>
</APPLET>
</BODY>
</HTML>

This example demonstrates two important things. First note the <PARAM> tags on lines 4 and 5. To get this applet to run, you must specify a graphic for it to load and a place for it to link to if the user clicks that button. Take a look at the syntax for the <PARAM> tag.

The <PARAM> tag must be included between the <APPLET> and the </APPLET> tags. A <PARAM> tag anywhere else has no point of reference and so the browser ignores it.

In general, the <PARAM> tag has two attributes of its own: NAME and VALUE. The NAME attribute is used to specify which parameter you are setting. In the case of the GrayButton, there are two NAMEs that must set, "graphic" and "link".

The second attribute of the <PARAM> tag is VALUE. The VALUE attribute is used to dictate the VALUE which should be associated with the NAME. The VALUE does not have to be a string, although both of them with GrayButton are. The VALUE could easily be a number if the applet called for that type of data.


NOTE: In addition to the <PARAM> tags, the example in Listing 14.3 also shows the use of an image link before the </APPLET>. This is another example of an alternative display. If the viewer does not have a Java-enabled browser, the graphic will be displayed instead. In the case of GrayButton, this works out especially nice, since the only thing that is lost without a Java browser is the level of interaction.


Additional <APPLET> Attributes

In addition to the attributes already mentioned, there are several additional attribute values you can use to further customize how an applet will behave, as shown in Table 14.1 below.
Table 14.1 Attributes for the <APPLET> Tag
Attribute Value Description
*Code class name Defines the name of the class file which extends java.applet.Applet.
^Height number Height in pixels the applet occupies vertically on the Web page.
^Width number Width in pixels that the applet occupies horizontally on the Web page.
Vspace number Vertical space in pixels between the applet and the rest of the HTML. Behaves identically to the Vspace value of an <IMG> tag.
HSpace number Horizontal space in pixels between the applet and the rest of the HTML. Behaves identically to the HSpace value of an <IMG> tag.
ALIGN any of: left, right, top, texttop, middle, absmiddle, baseline, bottom, absbottom Indicates the alignment of the applet in relationship to the rest of the page. These values work the same as their <IMG> 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 utilized if the browser understands the <Applet> tag, but is unable to display the applet. Otherwise the open HTML between the <Applet> and </Applet> tags is displayed.
Archives archive list Contains a list of archives and other resources that should be "preloaded" by the browser before it begins execution.
OBJECT serialized applet Contains the name of the file which has a serialized representation of the applet. The init() method of the applet is not called since it is presumed to have been called on the serialized applet, however the start() method is.
Note: If an OBJECT attribute is present, a CODE attribute need not be; however, one or the other is required.
CodeBase URL URL of base directory where the class files for the applet are located (under the security manager). This host, and the host where the HTML with the <Applet> tag is located, are the only hosts which can be accessed by the applet.
* - required
^ - highly recommended


To sum up, look at Listing 14.4. The text in normal characters is typed literally; the text shown in italics is replaced by whatever is appropriate for the applet you're including in the document. The first and last lines are required. Other lines in the tag are optional. Figure 14.4 shows how attributes can affect an applet's placement.

FIG. 14.4
As you look at this figure, you can see how the various attributes affect the applet's placement.

Listing 14.4LST14_04.TXT--The <applet> Tag

<applet attributes>
parameters
alternate-content
</applet>

Begin Developing Java Applets

Now that you have explored how to include an applet in an HTML page, take a look at how to write some of your own.

Many years ago two programming visionaries named Kernie and Richie invented a language called C. The first program they wrote was called Hello World. Since that time the first program that any programmer writes in any language simply displays "Hello World" to the screen. So, take a look at how to write the Hello World applet in Java.

In the previous several chapters you have talked about each of the parts of the HelloWorld application, but just for review, go through it one more time, as shown in Listing 14.5

Listing 14.5HelloWorld as an Applet

import java.applet.Applet;
import java.awt.Graphics;
/*
 *
 * HelloWorld
 *
 */
public class HelloWorld extends Applet {
     public void paint (Graphics g){
          g.drawString ("HelloWorld",5,20);
     }
}

In order to create the HelloWorld applet, copy the contents of Listing 14.5 into a file called HelloWorld.java. It is very important that you call the file HelloWorld.java or you will be unable to compile the program. Now, assuming you have installed the JDK from Sun and installed it in your path, compile the program by typing the following at a command prompt:

javac HelloWorld.java


NOTE: Windows users, in order for this to work you will need to open a DOS prompt window.




If everything has worked correctly, you should now have an additional file in your directory called HelloWorld.class. This file is the Java equivalent of an .exe file. Before you can run the applet, though, you will need to create an HTML file as discussed in the previous section. In the case of the HelloWorld applet, the HTML file should look like Listing 14.6.


NOTE: Technically, the class file is not an executable file by itself. In fact, several vendors such as Asymetric's SuperSced. have begun releasing native compilers for Java which actually produce .exe files.


Listing 14.6An HTML File for the "HelloWorld" Applet

<HTML>
<BODY>
<APPLET code="HelloWorld.class" HEIGHT=100 WIDTH=100></APPLET>
</BODY>
</HTML>

Once you have created the HTML file, you can open it in a browser like Netscape Navigator, or utilize one of the tools that come with the JDK called appletviewer. Figure 14.5 shows what happens when you load this file in Netscape.

Notice that when a Java applet is loaded, the Navigator has to go back to the server (or in this case, your hard drive) to download the HelloWorld.class file before it can be run. This is done exactly the same way that a GIF file is grabbed for an image, but it does take an extra second or two.

FIG. 14.5
HelloWorld displays some text on the browser.

Understanding "HelloWorld"--Building Applets

Now, go back and break down the code in the HelloWorld applet, so you can understand it.

The first thing that you should have noticed is that HelloWorld extends java.applet.Applet. Every applet in the world must extend applet. As you can see, you take advantage of object-oriented programming (OOP) inheritance to declare your applet class by subclassing Java's Applet class. For more information on inheritance, check out Chapter 11, "Classes."


NOTE: The reason it is necessary to extend applet is because every browser expects to receive an applet class from the CODE= attribute. By using the polymorphic characteristics of inher-itance, your customapplet, such as HelloWorld, is both a HelloWorld class and an applet class so it can fulfill this requirement.


Exploring the Life Cycle of an Applet

It may surprise you to learn that an applet actually has a life cycle. What does this mean? It means that throughout the time that an applet exists, certain methods will be called on that applet. To be precise, there are four methods which are called in on an applet:

init()--Called the first time that an applet is loaded

start()
--Called after the init() method, and thereafter each time a browser returns to a page on which the applet is contained

stop()
--Called any time that a browser leaves a Web page containing the applet

destroy()
--Called before a browser completely shuts down


Figure 14.6 shows the life cycle of an applet. To better understand how the life cycle of an applet works, take a look at a program designed to show when these methods are called. Listing 14.7 contains a program that prints out a message each time one of the methods is called, and puts up a graph of this activity.

FIG. 14.6
A visual representation of the life cycle of an applet is shown here.

Listing 14.7InitStartStop Applet, an Applet Which Demonstrates the Use of the Life Cycle Methods

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

/*
 *
 * InitStartStop
 *
 */
public class InitStartStop extends Applet{
     int initCount = 0;
     int startCount = 0;
     int stopCount = 0; 
     int destroyCount = 0;

     public void paint (Graphics g){
          //clear the area
          g.setColor(Color.white);
          g.fillRect(0,0,size().width,size().height);
          //paint all the standard parts of the graph
          g.setColor (Color.red);
          g.drawLine (120,20,120,220);
          g.drawLine (120,220,300,220);
          //draw the labels
          g.setColor (Color.gray);
          g.drawString ( "Init Count", 5,50);
          g.drawString ( "Start Count", 5,100);
          g.drawString ( "Stop Count", 5,150);
          g.drawString ( "Destroy Count", 5,200);
          //paint the grid lines
          g.setColor(Color.lightGray);
          for (int x=(120+25);x<300;x+=25){
               g.drawLine(x,20,x,199);
          }

          //draw the bars for each of the stats
          g.setColor (Color.black);
          g.fillRect (120,30,initCount * 25,40);
          g.fillRect (120,80,startCount * 25,40);
          g.fillRect (120,130,stopCount * 25, 40);
          g.fillRect (120,180,destroyCount * 25, 40);
     }

     public void update(Graphics g){
          paint(g);
     }     public void init(){
          initCount++;
          System.out.println("init");
          repaint();
     }

     public void start(){
          startCount++;
          System.out.println("start");
          repaint();
     }

     public void stop(){
          stopCount++;
          System.out.println("stop");
          repaint();
     }

     public void destroy(){
          destroyCount++;
          System.out.println("destroy");
          repaint();
     }
}

Compiling the InitStartStop Applet

To be able to run the InitStartStop applet, just like the HelloWorld applet, you must compile it and generate a HTML file which references the applet. To do this, first copy the contents of Listing 14.7 to a file called InitStartStop.java. Then compile this file using javac:

javac InitStartStop.java

Now, before you can actually use the InitStartStop applet, you must first create the HTML for it. The InitStartStop.html file is shown below:

<HTML>
<BODY>
<APPLET code="InitStartStop.class" HEIGHT=300 WIDTH=400></APPLET>
</BODY>
</HTML>

Finally, you're set to run the InitStartStop applet. To do this, load the InitStartStop.html file into a browser like Netscape Navigator. The first time you load the program you will see something that looks like Figure 14.7 below. The init() method has been called once, as has the start() method. This should be exactly what you expected to see.

FIG. 14.7
InitStartStop when it first starts has run the init() method and the start() method once.

Now hit the reload button a couple of times. Each time you do, the number of times that stop() has been called and the number of times that start() is called will both increment once, as demonstrated in Figure 14.8 below. However, the init() count will stay the same, since the init() method is only called the very first time the browser loads the applet.

FIG. 14.8
After leaving the page and coming back several times, start() and stop() will have incremented. Notice that the applet has always started one more time than it has stopped.

As you run the applet you can also look at those printout statements you were generating. To do this in Netscape 3.1 and earlier, select Options, Show _Java Console, users of Netscape 4.0 can get to the Java Console by accessing Communicator, _Java Console. This should produce yet another window as shown in Figure 14.9. Inside this window you can see all the System.out messages as they appear. Try hitting reload a few more times. Now, try going to a different Web page. What happened? Well of course, stop() was called and start() wasn't. Now hit the back button. start() is called.

FIG. 14.9
The Java console in Netscape shows you the System.out messages as they appear.

Understanding the InitStartStop Applet

To understand the InitStartStop applet, take it step by step.

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

The first thing in the file are several import statements. As you learned in Chapter 11, for a class to be used (without fully qualifying its name each time) the class must first be imported. Just like the HelloWorld applet, InitStartStop needs access to the java.awt.Graphics class. In addition, InitStartStop will need access to a couple of other java.awt classes, so rather than import each individual class separately, the entire package of java.awt is imported here.

The first method in InitStartStop is the paint method. This method paints a number of things to the screen using methods available in the java.Graphics class. You will learn more about the Graphics class in Chapter 27, so for now just concentrate on the last part of the paint() method.

//draw the bars for each of the stats
g.setColor (Color.black);
g.fillRect (120,30,initCount * 25,40);
g.fillRect (120,80,startCount * 25,40);
g.fillRect (120,130,stopCount * 25, 40);
g.fillRect (120,180,destroyCount * 25, 40);

The purpose of this section is to draw the actual bars that you saw indicating how many times each of the methods had been called. This is accomplished by increasing the width of the bar by 25 times the count number (such as initCount*25).

public void update(Graphics g){
     paint(g);
}

The next method in the class is the update(). Update just calls paint() so you might be wondering what it is doing there. To understand why, it's necessary to understand the relationship between update() and paint(). Ordinarily when an applet needs to be painted, either because it's just been displayed to the screen, or perhaps a different screen which had been covering the applet was just removed, the paint() method is called. However, when an applet only needs to be partially painted, such as when another window has only partially obscured the applet or when the repaint() method was called, the update() method is called. By default update() clears the panel, and then calls paint(). However, this can cause an annoying flicker (try running InitStartStop with this method removed). To get around this, it's become routine for programmers to insert an update() method which does not clear the screen, but which calls paint() right away.

The next several methods are really the ones you want to see something from. Each method increments a counter, does a printout, and calls repaint() (which causes the update/paint() method to be called).

     public void init(){
          initCount++;
          System.out.println("init");
          repaint();
     }

     public void start(){
          startCount++;
          System.out.println("start");
          repaint();
     }

     public void stop(){
          stopCount++;
          System.out.println("stop");
          repaint();
     }

     public void destroy(){
          destroyCount++;
          System.out.println("destroy");
          repaint();
     }
}

Java Animator Applet

One of the most popular uses right now for Java is to create simple animations. It should be pointed out right now that Java is not the best medium to do this. If all you want to do is create an animation, there are much better ways to do this, such as GIF89a Cel Frame animations. However, since this is so frequently done in Java, an animator is shown here. Listing 14.8 shows a complete version of an animator written in Java.

Listing 14.8Animator Class Cycles Through Images

import java.awt.*;
import java.util.Vector;

public class Animator extends java.applet.Applet implements Runnable {
Vector images;
int imgNumber;
int currentImage=1;
Thread thisThread;

  public void init(){
    //Read in the number of images in the animation
    imgNumber = new Integer(getParameter("imgNumber")).intValue();
    
    //Load the images
    for (int x=0;x<imgNumber;x++){
      Image img = getImage(getDocumentBase(),"images/img"+(x+1));
      images.addElement(img);
      }
  }
  
  public void paint(Graphics g){
    g.drawImage((Image)images.elementAt(currentImage++),0,0,null);
    currentImage%=imgNumber;
    }
  
  public void update(Graphics g){
    paint(g);
  }
  
  public void start(){
    thisThread = new Thread(this);
    thisThread.start();
    }
    
  public void stop(){
    thisThread.stop();
  }
  
  public void run(){
    while(true){
      try{
        thisThread.sleep(100);
        }
        catch (Exception e){}
    }
   }
}

Right away you can probably tell that there is a lot more to this applet than to the HelloWorld one. To compile this program, first copy all of Listing 14.8 into a file called Animator.java. To run it you will need to create an HTML file which should look something like Listing 14.9.

Listing 14.9HTML File for Including Animator

<HTML>
<BODY>
<APPLET code="Animator.class" HEIGHT=200 WIDTH=200>
<PARAM NAME="imgNumber" VALUE="5">
</APPLET>
</BODY>
</HTML>

In addition to these files you will also need to have several images that you want to animate, and you will need to place them in a subdirectory called images. The images must be called img1.gif, img2.gif ... where img1.gif is the first image of the animation. You will also want to change the imgNumber parameter to have the correct number of images. With all that done, you should see something similar to Figure 14.10.

FIG. 14.10
Java can be used to generate some interesting animations.

Now, to understand how the animator works, break Listing 14.8 into some more manageable chunks. First take the first three lines of the code.

import java.awt.*;
import java.util.Vector;
public class Animator extends java.applet.Applet implements Runnable {

The first two lines serve to import other Java classes. Java is an extensible language, and the object-oriented nature of the language allows you to take advantage of pre-built classes. The first two lines of the Animator code import such classes.

The third line of code is the class declaration. At the end of the line you will notice that the Animator, like HelloWorld, extends java.applet.Applet. java.applet.Applet is the name of the class from which all applets extend. Immediately after the class declaration is the statement implements Runnable which indicates that the application can be run as a thread. It is important that Animator be able to run as a thread since it will continue to process even after the rest of the page is done loading.

Immediately after these lines of code, Animator declares several variables of its own.

Vector images;
int imgNumber;
int currentImage=1;
Thread thisThread;

Remember from Chapter 10 that Java is a strongly typed language. This means that each variable must be declared to be a specific type. In some other languages, such as JavaScript, you would have created the variables with only the var keyword.

var images;
var imgNumber;
var currentImage=1;
var thisThread;

For a variety of reasons, this is not really the best way to work, and Java requires that you declare the type that each variable will be. As you can see, you are creating four variables. The Vector is a class type that is very convenient to contain a number of elements, especially if you do not know ahead of time how many you will be adding. The thread variable will be used to control the activity of the applet later on.

The Applet Animator has several methods. The first of these is the init() method.

public void init(){
  //Read in the number of images in the animation
  imgNumber = new Integer(getParameter("imgNumber")).intValue();
    
  //Load the images
  for (int x=0;x<imgNumber;x++){
    Image img = getImage(getDocumentBase(),"images/img"+(x+1));
    images.addElement(img);
    }
}

The init() method is called when the page is initially loaded into the browser. It is convenient to use the init() method to set up variables that only have to be initialized once. In the case of the Animator class, all of the images only need to be loaded once. Notice that after the getImage method is called, the image is added to the images Vector.

The next method is the paint method. The paint method is called each time the Applet needs to be displayed on the Web page. This can happen if the user scrolls the Applet off the screen and then scrolls back, or if you specifically cause the applet to be repainted.

public void paint(Graphics g){
  g.drawImage((Image)images.elementAt(currentImage++),0,0,null);
  currentImage%=imgNumber;
  }

Without breaking the paint method apart completely, break the drawImage line apart a bit. drawImage is a method that obviously draws an image to the graphics screen. There are four parameters which must be given the drawImage method. First, the name of the image, next the x and y locations, and finally the imageObserver which should pay attention to the image.

So why is the image name ((Image)images.elementAt(currentImage++) so complicated? Well, take it from the right side back. First, you want to display the current image (currentImage). It is convenient to increment the currentImage number so that the next time through you will display the next image, so you automatically increment the currentImage variable (currentImage++). Now you have stored the images in a Vector, and the way to get the current image from the vector is to use the method elementAt on the image object (elementAt(CurrentImage++)). The only problem at this point is that the Vector does not really know it is holding an image. The Vector only knows that it has something, and so it returns the image to you in a way that isn't quite right, so you need to perform what is known as a cast. The (Image) in front of the images.elementAt performs the cast for you and now you have retrieved an image.

The next method is start. start is called each time the user goes to a specific page. But wait, isn't that when the init() method is called? No, not exactly. You see, the init() method is only called the first time the page is loaded. From that point on, each time the page is loaded, the only method that is called is start. start is called the first time too, after the init method, but on successive loads only start is called.

public void start(){
  thisThread = new Thread(this);
  thisThread.start();
  }

The start method is a great place to put the applet into a known state. In the case of Animator, a thread is created. Without a complete explanation of threads, this means that the applet will continue to run as the rest of the browser does other things.

public void stop(){
  thisThread.stop();
}

To learn more about threads, refer to Chapter 13, "Threads."

A very close cousin to the start method is the stop method, which is called each time the user leaves the page. It is important to clean up what you have started when the page is exited. The stop method of Animator takes the thread it was running and stops it.

The last method for Animator is run. run is the method that actually runs in the thread.

public void run(){
  while(true){
    repaint();
    try{
      thisThread.sleep(100);
      }
      catch (Exception e){}
  }
}

Essentially what occurs in Animator's run method is a constant loop which consists of first telling the Animator to repaint, and then to place the Animator thread in a state known as sleep for 100ms. The result of this is that 10 times a second (1/100ms) the next frame of the animation is displayed.

An Applet that Uses Controls

As you saw in the previous applet example, applets are interactive applications that can handle messages generated by both the system and the user. Another way, besides the mouse, that you can enable user interaction is by including controls--such as buttons, menus, list boxes, and text boxes--in your applet's display. Although controls are covered thoroughly in Chapter 29, " java.awt - Components," you'll get an introduction to them now, as you create an applet that can connect you to various Web sites on the Internet.

Listing 14.10 is the Java source code for the applet in question, and Listing 14.11 is the applet's HTML document. Before running this applet (by loading its HTML document into a Java-compatible browser), make your Internet connection. Then, when you run the applet, you see a window something like Figure 14.11, which shows InternetApplet running in Netscape Navigator 3.1. Just click one of the connection buttons and you automatically log on to the Web site associated with the button. Figure 14.12 shows where you end up when you click the CNet button.

FIG. 14.11
The InternetApplet applet uses buttons to provide an instant connection to eight different Web sites.

FIG. 14.12
The CNet button, for example, connects to CNet's terrific site.

Listing 14.10InternetApplet.java--The InternetApplet Applet

import java.awt.*;
import java.applet.*;
import java.net.*;
public class InternetApplet extends Applet
{
    boolean badURL;
    public void init()
    {
        GridLayout layout = new GridLayout(2, 4, 10, 10);
        setLayout(layout);
        Font font = new Font("TimesRoman", Font.PLAIN, 24);
        setFont(font);
        Button button = new Button("Sun");
        add(button);
        button = new Button("Netscape");
        add(button);
        button = new Button("Microsoft");
        add(button);
        button = new Button("Macmillan");
        add(button);
        button = new Button("Time");
        add(button);
        button = new Button("CNet");
        add(button);
        button = new Button("Borland");
        add(button);
        button = new Button("Yahoo");
        add(button);
        badURL = false;
    }
    public void paint(Graphics g)
    {
        if (badURL)
            g.drawString("Bad URL!", 60, 130);
    }
    public boolean action(Event evt, Object arg)
    {
        String str;
        if (arg == "Sun")
            str = "http://www.sun.com";
        else if (arg == "Netscape")
            str = "http://www.netscape.com";
        else if (arg == "Microsoft")
            str = "http://www.microsoft.com";
        else if (arg == "Macmillan")
            str = "http://www.mcp.com";
        else if (arg == "Time")
            str = "http://www.pathfinder.com";
        else if (arg == "CNet")
            str = "http://www.cnet.com";
        else if (arg == "Borland")
            str = "http://www.borland.com";
        else
            str = "http://www.yahoo.com";
        try
        {
            URL url = new URL(str);
            AppletContext context = getAppletContext();
            context.showDocument(url);
        }
        catch (MalformedURLException e)
        {
            badURL = true;
            repaint();
        }
        
        return true;
    }
}

Listing 14.11INTERNETAPPLET.HTML--InternetApplet's HTML Document

<title>Applet Test Page</title>
<h1>Applet Test Page</h1>
<applet
    code="InternetApplet.class"
    width=500
    height=150
    name="InternetApplet">
</applet>

Understanding the InternetApplet Applet

Now take a look at the applet's source code. The first three lines enable the program to access the classes stored in Java's awt, applet, and net packages:

import java.awt.*;
import java.applet.*;
import java.net.*;

You're already familiar with the awt and applet packages. The net package contains the classes needed to log on to the Internet.

The applet's main class, which is derived from Applet, begins in the next line:

public class InternetApplet extends Applet

InternetApplet then declares its single data member:

boolean badURL;

The badURL data member is used in the program to notify the applet that the currently selected URL is no good.

Exploring the init() Method

Next comes the familiar init() method, where the applet can perform whatever initialization it requires. In this case, the applet first declares and sets a layout manager:

GridLayout layout = new GridLayout(2, 4, 10, 10);
setLayout(layout);

Java programs use layout managers to control where components in the program will appear on the screen. Java offers many types of layout managers, each represented by its own class in the awt package. (See Chapter 30, "Containers and Layout Managers," for more information on layout managers.) If you don't create and set your own layout manager, Java uses the FlowLayout manager--which places components horizontally one after the other--by default. In InternetApplet, you're using a GridLayout manager, which organizes components into a grid. GridLayout's constructor takes four arguments:

These latter two arguments have default values of 0 if you want to leave them off.

The setLayout() function is a member of the Container class, which is a superclass (a parent class in the class hierarchy) of the Applet class. Its single argument is a reference to a layout-manager object. After calling setLayout(), Java knows to use the new layout manager rather than the default one.

After setting the applet's layout manager, the program creates and sets the font that'll be used for all text in the applet:

Font font = new Font("TimesRoman", Font.PLAIN, 24);
setFont(font);

The constructor for the Font class takes three arguments--the font's name, attribute, and size. The font's name can be Dialog, Helvetica, TimesRoman, Courier, or Symbol, whereas the attribute can be Font.PLAIN, Font.ITALIC, or Font.BOLD. The setFont() method sets the new font for the applet.

The next task is to create, and add to the applet, the button controls used to select Web sites. Listing 14.12 shows the code that accomplishes this task.

Listing 14.12LST14_12.TXT--Creating Button Controls

Button button = new Button("Sun");
add(button);
button = new Button("Netscape");
add(button);
button = new Button("Microsoft");
add(button);
button = new Button("Macmillan");
add(button);
button = new Button("Time");
add(button);
button = new Button("CNet");
add(button);
button = new Button("Borland");
add(button);
button = new Button("Yahoo");
add(button);

The Button class's constructor takes a single argument, which is the text label that appears in the button when it's displayed. The add() method adds the button to the next available cell in the GridLayout manager.

Finally, init() sets the badURL flag to false:

badURL = false;

Exploring the action() Method

Most user events caused in an applet can be handled by overriding the action() method. The signature for the action() method looks like this:

public boolean action(Event evt, Object arg)

As you can see, action() receives two parameters--an Event object and an Object object. You learn more about these objects in Chapter 19, "Exceptions and Events in Depth." For now, it's enough to know that, in the case of a button control, arg is the button's text label.

When the user clicks one of the applet's buttons, the action() method is called. As I said, the arg parameter is the text label of the button that was clicked, so it's pretty easy to determine which button the user selected. To do this, InternetApplet uses an if-else statement to check the button's label. When the program finds the button the user selected, it sets str, which is an object of Java's String class, to the selected URL, as shown in Listing 14.13.

Listing 14.13LST14_13.TXT--Getting the Requested URL

String str;
if (arg == "Sun")
    str = "http://www.sun.com";
else if (arg == "Netscape")
    str = "http://www.netscape.com";
else if (arg == "Microsoft")
    str = "http://www.microsoft.com";
else if (arg == "Macmillan")
    str = "http://www.mcp.com";
else if (arg == "Time")
    str = "http://www.pathfinder.com";
else if (arg == "CNet")
    str = "http://www.cnet.com";
else if (arg == "Borland")
    str = "http://www.borland.com";
else
    str = "http://www.yahoo.com";

After obtaining the selected URL, the applet can connect to the Web site. Before doing this, though, the program must set up a try and catch program block, because the URL class' constructor throws a MalformedURLException exception, which must be caught by your program. (You learn more about exceptions in Chapter 19, "Exceptions and Events in Depth.") The try program blocks attempts to create the URL object and connects to the Web site, as shown in Listing 14.14.

Listing 14.14LST14_14.TXT--Connecting to a Web Site

try
{
    URL url = new URL(str);
    AppletContext context = getAppletContext();
    context.showDocument(url);
}

In the try block, the program first tries to create an URL object from the URL text string. If the construction fails, the URL class throws a MalformedURLException exception, and program execution continues at the catch program block, which you look at soon. If the URL object gets constructed successfully, the program calls the getAppletContext() method to get a reference to the applet's AppletContext object. This object's showDocument() method is what connects the applet to the chosen URL.

If the URL class's constructor throws an exception, program execution jumps to the catch program block, which is shown in Listing 14.15.

Listing 14.15LST14_15.TXT--The Catch Program Block

catch (MalformedURLException e)
{
    badURL = true;
    repaint();
}

In the catch program block, the program simply sets the badURL flag to true and calls repaint() to display an error message to the user.

Exploring the paint() Method

Listing 14.16 shows the applet's paint() method, which does nothing more than display an error message if the badURL flag is set to true.


NOTE: Because the URLs are hard-coded into the program, it's not likely that the URL will con-struct improperly. If you were to change a button's URL, though, the error message lets you know if you typed the URL incorrectly.


Listing 14.16LST14_16.TXT--The paint() Method

public void paint(Graphics g)
{
    if (badURL)
        g.drawString("Bad URL!", 60, 130);

}

The drawString() function, which is a method of the Graphics class, displays a text string on the screen. Its three arguments are the string to display, and the X,Y coordinates at which to display the string.