Section 5.2
The Applet Life Cycle


DURING THE TIME THAT AN APPLET EXITS, it responds to a stream of events that are sent to it from the outside. An applet has no "main program" and takes no action on its own initiative. (We will see later, though, that an applet can create a separate "thread" that can run very much like a separate, active program.) The life cycle of an applet, then, is determined by the events it receives and the way it responds to them. The system sends an event to an applet by calling one of the applet's methods.

In this section, we'll look at some of the events that can occur and the methods that respond to them. All these methods are defined in the Applet class, but the versions in that class do nothing. To define an applet's response to an event, you should override the appropriate method in a subclass.


Initialization and Cleanup

An applet class does not ordinarily use a constructor to do initialization. Instead, just after an applet object is created, the system calls that object's init() method, which has the form

public void init() { . . . }

This method can do the task usually performed by a constructor, that is, to initialize the applet's instance variables. The init() method is also the place where other components, such as buttons, are added to the applet. There is also a complementary method called destroy() that is called by the system just before the applet object is disposed of. It takes the form

public void destroy() { . . . }

This method is called to give the applet a chance to clean up before it ceases to exist. Because of Java's automatic garbage collection, a lot of cleanup is done automatically. There are a few cases, however, where destroy() might be useful. For example, it is possible for an applet to create a separate window on the screen. You could use the applet's destroy method to close such a window.

An applet also has start() and stop() methods, which play similar roles to init() and destroy(). One difference is that while init() and destroy() are each called exactly once during the life cycle of an applet, start() and stop() can be called many times. The start() method is called once when the applet object is first created, immediately after the init() method is called. The system can choose to stop the applet by calling its stop() method and then later restart it by calling its start() method again. For example, a Web browser will typically stop an applet if the user leaves the page on which the applet is displayed, and will restart it if the user returns to that page.The stop() method will be called at least once, before the applet is destroyed. An applet that has been stopped will not receive any other events until it has been restarted. The start() and stop() methods take the form

public void start() { . . . }

and

public void stop() { . . . }

It is not always clear what initialization should be done in init() and what should be done in start(). Things that only need to be done once should ordinarily be done in init(). If the applet uses a large amount of some computer resource such as memory, it might be reasonable for it to allocate that resource in its start() method and release it in its stop() method, so that the applet will not be hogging resources when it isn't even running. On the other hand, sometimes this is impossible because the applet needs to retain the resource for its entire lifetime. You'll see some examples of using start() and stop() in the next chapter.


Mouse Events

The user interacts with an applet by moving the mouse, by clicking with the mouse, and by pressing keys on the keyboard. The applet is notified of a lot of different events related to these user actions. As far as the mouse goes, the system calls the following methods:

      public boolean mouseEnter(Event evt, int x, int y) {
         . . . // respond to fact that mouse has entered applet's rectangle
         return true;
      }
      public boolean mouseExit(Event evt, int x, int y) {
         . . . // respond to fact that mouse has left applet's rectangle
         return true;
      }
      public boolean mouseDown(Event evt, int x, int y) {
         . . . // respond to fact that user has pressed mouse button
         return true;
      }
      public boolean mouseUp(Event evt, int x, int y) {
         . . . // respond to fact that mouse has released mouse button
         return true;
      }
      public boolean mouseDrag(Event evt, int x, int y) {
         . . . // respond to fact that mouse has moved, while
               //   user is holding down a mouse button
         return true;
      }
      public boolean mouseMove(Event evt, int x, int y) {
         . . . // respond to fact that mouse has moved, while
               //   user is NOT holding down a mouse button
         return true;
      }

As you can see, if you simply move the mouse across the applet, the system calls mouseEnter() as soon as the mouse enters the applet. As the mouse moves, the system calls mouseMove() over and over. Exactly how often the system will check the position of the mouse to see whether it has moved depends on the implementation of Java that you are using and on how busy the system is with other things, so you can't be sure how many times mouseMove() will be called. (In particular, it will almost certainly not be called every time the mouse moves a single pixel.)

If the user clicks the mouse somewhere in the rectangle occupied by the applet, the system will first call the applet's mouseDown() method when the user presses the button, and then call its mouseUp() method when the user releases it. If the user moves the mouse while holding the button down, the computer will call mouseDrag() over and over as the mouse moves.

In all of these methods, the parameters x and y give the horizontal and vertical position of the mouse, in coordinates appropriate to the applet. The parameter x measures horizontal distance, in pixels, from the left edge of the applet, while y measures vertical distance from the top edge. You can use this information to tell where the user clicked the mouse and to track the mouse as it moves.

The parameter evt carries full information about the event that caused the method to be called. (It even contains copies of x and y, but these are pulled out as separate parameters for your convenience.) For example, there is a public instance variable named clickcount that you can use in the mouseDown() method to check for double clicks: Just check if (evt.clickcount == 2).

You can also check whether the user was holding down the shift key or the control key when the event occurs. The Event class includes instance methods named shiftDown() and controlDown() that can be used to check for these keys. These methods return boolean values, so you can simply check if (evt.shiftDown()) or if (evt.controlDown()).

The META key (on a Macintosh, the command key) works in the same way. You can use evt.metaDown() to check whether the user was holding down the META key. However, on a computer that has a two- or three-button mouse, the evt.metaDown() can also be used to distinguish between the left and right mouse buttons in the mouseDown(), mouseUp and mouseDrag() methods. The right mouse button generates events for which metaDown() is true, whether or not the user is actually holding down the META key. Things are done this way so that the same program can work on different platforms with different types of mice. (The middle mouse button is simulated using the ALT key, but for some reason there is no altDown() method. To test whether the ALT key is down, you have to say "if ((evt.modifiers & Event.ALT_MASK) != 0)"!)

Here's a simple applet that displays the coordinates of the mouse as you move or drag it around the applet:

        import java.awt.*;
        import java.applet.*;
        
        public class SimpleTrackMouse extends Applet {
        
           int mouse_x, mouse_y;  // mouse coordinates
           String modifierKeys = "";  // special keys that are held down
           Color displayColor = Color.black;
           
           public void init() {   // I want a white background
              setBackground(Color.white);
           }
           
           public void paint(Graphics g) {
              int w = size().width;  // get the width of the applet
              int h = size().height; // get the height of the applet
              g.setColor(Color.blue);
              g.drawRect(0,0,w-1,h-1);  // draw a frame for the applet area
              g.setColor(Color.black);
              g.drawString(modifierKeys, 4, 20);
              g.setColor(displayColor);
              g.drawString("(" + mouse_x + "," + mouse_y + ")",
                                  mouse_x, mouse_y);
           }  // end of paint()
           
           void setInfo(Event evt, int x, int y) {
                 // set up the information about event for display
              mouse_x = x;
              mouse_y = y;
              modifierKeys = "";
              if (evt.shiftDown())
                 modifierKeys += "Shift ";
              if (evt.controlDown())
                 modifierKeys += "Control ";
              if (evt.metaDown())
                 modifierKeys += "META ";
              if ((evt.modifiers & Event.ALT_MASK) != 0)
                 modifierKeys += "ALT ";
           }
           
           public boolean mouseMove(Event evt, int x, int y) {
              setInfo(evt, x, y);
              displayColor = Color.black;
              repaint();
              return true;
           }
           
           public boolean mouseDrag(Event evt, int x, int y) {
              setInfo(evt, x, y);
              displayColor = Color.red;  // red when mouse is down
              repaint();
              return true;
           }
           
        }  // end of class SimpleTrackMouse
        

This applet displays the mouse's coordinates at the current position of the mouse. Different colors are used for mouseMove and mouseDrag events. If the user is holding down one of the special keys, that fact is noted in the upper left corner of the applet. Try it by moving your mouse over the applet:

Sorry, but your browser
doesn't support Java.


Keyboard Events

Everytime the user presses a key on the keyboard, two events are generated: one when the user presses the key and one when the user releases the key. An applet can be programmed to respond to such events by overriding the keyDown() and keyUp() methods. Override the keyDown() method if you want your applet to respond to the user's typing. You will probably never need to override the keyUp() method. (I'll note immediately, though, that handling keyboard events in an applet is relatively rare, since keyboard handling is usually done automatically by predefined components such as text input boxes.)

The keyboard event-handling methods are defined as follows:

       public void keyDown(Event evt, int key) {
          . . . // respond to the fact that a key has been pressed
          return true;
       }
       public void keyUp(Event evt, int key) {
          . . . // respond to the fact that a key has been released
          return true;
       }

The key parameter in these methods tells you which key was pressed by the user. You might be surprised to see that this parameter has type int rather than char. This is because characters aren't the only things that the user can type! The user can also press "action keys" such as the arrow keys and the function keys F1, F2, etc.

If the user actually types a character, then the key parameter tells you which character was typed. Because key is of type int, you have to use a type-cast to discover which character was typed:

char typedChar = (char)key;

If the use pressed one of the action keys, then the value of the key parameter will be a special constant value that specifies which key was pressed. The value will be one of the following predefined constants: Event.UP, Event.DOWN, Event.LEFT, Event.RIGHT, Event.HOME, Event.END, Event.PGUP, Event.PGDN, or Event.F1 through Event.F12. The first four of these, which are probably the most useful correspond to the up, down, left, and right arrow keys.

There is another complication when dealing with keyboard events: There is the question of who gets such events when they occur. There might, for example, be several applets on a page of a Web browser. When the user types, only one of the applets can receive the keyboard events (and in fact, keyboard events can also go to the Web page itself). We say that an object has the input focus if it is the object to which the system sends keyboard events. Java provides three methods for dealing with the input focus. An applet can call the method requestFocus() if it would like to have the input focus. (This doesn't mean that it will get it; the system can refuse the request.) The system calls the applet's gotFocus() and lostFocus() methods to let the applet know when it is getting and losing the input focus and to give it a chance to respond.


Action Events and Other Events

Besides mouse and keyboard events, there are events that are generated when the user interacts with graphical interface components such as buttons, menus, and text boxes. (The user actually causes these other events with the mouse or keyboard, but they are translated by the system into more meaningful terms.) For many of these events, the system calls the action() method, which takes the form

       public boolean action(Event evt, Object arg) {
          . . . // respond to the action event
          return true;  // or return false, if action not handled
       }

This method is called when the user clicks on a button or a checkbox, double-clicks on an item in a list, presses return while typing in a text input box, or selects an item from a menu or pop-up menu. (Buttons, checkboxes, and so forth are graphical user interface components which are actually objects belonging to the classes Button, Checkbox, List, TextField, Menu, or Choice.)

I will have more to say about action events in the next chapter, when I discuss the various GUI components.

There are still more events, and there is one other method that you will have to override if you want to handle them. This is the very general method handleEvent(), which takes the form:

        public boolean handleEvent(Event evt) {
           . . . // handle the event
           return true;  // or return super.handleEvent(Evt), 
                         //       if event was not handled
        }

I have been less than honest with you in this section when I've said that "the system" calls methods like mouseDown() and action(). In fact, the system really only calls handleEvent(), and handleEvent() calls all the other special-purpose event-handling methods, as appropriate. Some events, dealing with certain GUI components, don't have special-purpose event handlers. If you want to respond to those events, you have to override handleEvent() itself. I'll discuss a few events of this type in the next chapter.


[ Next Section | Previous Section | Chapter Index | Main Index ]