Friday 24 March 2017

The Delegation Event Model & Event Listener Interfaces - Java Tutorials

The Delegation Event Model

Before beginning our discussion of event handling, an important point must be made: The way in which events are handled by an applet changed significantly between the original version of Java (1.0) and modern versions of Java, beginning with version 1.1. The 1.0 method of event handling is still supported, but it is not recommended for new programs. Also, many of the methods that support the old 1.0 event model have been deprecated. The modern approach is the way that events should be handled by all new programs, including those written for Java 2, and thus is the method employed by programs in this book.

The modern approach to handling events is based on the delegation event model, which defines standard and consistent mechanisms to generate and process events. Its concept is quite simple: a source generates an event and sends it to one or more listeners. In this scheme, the listener simply waits until it receives an event. Once received, the listener processes the event and then returns. The advantage of this design is that the application logic that processes events is cleanly separated from the user interface logic that generates those events. A user interface element is able to “delegate” the processing of an event to a separate piece of code.

In the delegation event model, listeners must register with a source in order to receive an event notification. This provides an important benefit: notifications are sent only to listeners that want to receive them. This is a more efficient way to handle events than the design used by the old Java 1.0 approach. Previously, an event was propagated up the containment hierarchy until it was handled by a component. This required components to receive events that they did not process, and it wasted valuable time. The delegation event model eliminates this overhead.

Java also allows you to process events without using the delegation event model. This can be done by extending an AWT component. However, the delegation event model is the preferred design for the reasons just cited.

The following sections define events and describe the roles of sources and listeners.


Events

In the delegation model, an event is an object that describes a state change in a source. It can be generated as a consequence of a person interacting with the elements in a graphical user interface. Some of the activities that cause events to be generated are pressing a button, entering a character via the keyboard, selecting an item in a list, and clicking the mouse. Many other user operations could also be cited as examples.

Events may also occur that are not directly caused by interactions with a user interface. For example, an event may be generated when a timer expires, a counter exceeds a value, a software or hardware failure occurs, or an operation is completed. You are free to define events that are appropriate for your application.


Event Sources

A source is an object that generates an event. This occurs when the internal state of that object changes in some way. Sources may generate more than one type of event. A source must register listeners in order for the listeners to receive notifications about a specific type of event. Each type of event has its own registration method. Here is the general form:

      public void addTypeListener(TypeListener el)

Here, Type is the name of the event and el is a reference to the event listener. For example, the method that registers a keyboard event listener is called addKeyListener( ). The method that registers a mouse motion listener is called addMouseMotionListener( ). When an event occurs, all registered listeners are notified and receive a copy of the event object. This is known as multicasting the event. In all cases, notifications are sent only to listeners that register to receive them.

Some sources may allow only one listener to register. The general form of such a method is this:

      public void addTypeListener(TypeListener el)
          throws java.util.TooManyListenersException

Here, Type is the name of the event and el is a reference to the event listener. When such an event occurs, the registered listener is notified. This is known as unicasting the event. A source must also provide a method that allows a listener to unregister an interest in a specific type of event. The general form of such a method is this:

      public void removeTypeListener(TypeListener el)

Here, Type is the name of the event and el is a reference to the event listener. For example, to remove a keyboard listener, you would call removeKeyListener( ). The methods that add or remove listeners are provided by the source that generates events. For example, the Component class provides methods to add and remove keyboard and mouse event listeners.


Event Listeners

A listener is an object that is notified when an event occurs. It has two major requirements. First, it must have been registered with one or more sources to receive notifications about specific types of events. Second, it must implement methods to receive and process these notifications.

The methods that receive and process events are defined in a set of interfaces found in java.awt.event. For example, the MouseMotionListener interface defines two methods to receive notifications when the mouse is dragged or moved. Any object may receive and process one or both of these events if it provides an implementation of this interface. Many other listener interfaces are discussed later in this and other chapters.


Sources of Events

Table 20-2 lists some of the user interface components that can generate the events described in the previous section. In addition to these graphical user interface elements, other components, such as an applet, can generate events. For example, you receive key and mouse events from an applet. (You may also build your own components that generate events.) In this chapter we will be handling only mouse and keyboard events.


Event Source Examples

Button:  Generates action events when the button is pressed.

Checkbox:  Generates item events when the check box is selected or deselected.

Choice:  Generates item events when the choice is changed.

List:  Generates action events when an item is double-clicked; generates item events when an item is selected or deselected.

Menu Item:  Generates action events when a menu item is selected; generates item events when a checkable menu item is selected or deselected.

Scrollbar:  Generates adjustment events when the scroll bar is manipulated.

Text components:  Generates text events when the user enters a character.

Window:  Generates window events when a window is activated, closed, deactivated, deiconified, iconified, opened, or quit.





Event Listener Interfaces

As explained, the delegation event model has two parts: sources and listeners. Listeners are created by implementing one or more of the interfaces defined by the java.awt.event package. When an event occurs, the event source invokes the appropriate method defined by the listener and provides an event object as its argument. Lists commonly used listener interfaces and provides a brief description of the methods that they define. The following sections examine the specific methods that are contained in each interface.


Commonly Used Event Listener Interfaces

ActionListener:  Defines one method to receive action events.

AdjustmentListener:  Defines one method to receive adjustment events.

ComponentListener:  Defines four methods to recognize when a component is hidden, moved, resized, or shown.

ContainerListener:  Defines two methods to recognize when a component is added to or removed from a container.

FocusListener:  Defines two methods to recognize when a component gains or loses keyboard focus.

ItemListener:  Defines one method to recognize when the state of an item changes.

KeyListener:  Defines three methods to recognize when a key is pressed, released, or typed.

MouseListener:  Defines five methods to recognize when the mouse is clicked, enters a component, exits a component, is pressed, or is released.

MouseMotionListener:  Defines two methods to recognize when the mouse is dragged or moved.

MouseWheelListener:  Defines one method to recognize when the mouse wheel is moved. (Added by Java 2, version 1.4)

TextListener:  Defines one method to recognize when a text value changes.

WindowFocusListener:  Defines two methods to recognize when a window gains or loses input focus. (Added by Java 2, version 1.4)

WindowListener:  Defines seven methods to recognize when a window is activated, closed, deactivated, deiconified, iconified, opened, or quit.


The ActionListener Interface
This interface defines the actionPerformed( ) method that is invoked when an action event occurs. Its general form is shown here:

      void actionPerformed(ActionEvent ae)


The AdjustmentListener Interface
This interface defines the adjustmentValueChanged( ) method that is invoked when an adjustment event occurs. Its general form is shown here:

      void adjustmentValueChanged(AdjustmentEvent ae)


The ComponentListener Interface
This interface defines four methods that are invoked when a component is resized, moved, shown, or hidden. Their general forms are shown here:

      void componentResized(ComponentEvent ce)
      void componentMoved(ComponentEvent ce)
      void componentShown(ComponentEvent ce)
      void componentHidden(ComponentEvent ce)

The AWT processes the resize and move events. The componentResized( ) and componentMoved( ) methods are provided for notification purposes only.


The ContainerListener Interface
This interface contains two methods. When a component is added to a container, componentAdded( ) is invoked. When a component is removed from a container, componentRemoved( ) is invoked. Their general forms are shown here:

      void componentAdded(ContainerEvent ce)
      void componentRemoved(ContainerEvent ce)


The FocusListener Interface
This interface defines two methods. When a component obtains keyboard focus, focusGained( ) is invoked. When a component loses keyboard focus, focusLost( ) is called. Their general forms are shown here:

      void focusGained(FocusEvent fe)
      void focusLost(FocusEvent fe)


The ItemListener Interface
This interface defines the itemStateChanged( ) method that is invoked when the state of an item changes. Its general form is shown here:

      void itemStateChanged(ItemEvent ie)


The KeyListener Interface
This interface defines three methods. The keyPressed( ) and keyReleased( ) methods are invoked when a key is pressed and released, respectively. The keyTyped( ) method is invoked when a character has been entered.

For example, if a user presses and releases the A key, three events are generated in sequence: key pressed, typed, and released. If a user presses and releases the HOME key, two key events are generated in sequence: key pressed and released.

The general forms of these methods are shown here:

      void keyPressed(KeyEvent ke)
      void keyReleased(KeyEvent ke)
      void keyTyped(KeyEvent ke)


The MouseListener Interface
This interface defines five methods. If the mouse is pressed and released at the same point, mouseClicked( ) is invoked. When the mouse enters a component, the mouseEntered( ) method is called. When it leaves, mouseExited( ) is called. The mousePressed( ) and mouseReleased( ) methods are invoked when the mouse is pressed and released, respectively.

The general forms of these methods are shown here:

      void mouseClicked(MouseEvent me)
      void mouseEntered(MouseEvent me)
      void mouseExited(MouseEvent me)
      void mousePressed(MouseEvent me)
      void mouseReleased(MouseEvent me)


The MouseMotionListener Interface
This interface defines two methods. The mouseDragged( ) method is called multiple times as the mouse is dragged. The mouseMoved( ) method is called multiple times as the mouse is moved. Their general forms are shown here:

      void mouseDragged(MouseEvent me)
      void mouseMoved(MouseEvent me)


The MouseWheelListener Interface
This interface defines the mouseWheelMoved( ) method that is invoked when the mouse wheel is moved. Its general form is shown here.

      void mouseWheelMoved(MouseWheelEvent mwe)

MouseWheelListener was added by Java 2, version 1.4.


The TextListener Interface
This interface defines the textChanged( ) method that is invoked when a change occurs in a text area or text field. Its general form is shown here:

      void textChanged(TextEvent te)


The WindowFocusListener Interface
This interface defines two methods: windowGainedFocus( ) and windowLostFocus( ). These are called when a window gains or losses input focus. Their general forms are shown here.

      void windowGainedFocus(WindowEvent we)
      void windowLostFocus(WindowEvent we)

WindowFocusListener was added by Java 2, version 1.4.


The WindowListener Interface
This interface defines seven methods. The windowActivated( ) and windowDeactivated( ) methods are invoked when a window is activated or deactivated, respectively. If a window is iconified, the windowIconified( ) method is called. When a window is deiconified, the windowDeiconified( ) method is called. When a window is opened or closed, the windowOpened( ) or windowClosed( ) methods are called, respectively. The windowClosing( ) method is called when a window is being closed. The general forms of these methods are

      void windowActivated(WindowEvent we)
      void windowClosed(WindowEvent we)
      void windowClosing(WindowEvent we)
      void windowDeactivated(WindowEvent we)
      void windowDeiconified(WindowEvent we)
      void windowIconified(WindowEvent we)
      void windowOpened(WindowEvent we)

Passing Parameters to Applets, getDocumentBase( ) and getCodeBase( ) & AppletContext and showDocument( ) - Java Tutorials

Passing Parameters to Applets

As just discussed, the APPLET tag in HTML allows you to pass parameters to your applet. To retrieve a parameter, use the getParameter( ) method. It returns the value of the specified parameter in the form of a String object. Thus, for numeric and boolean values, you will need to convert their string representations into their internal formats. Here is an example that demonstrates passing parameters:

  // Use Parameters
  import java.awt.*;
  import java.applet.*;
  /*
  <applet code="ParamDemo" width=300 height=80>
  <param name=fontName value=Courier>
  <param name=fontSize value=14>
  <param name=leading value=2>
  <param name=accountEnabled value=true>
  </applet>
  */

  public class ParamDemo extends Applet{
    String fontName;
    int fontSize;
    float leading;
    boolean active;

    // Initialize the string to be displayed.
    public void start() {
      String param;

      fontName = getParameter("fontName");
      if(fontName == null)
        fontName = "Not Found";

      param = getParameter("fontSize");
      try {
        if(param != null) // if not found
          fontSize = Integer.parseInt(param);
        else
          fontSize = 0;
      } catch(NumberFormatException e) {
        fontSize = -1;
      }

      param = getParameter("leading");
      try {
        if(param != null) // if not found
          leading = Float.valueOf(param).floatValue();
        else
          leading = 0;
      } catch(NumberFormatException e) {
        leading = -1;
      }

      param = getParameter("accountEnabled");
      if(param != null)
        active = Boolean.valueOf(param).booleanValue();
    }

    // Display parameters.
    public void paint(Graphics g) {
      g.drawString("Font name: " + fontName, 0, 10);
      g.drawString("Font size: " + fontSize, 0, 26);
      g.drawString("Leading: " + leading, 0, 42);
      g.drawString("Account Active: " + active, 0, 58);
    }
  }

As the program shows, you should test the return values from getParameter( ). If a parameter isn’t available, getParameter( ) will return null. Also, conversions to numeric types must be attempted in a try statement that catches NumberFormatException. Uncaught exceptions should never occur within an applet.


Improving the Banner Applet

It is possible to use a parameter to enhance the banner applet shown earlier. In the previous version, the message being scrolled was hard-coded into the applet. However, passing the message as a parameter allows the banner applet to display a different message each time it is executed. This improved version is shown here. Notice that the APPLET tag at the top of the file now specifies a parameter called message that is linked to a quoted string.

  // A parameterized banner
  import java.awt.*;
  import java.applet.*;
  /*
  <applet code="ParamBanner" width=300 height=50>
  <param name=message value="Java makes the Web move!">
  </applet>
  */

  public class ParamBanner extends Applet implements Runnable {
    String msg;
    Thread t = null;
    int state;
    boolean stopFlag;

    // Set colors and initialize thread.
    public void init() {
      setBackground(Color.cyan);
      setForeground(Color.red);
    }

    // Start thread
    public void start() {
      msg = getParameter("message");
      if(msg == null) msg = "Message not found.";
      msg = " " + msg;
      t = new Thread(this);
      stopFlag = false;
      t.start();
    }

    // Entry point for the thread that runs the banner.
    public void run() {
      char ch;

      // Display banner
      for( ; ; ) {
        try {
          repaint();
          Thread.sleep(250);
          ch = msg.charAt(0);
          msg = msg.substring(1, msg.length());
          msg += ch;
          if(stopFlag)
            break;
        } catch(InterruptedException e) {}
      }
    }

    // Pause the banner.
    public void stop() {
      stopFlag = true;
      t = null;
    }

    // Display the banner.
    public void paint(Graphics g) {
      g.drawString(msg, 50, 30);
    }
  }




getDocumentBase( ) and getCodeBase( )

Often, you will create applets that will need to explicitly load media and text. Java will allow the applet to load data from the directory holding the HTML file that started the applet (the document base) and the directory from which the applet’s class file was loaded (the code base). These directories are returned as URL objects (described in Chapter 18) by getDocumentBase( ) and getCodeBase( ). They can be concatenated with a string that names the file you want to load. To actually load another file, you will use the showDocument( ) method defined by the AppletContext interface, discussed in the next section.

The following applet illustrates these methods:

  // Display code and document bases.
  import java.awt.*;
  import java.applet.*;
  import java.net.*;
  /*
  <applet code="Bases" width=300 height=50>
  </applet>
  */

  public class Bases extends Applet{
    // Display code and document bases.
    public void paint(Graphics g) {
      String msg;

      URL url = getCodeBase(); // get code base
      msg = "Code base: " + url.toString();
      g.drawString(msg, 10, 20);

      url = getDocumentBase(); // get document base
      msg = "Document base: " + url.toString();
      g.drawString(msg, 10, 40);
    }
  }




AppletContext and showDocument( )

One application of Java is to use active images and animation to provide a graphical means of navigating the Web that is more interesting than the underlined blue words used by hypertext. To allow your applet to transfer control to another URL, you must use the showDocument( ) method defined by the AppletContext interface. AppletContext is an interface that lets you get information from the applet’s execution environment. The methods defined by AppletContext are shown in Table 19-2. The context of the currently executing applet is obtained by a call to the getAppletContext( ) method defined by Applet.

Within an applet, once you have obtained the applet’s context, you can bring another document into view by calling showDocument( ). This method has no return value and throws no exception if it fails, so use it carefully. There are two showDocument( ) methods. The method showDocument(URL) displays the document at the specified URL. The method showDocument(URL, where) displays the specified document at the specified location within the browser window. Valid arguments for where are “_self” (show in current frame), “_parent” (show in parent frame), “_top” (show in topmost frame), and “_blank” (show in new browser window). You can also specify a name, which causes the document to be shown in a new browser window by that name.


The Abstract Methods Defined by the AppletContext Interface

Applet getApplet(String appletName):  Returns the applet specified by appletName if it is within the current applet context. Otherwise, null is returned.

Enumeration getApplets( ):  Returns an enumeration that contains all of the applets within the current applet context.

AudioClip getAudioClip(URL url):  Returns an AudioClip object that encapsulates the audio clip found at the location specified by url.

Image getImage(URL url):  Returns an Image object that encapsulates the image found at the location specified by url.

InputStream getStream(String key):  Returns the stream linked to key. Keys are linked to streams by using the setStream( ) method. A null reference is returned if no stream is linked to key. (Added by Java 2, version 1.4)

Iterator getStreamKeys( ):  Returns an iterator for the keys associated with the invoking object. The keys are linked to streams. See getStream( ) and setStream( ). (Added by Java 2, version 1.4)

void setStream(String key, InputStream strm):  Links the stream specified by strm to the key passed in key. The key is deleted from the invoking object if strm is null. (Added by Java 2, version 1.4)

void showDocument(URL url):  Brings the document at the URL specified by url into view. This method may not be supported by applet viewers.

void showDocument(URL url, String where):  Brings the document at the URL specified by url into view. This method may not be supported by applet viewers. The placement of the document is specified by where as described in the text.

void showStatus(String str):  Displays str in the status window.


The following applet demonstrates AppletContext and showDocument( ). Upon execution, it obtains the current applet context and uses that context to transfer control to a file called Test.html. This file must be in the same directory as the applet. Test.html can contain any valid hypertext that you like.

  /* Using an applet context, getCodeBase(),
     and showDocument() to display an HTML file.
  */

  import java.awt.*;
  import java.applet.*;
  import java.net.*;
  /*
  <applet code="ACDemo" width=300 height=50>
  </applet>
  */

  public class ACDemo extends Applet{
    public void start() {
      AppletContext ac = getAppletContext();
      URL url = getCodeBase(); // get url of this applet

      try {
        ac.showDocument(new URL(url+"Test.html"));
      } catch(MalformedURLException e) {
        showStatus("URL not found");
      }
    }
  }


The AudioClip Interface

The AudioClip interface defines these methods: play( ) (play a clip from the beginning), stop( ) (stop playing the clip), and loop( ) (play the loop continuously). After you have loaded an audio clip using getAudioClip( ), you can use these methods to play it.


The AppletStub Interface

The AppletStub interface provides the means by which an applet and the browser (or applet viewer) communicate. Your code will not typically implement this interface.


Outputting to the Console

Although output to an applet’s window must be accomplished through AWT methods, such as drawString( ), it is still possible to use console output in your applet—especially for debugging purposes. In an applet, when you call a method such as System.out.println( ), the output is not sent to your applet’s window. Instead, it appears either in the console session in which you launched the applet viewer or in the Java console that is available in some browsers. Use of console output for purposes other than debugging is discouraged, since it violates the design principles of the graphical interface most users will expect.

Simple Applet Display Methods, Requesting Repainting, Using the Status Window & The HTML APPLET Tag - Java Tutorials

Simple Applet Display Methods

As we’ve mentioned, applets are displayed in a window and they use the AWT to perform input and output. Although we will examine the methods, procedures, and techniques necessary to fully handle the AWT windowed environment in subsequent chapters, a few are described here, because we will use them to write sample applets.

As we described in Chapter 12, to output a string to an applet, use drawString( ), which is a member of the Graphics class. Typically, it is called from within either update( ) or paint( ). It has the following general form:

      void drawString(String message, int x, int y)

Here, message is the string to be output beginning at x,y. In a Java window, the upper-left corner is location 0,0. The drawString( ) method will not recognize newline characters. If you want to start a line of text on another line, you must do so manually, specifying the precise X,Y location where you want the line to begin. (As you will see in later chapters, there are techniques that make this process easy.)

To set the background color of an applet’s window, use setBackground( ). To set the foreground color (the color in which text is shown, for example), use setForeground( ). These methods are defined by Component, and they have the following general forms:

      void setBackground(Color newColor)
      void setForeground(Color newColor)

Here, newColor specifies the new color. The class Color defines the constants shown here that can be used to specify colors:

      Color.black 
      Color.magenta
      Color.blue 
      Color.orange
      Color.cyan 
      Color.pink
      Color.darkGray 
      Color.red
      Color.gray 
      Color.white
      Color.green 
      Color.yellow
      Color.lightGray

For example, this sets the background color to green and the text color to red:

  setBackground(Color.green);
  setForeground(Color.red);

A good place to set the foreground and background colors is in the init( ) method. Of course, you can change these colors as often as necessary during the execution of your applet. The default foreground color is black. The default background color is light gray.

You can obtain the current settings for the background and foreground colors by calling getBackground( ) and getForeground( ), respectively. They are also defined by Component and are shown here:

      Color getBackground( )
      Color getForeground( )

Here is a very simple applet that sets the background color to cyan, the foreground color to red, and displays a message that illustrates the order in which the init( ), start( ), and paint( ) methods are called when an applet starts up:

  /* A simple applet that sets the foreground and
     background colors and outputs a string. */
  import java.awt.*;
  import java.applet.*;
  /*
  <applet code="Sample" width=300 height=50>
  </applet>
  */

  public class Sample extends Applet{
    String msg;

    // set the foreground and background colors.
    public void init() {
      setBackground(Color.cyan);
      setForeground(Color.red);
      msg = "Inside init( ) --";
    }

    // Initialize the string to be displayed.
    public void start() {
      msg += " Inside start( ) --";
    }

    // Display msg in applet window.
    public void paint(Graphics g) {
      msg += " Inside paint( ).";
      g.drawString(msg, 10, 30);
    }
  }

The methods stop( ) and destroy( ) are not overridden, because they are not needed by this simple applet.




Requesting Repainting

As a general rule, an applet writes to its window only when its update( ) or paint( ) method is called by the AWT. This raises an interesting question: How can the applet itself cause its window to be updated when its information changes? For example, if an applet is displaying a moving banner, what mechanism does the applet use to update the window each time this banner scrolls? Remember, one of the fundamental architectural constraints imposed on an applet is that it must quickly return control to the AWT run-time system. It cannot create a loop inside paint( ) that repeatedly scrolls the banner, for example. This would prevent control from passing back to the AWT. Given this constraint, it may seem that output to your applet’s window will be difficult at best. Fortunately, this is not the case. Whenever your applet needs to update the information displayed in its window, it simply calls repaint( ).

The repaint( ) method is defined by the AWT. It causes the AWT run-time system to execute a call to your applet’s update( ) method, which, in its default implementation, calls paint( ). Thus, for another part of your applet to output to its window, simply store the output and then call repaint( ). The AWT will then execute a call to paint( ), which can display the stored information. For example, if part of your applet needs to output a string, it can store this string in a String variable and then call repaint( ). Inside paint( ), you will output the string using drawString( ).

The repaint( ) method has four forms. Let’s look at each one, in turn. The simplest version of repaint( ) is shown here:

      void repaint( )

This version causes the entire window to be repainted. The following version specifies a region that will be repainted:

      void repaint(int left, int top, int width, int height)

Here, the coordinates of the upper-left corner of the region are specified by left and top, and the width and height of the region are passed in width and height. These dimensions are specified in pixels. You save time by specifying a region to repaint. Window updates are costly in terms of time. If you need to update only a small portion of the window, it is more efficient to repaint only that region.

Calling repaint( ) is essentially a request that your applet be repainted sometime soon. However, if your system is slow or busy, update( ) might not be called immediately. Multiple requests for repainting that occur within a short time can be collapsed by the AWT in a manner such that update( ) is only called sporadically. This can be a problem in many situations, including animation, in which a consistent update time is necessary. One solution to this problem is to use the following forms of repaint( ):

      void repaint(long maxDelay)
      void repaint(long maxDelay, int x, int y, int width, int height)

Here, maxDelay specifies the maximum number of milliseconds that can elapse before update( ) is called. Beware, though. If the time elapses before update( ) can be called, it isn’t called. There’s no return value or exception thrown, so you must be careful.

It is possible for a method other than paint( ) or update( ) to output to an applet’s window. To do so, it must obtain a graphics context by calling getGraphics( ) (defined by Component) and then use this context to output to the window. However, for most applications, it is better and easier to route window output through paint( ) and to call repaint( ) when the contents of the window change.


A Simple Banner Applet

To demonstrate repaint( ), a simple banner applet is developed. This applet scrolls a message, from right to left, across the applet’s window. Since the scrolling of the message is a repetitive task, it is performed by a separate thread, created by the applet when it is initialized. The banner applet is shown here:

  /* A simple banner applet.

     This applet creates a thread that scrolls
     the message contained in msg right to left
     across the applet's window.
  */
  import java.awt.*;
  import java.applet.*;
  /*
  <applet code="SimpleBanner" width=300 height=50>
  </applet>
  */

  public class SimpleBanner extends Applet implements Runnable {
    String msg = " A Simple Moving Banner.";
    Thread t = null;
    int state;
    boolean stopFlag;

    // Set colors and initialize thread.
    public void init() {
      setBackground(Color.cyan);
      setForeground(Color.red);
    }

    // Start thread
    public void start() {
      t = new Thread(this);
      stopFlag = false;
      t.start();
    }

    // Entry point for the thread that runs the banner.
    public void run() {
      char ch;

      // Display banner
      for( ; ; ) {
        try {
          repaint();
          Thread.sleep(250);
          ch = msg.charAt(0);
          msg = msg.substring(1, msg.length());
          msg += ch;
          if(stopFlag)
            break;
        } catch(InterruptedException e) {}
      }
    }

    // Pause the banner.
    public void stop() {
      stopFlag = true;
      t = null;
    }

    // Display the banner.
    public void paint(Graphics g) {
      g.drawString(msg, 50, 30);
    }
  }

Let’s take a close look at how this applet operates. First, notice that SimpleBanner extends Applet, as expected, but it also implements Runnable. This is necessary, since the applet will be creating a second thread of execution that will be used to scroll the banner. Inside init( ), the foreground and background colors of the applet are set.

After initialization, the AWT run-time system calls start( ) to start the applet running. Inside start( ), a new thread of execution is created and assigned to the Thread variable t. Then, the boolean variable stopFlag, which controls the execution of the applet, is set to false. Next, the thread is started by a call to t.start( ). Remember that t.start( ) calls a method defined by Thread, which causes run( ) to begin executing. It does not cause a call to the version of start( ) defined by Applet. These are two separate methods.

Inside run( ), the characters in the string contained in msg are repeatedly rotated left. Between each rotation, a call to repaint( ) is made. This eventually causes the paint( ) method to be called and the current contents of msg is displayed. Between each iteration, run( ) sleeps for a quarter of a second. The net effect of run( ) is that the contents of msg is scrolled right to left in a constantly moving display. The stopFlag variable is checked on each iteration. When it is true, the run( ) method terminates.

If a browser is displaying the applet when a new page is viewed, the stop( ) method is called, which sets stopFlag to true, causing run( ) to terminate. This is the mechanism used to stop the thread when its page is no longer in view. When the applet is brought back into view, start( ) is once again called, which starts a new thread to execute the banner.




Using the Status Window

In addition to displaying information in its window, an applet can also output a message to the status window of the browser or applet viewer on which it is running. To do so, call showStatus( ) with the string that you want displayed. The status window is a good place to give the user feedback about what is occurring in the applet, suggest options, or possibly report some types of errors. The status window also makes an excellent debugging aid, because it gives you an easy way to output information about your applet.

The following applet demonstrates showStatus( ):

  // Using the Status Window.
  import java.awt.*;
  import java.applet.*;
  /*
  <applet code="StatusWindow" width=300 height=50>
  </applet>
  */

  public class StatusWindow extends Applet{
    public void init() {
      setBackground(Color.cyan);
    }

    // Display msg in applet window.
    public void paint(Graphics g) {
      g.drawString("This is in the applet window.", 10, 20);
      showStatus("This is shown in the status window.");
    }
  }




The HTML APPLET Tag

The APPLET tag is used to start an applet from both an HTML document and from an applet viewer. (The newer OBJECT tag also works, but this book will use APPLET.) An applet viewer will execute each APPLET tag that it finds in a separate window, while web browsers like Netscape Navigator, Internet Explorer, and HotJava will allow many applets on a single page. So far, we have been using only a simplified form of the APPLET tag. Now it is time to take a closer look at it.

The syntax for the standard APPLET tag is shown here. Bracketed items are optional.

      < APPLET
        [CODEBASE = codebaseURL]
        CODE = appletFile
        [ALT = alternateText]
        [NAME = appletInstanceName]
        WIDTH = pixels HEIGHT = pixels
        [ALIGN = alignment]
        [VSPACE = pixels] [HSPACE = pixels]
      >
      [< PARAM NAME = AttributeName VALUE = AttributeValue>]
      [< PARAM NAME = AttributeName2 VALUE = AttributeValue>]
      . . .
      [HTML Displayed in the absence of Java]
      </APPLET>

Let’s take a look at each part now.

CODEBASE CODEBASE     is an optional attribute that specifies the base URL of the applet code, which is the directory that will be searched for the applet’s executable class file (specified by the CODE tag). The HTML document’s URL directory is used as the CODEBASE if this attribute is not specified. The CODEBASE does not have to be on the host from which the HTML document was read.

CODE     CODE is a required attribute that gives the name of the file containing your applet’s compiled .class file. This file is relative to the code base URL of the applet, which is the directory that the HTML file was in or the directory indicated by CODEBASE if set.

ALT     The ALT tag is an optional attribute used to specify a short text message that should be displayed if the browser understands the APPLET tag but can’t currently run Java applets. This is distinct from the alternate HTML you provide for browsers that don’t support applets.

NAME     NAME is an optional attribute used to specify a name for the applet instance. Applets must be named in order for other applets on the same page to find them by name and communicate with them. To obtain an applet by name, use getApplet( ), which is defined by the AppletContext interface.

WIDTH AND HEIGHT     WIDTH and HEIGHT are required attributes that give the size (in pixels) of the applet display area.

ALIGN     ALIGN is an optional attribute that specifies the alignment of the applet. This attribute is treated the same as the HTML IMG tag with these possible values: LEFT, RIGHT, TOP, BOTTOM, MIDDLE, BASELINE, TEXTTOP, ABSMIDDLE, and ABSBOTTOM.

VSPACE AND HSPACE     These attributes are optional. VSPACE specifies the space, in pixels, above and below the applet. HSPACE specifies the space, in pixels, on each side of the applet. They’re treated the same as the IMG tag’s VSPACE and HSPACE attributes.

PARAM NAME AND VALUE     The PARAM tag allows you to specify appletspecific arguments in an HTML page. Applets access their attributes with the getParameter( ) method.

HANDLING OLDER BROWSERS     Some very old web browsers can’t execute applets and don’t recognize the APPLET tag. Although these browsers are now nearly extinct (having been replaced by Java-compatible ones), you may need to deal with them occasionally. The best way to design your HTML page to deal with such browsers is to include HTML text and markup within your <applet></applet> tags. If the applet tags are not recognized by your browser, you will see the alternate markup. If Java is available, it will consume all of the markup between the <applet></applet> tags and disregard the alternate markup.

Here’s the HTML to start an applet called SampleApplet in Java and to display a message in older browsers:

  <applet code="SampleApplet" width=200 height=40>
   If you were driving a Java powered browser,
   you'd see &quote;A Sample Applet&quote; here.<p>

  </applet>