java.applet.Applet

An applet is a Java class that runs in a Web browser. Whereas a stand-alone Java application uses the main() function as its cornerstone, the architecture and life cycle of an applet is more complex. Also, since applets are routinely packaged with HTML pages that are downloaded from the Web, they represent significant security issues. Therefore, many file and system functions that are legal for applications, are not legal for applets.
Java provides a SecurityManager class that controls access to nearly every system-level call in the JVM. This model is called the "sandbox" security model - the JVM provides a sandbox that allows applets to "play nicely", but if they attempt to leave the sandbox they are prevented. [Sun275, p10-3]
The class Applet shares much commonality with the class Frame. The common ancestries are portrayed below.
   Object
      |
      +--- Component
              |
              +--- Container
                      |
                      +--- Window
                      |       |
                      |       +--- Frame
                      |
                      +--- Panel
                              |
                              +--- Applet
The next two examples offer a comparison between a Frame and an Applet. Hard copy of the windows are provided on a subsequent page.
    1  import java.awt.*;
     
    2  class Test extends Frame {
    3     public Test() {
    4        super( "Applet test" );
    5        setBounds( 50, 100, 300, 100 );
    6        Label lab = new Label( "Hello world", Label.CENTER );
    7        add( lab );
    8        setVisible( true );
    9     }
   10     public static void main( String[] args ) {
   11        new Test();
   12  }  }
The size for the entire window is being set with setBounds(). Since BorderLayout is the default for Frames, the Label is assigned to the "BorderLayout.CENTER" position and is centered vertically upon display.
    1  //////////////////////// Test.html ////////////////////////
    2  <title>Applet test</title>
    3  Here is before<br>
    4  <applet codebase="." code="Test.class" width=300 height=100>
    5  </applet>
    6  <br>Here is after

    7  //////////////////////// Test.java ////////////////////////
    8  import java.applet.*;
    9  import java.awt.*;

   10  public class Test extends Applet {
   11     public Test() {
   12        setBackground( Color.lightGray );
   13        Label lab = new Label( "Hello world", Label.CENTER );
   14        add( lab );
   15     }
   16     public void init() {
   17        new Test();
   18  }  }
Applets must be declared in an HTML file using the <applet> tag. Width and height of the applet are the responsibility of the HTML entry. Since FlowLayout is the default for Applets, the Label is not centered vertically upon display. main() is not used in the applet architecture. The "entry points" that are required are discussed next.


Applet life cycle

There are four methods in class Applet that provide the framework for an applet's life cycle: init(), start(), stop(), and destroy(). The first code the browser calls is the class's default constructor.

init() is automatically called when Java launches the applet for the first time. Common responsibilities for this method are: processing PARAM values from the HTML entry, initializing data values, creating user interface components, and creating threads. Applets can have a default constructor, but it is customary to perform all initialization here instead.

start() is automatically called after Java calls init(). It tells the applet that it should become "live". It is also called whenver the browser is restored after being iconified, or when the browser returns to the page containing the applet after moving to another URL. Common responsibilities for this method are: invoking a thread's start() method, asking a thread to continue execution on subsequent invocations, starting animations, and playing sounds.

stop() is automatically called when the applet ceases to be "live" (the user moves off the page on which the applet sits, or the browser is iconified). Its purpose is to give you a chance to stop time-consuming activities when the user is not paying attention to the applet. start() and stop() effectively form a pair. Whatever start() triggers, then stop() will "pause". Common responsibilities for this method are: stop an animation, stop a sound, and ask a thread to pause itself.

destroy() is guaranteed to be called when the browser shuts down normally. Since applets are meant to live on HTML pages, you do not need to worry about destroying the parent Panel. This will happen automatically when the browser shuts down. What you do need to put in the destroy() method is the code for reclaiming non-memory-dependent resources such as graphics contexts that you may have consumed. Java itself will call stop() before calling destroy() if the applet is still active. Interrupting active threads is another example responsibility.


Applet display

Applets are essentially graphical in nature, and, access to "standard out" is unknown or impossible; so, use of System.out.println() is not normally practiced. Instead, you "draw" text and graphics on the applet. But making sure the "drawing" remains current and intact in the presence of exposures, resizings, and un-iconifying is a challenge. The following architecture has been established to address these issues.

paint( Graphics g ) - called by the system whenever the component needs to redraw itself. Includes a "clipping rectangle" capability that causes updates to be limited to the region that has been "damaged".

update( Graphics g ) - clears this component by filling it with the background color, and, calls this component's paint method to completely redraw itself.

repaint() - called by the programmer to tell the system to call the referenced component's update() method.

Normally, the default implementation for update() is sufficient. The programmer is routinely responsible for writing the paint() method. If a call to paint() is desired - don't call it directly. Instead, call repaint() to have the paint() method called indirectly.

"The applet model requires that you adopt a specific strategy for maintaining your display:"

[Source: Sun275, p10-11]

The example below demonstrates all the start-up methods and their order of invocation.

    1  //////////////////////// Test.java ////////////////////////
    2  Here is before<br>
    3  <applet codebase="." code="Test.class" width=400 height=40>
    4  </applet>
    5  <br>Here is after

    6  //////////////////////// Test.java ////////////////////////
    7  import java.applet.*;
    8  import java.awt.*;

    9  public class Test extends Applet {
   10     StringBuffer sb = new StringBuffer( "attr" );

   11     public Test() {
   12        sb.append( " ctor" );
   13        setBackground( Color.lightGray );
   14     }
   15     public void init() {
   16        sb.append( " init" );
   17     }
   18     public void start() {
   19        sb.append( " start" );
   20     }
   21     public void paint( Graphics g ) {
   22        sb.append( " paint" );
   23        g.drawString( sb.toString(), 15, 23 );
   24  }  }
The output below was produced by: accessing the Test.html page, going to a different page, returning to the Test.html page, obscuring part of the applet, and subsequently unobscuring it.
   attr ctor init start paint start paint paint

HTML syntax

Here is a summary of the Applet HTML tag (optional fields appear in brackets).
   <APPLET   CODE= .class file name   WIDTH= pixels   HEIGHT= pixels
      [ CODEBASE= url or directory ]   [ ALT= alternate text message ]
      [ ALIGN= alignment ]             [ ARCHIVE= names of jar files ]
      [ HSPACE= pixels ]               [ VSPACE= pixels ]
      [ NAME= name for other applets on page ]
   >
      [ <PARAM NAME= identifier   VALUE= value> ]
      .....
      [ alternate HTML ]
   </APPLET>
The CODE tag is required. There are two ways to specify its value. In both cases, the value is case-sensitive and must include the .class extension. If a URL is specified, the applet may exist on any accessible machine.

The CODEBASE tag lets you architect a "base address" for a hierarchy of HTML and Java byte-code files, and then use the CODE tag as an "offset" (a relative path within the CODEBASE directory).

An applet can determine the directory it came from by calling getCodeBase(). It can also determine its host HTML file's directory by calling getDocumentBase().

The WIDTH and HEIGHT tags are required and specify the applet's initial width and height. It is possible for the final width and height to be different if other elements on the HTML page cause the browser to constrain the applet's size.

The PARAM tag allows data to be passed from the HTML page to the applet.

    1  <applet codebase="." code="Test.class" width=400 height=100>
    2     <param name=VALUE value=CamelCase>
    3     <param name=words value="the quick brown fox">
    4  </applet>

    5  import java.awt.Graphics;
    6  import java.applet.Applet;

    7  public class Test extends Applet {
    8     String value, words;

    9     public void init() {
   10        value = getParameter( "VALUE" );
   11        words = getParameter( "words" );
   12     }
   13     public void paint( Graphics g ) {
   14        g.drawString( value, 20, 20 );  // camel case is preserved
   15        g.drawString( words, 20, 40 );  // embedded white space is fine
   16  }  }
The argument to getParameter() is case-insensitive. The String that is returned has its case and embedded white space preserved. A missing parameter causes getParameter() to return null.

The ALT tag is for browsers that understand what the APPLET tag means but do not actually support applets. Such a browser will display the alternate text specified here in the space where the applet would normally appear. If a browser is completely Java-ignorant, it will not even understand the APPLET tag. However, it will correctly display the "alternate HTML" that appears between the APPLET and /APPLET tags.

   <APPLET  CODE=Test.class  WIDTH=100  HEIGHT=100
    ALT="applet goes here">
    Get another browser!<p>
   </APPLET>
The HSPACE tag designates the distance in pixels between the applet's left and right edges and any adjacent HTML elements. The VSPACE tag does the same for the applet's top and bottom edges. The ALIGN tag serves the same role as it does in other HTML components. The legal values are: left, right, top, texttop, middle, absmiddle, baseline, bottom, and absbottom.

The NAME tag supports inter-applet communication. If an applet has a name, then another applet on the same HTML page can use the name to get a reference to the first applet. The second applet can then make method calls to the first applet. [Roberts, p365]

    1  Here is before<br>
    2  <applet codebase="." code="Test.class" width=400 height=100 name=first>
    3     <param name=local value=abc>
    4     <param name=other value=second>
    5  </applet><br>
    6  Here is between<br>
    7  <applet codebase="." code="Test.class" width=400 height=100 name=second>
    8     <param name=local value=xyz>
    9     <param name=other value=first>
   10  </applet><br>
   11  Here is after

   12  import java.awt.Graphics;
   13  import java.applet.Applet;

   14  public class Test extends Applet {
   15     private String local, other;
   16     private Applet app;

   17     public void init() {
   18        local = getParameter( "LOCAL" );
   19        other = getParameter( "OTHER" );
   20        app = getAppletContext().getApplet( other );
   21     }
   22     public void paint( Graphics g ) {
   23        g.drawString( "I am " + local + ".  Other is " + ((Test)app).getLocal(), 20, 20 );
   24     }
   25     public String getLocal() {
   26        return local;
   27  }  }
The getAppletContext() call on line 20 is asking the host browser to return an object that acts as a communication path between the applet and the browser. This object knows how to return a reference to another applet (given the NAME tag for that applet). Notice how the "name" tag on line 2 matches the "other" param entry on line 9. We can now interact with that applet by calling any method in its public interface. [Horstmann, vol1, pp495-497]

Version 1.1 of the JDK introduced JAR files. A JAR (Java ARchive) file is a zipped collection of files. The ARCHIVE tag identifies any JAR files on the server that the browser should download.

JAR files greatly speed remote class loading. There is a significant time penalty for downloading a file. If an applet defines 10 classes, then ordinarily the penalty is incurred 10 times. With JAR technology, all 10 class files can be bundled into a single JAR file, and the per-file penalty is only incurred once. [Roberts, p365]


Image, audio, looping

Applets can handle both images and audio. Java applications do not have the resources provided by a browser and cannot use the methods described below. Java 1.1 supports gif and jpeg image files, and Sun's au audio format. The most basic image example follows.
    1  import java.awt.Graphics;
    2  import java.applet.Applet;

    3  public class Test extends Applet {
    4     private Image duke;

    5     public void init() {
    6        duke = getImage( getDocumentBase(), "images\\javalogo.gif" );
    7     }
    8     public void paint( Graphics g ) {
    9        g.drawImage( duke, 0, 0, this );
   10  }  }
getImage() requires a URL object (not covered here). The method getDocumentBase() is popular because it returns a URL object that represents the directory that contains the parent HTML file. From that "absolute" file system reference, the programmer can specify a "relative offset" to fully qualify the desired image file. On line 6, the "\\" is necessary on DOS systems to separate directories and to "escape" the default meaning of the '\' character.

The arguments to drawImage() are: the Image object, x, y, and the "image observer" (line 9). Images are loaded incrementally in a background thread. Each time more of the image is loaded, the paint() method is called. The correct object's method is called because the applet has "registered" itself by passing this to drawImage() (line 9).

Playing an audio clip looks remarkably similar.

    1  import java.awt.Graphics;
    2  import java.applet.*;

    3  public class Test extends Applet {
    4     private AudioClip sound;

    5     public void init() {
    6        sound = getAudioClip( getDocumentBase(), "audio\\yahoo1.au" );
    7     }
    8     public void paint( Graphics g ) {
    9        sound.play();
   10  }  }
The example above replays the clip each time paint() is called. The example below puts the clip in continuous repeat mode every time the HTML page is "live", and stops it whenever the page ceases to be "live" (the browser is iconified, or the page ceases to be current).
    1  import java.awt.*;
    2  import java.applet.*;

    3  public class Test extends Applet {
    4     private AudioClip sound;

    5     public void init() {
    6        sound = getAudioClip( getDocumentBase(), "audio\\spacemusic.au" );
    7     }
    8     public void start() {
    9        sound.loop();
   10     }
   11     public void stop() {
   12        sound.stop();
   13  }  }

Dual purpose code

It is possible to create Java code that can be used both as an applet and as an application. The easiest strategy is to architect the applet first: inherit (extends) from class Applet, put constructor functionality in an init() method, put restart functionality in a start() method, and create a paint() method that is capable of "reinstating" the entire user interface on demand.

We can now architect the application by adding a main() method (it will be ignored by the applet). The main() should: create an instance of class Frame, create an instance of the applet, add the applet to the frame (Applet inherits from Panel and panels can be added to frames), call setSize() and setVisible() on the frame, and call init() and start() on the applet.

To read more about converting an applet to an application, see [Liang, p323]. To convert an application to an applet see [Horstmann, vol1, p470] and [Liang, p326].