THE HITMAN EXAMPLE

HitManApplet is a Java applet that demonstrates how Javascript and Java can interact on an HTML page using LiveConnect. HitManApplet uses getMember() to search the JavaScript object hierarchy for VictimApplet objects; each VictimApplet is then "hit." You should know HTML, Java, and Javascript to easily understand what is happening in this example, but the sample code will be described in detail below so you will probably be able to follow along even if you are not an expert yet.

The Applets:

The Hitman:
A Victim:
Another Victim:

Notice that there are three rectangles on the page; Each of these is an applet The top rectangle says "Hit Them!" and is an instance of HitManApplet. The two lower rectangles with numbers inside them are both instances of VictimApplet. Click the HitManApplet box and watch the two other boxes increment together.

What these applets demonstrate is the use of the JSObject in Java to find and access other Applets on a page. This particular functionality could also be found in Java's AppletContext, but the technique which we are demonstrating can be easily extended to provide functionality that is not available from AppletContext. For instance, it could be used to find the applets in a particular named frame. Or it could be slightly modified to search for Plug-ins instead of Applets.

Here is the HTML source, so you can see how both applets are called from HTML.

The Hitman:
<APPLET ARCHIVE="HitManApplet/HitManApplet.zip" 
                CODE="netscape/dts/examples/HitMan/HitManApplet.class" 
                WIDTH=100 HEIGHT=50 NAME=killer MAYSCRIPT>
</APPLET>
<BR>
A Victim:
<APPLET ARCHIVE="HitManApplet/HitManApplet.zip" 
                CODE="netscape/dts/examples/HitMan/VictimApplet.class" 
                WIDTH=70 HEIGHT=70 NAME=joe MAYSCRIPT>
</APPLET>
<BR>
Another Victim:
<APPLET ARCHIVE="HitManApplet/HitManApplet.zip" 
                CODE="netscape/dts/examples/HitMan/VictimApplet.class" 
                WIDTH=70 HEIGHT=70 NAME=joejr MAYSCRIPT>
</APPLET>


Notice that the APPLET tag is used to embed Java applets into HTML. In this example there are three APPLET tags, so there are three instances of our sample applets on the screen. The ARCHIVE attribute of the APPLET tag specifies a single file containg all of the necessary classes for this example. The applet class specified in the CODE attribute. Notice the class in the first applet tag is HitManApplet.class and, for both the other applet tags, the class is VictimApplet.class. The width and height of the rectangles are designated by their corresponding attributes. Finally, each of the applet tags end with MAYSCRIPT, which gives the applets permission to access JavaScript functionality through the JSObject class.

The VictimApplet is very simple. (Look at the source here.) The main feature of this class is the hit() method, which increments the numHits instance variable. This method will get called by the HitManApplet. Notice that this class does not use JSObject, but must still have MAYSCRIPT set in the APPLET tag. This is because HitManApplet, which does use JSObject, will be accessing VictimApplet. For security reasons, Netscape Navigator will not allow a MAYSCRIPT'ed Applet to communicate with a non-MAYSCRIPT'ed applet, and vice versa.

HitManApplet is much more interesting. (Look at the source here.) Using the JSObject class, HitManApplet traverses the JavaScript object structure to find all of the applets that reside in the same frame as the HitManApplet. It then checks the type of each applet to determine whether or not it is a member of the VictimApplet class. HitManApplet then calls the hit() method of every VictimApplet.

Here is a detailed description of HitThem(), the HitManApplet method which does all of the work.

        JSObject window = JSObject.getWindow( this );

The getWindow static method takes an Applet, and returns a JSObject that represents the window which contains the Applet. All JavaScript commands must be performed in the context of a window, so this is always the first call for an applet to make when working with JavaScript.

        JSObject document = (JSObject) window.getMember("document");
        JSObject applets = (JSObject) document.getMember("applets");

We must traverse the JavaScript object hierarchy to get to the JavaScript "applets" object, which is an array of all applets in the given window. The getMember method returns an Object. This Object must then be cast up to the appropriate class. We know that the "document" member of the window object will be of type JSObject, so we cast it as such. We also know that the "applets" member of the document object will be a JSObject as well. If our assumptions turn out to be incorrect, Java will throw a ClassCastException. We will use this fact to our advantage later. In any event, if all went well, we now have a JSObject which represents an array of Applets on our page.

        int numApplets = ((Double) applets.getMember("length")).intValue();

Since we know that the applets object is a JavaScript array, we also know that the array will have a member called "length", which has a numerical value. JavaScript returns all numerical values to Java as type java.lang.Double, so we cast the return value of applets.getMember("length") as such. However, what we need is an integer value. We get this from Double's intValue() method.

        targetLoop: for( int index = 0; index < numApplets; index++ ) {

Now that we have a bounding value, we can iterate through the list of applets. We label this loop targetLoop. You will see why shortly.

        Object theApplet = applets.getSlot( index );

For JavaScript arrays, we can call the getSlot method to get indexed members of the array. We don't cast the object yet, since we don't know exactly what class it belongs to.

        try {
                targetApplet = (VictimApplet) theApplet;
        } 
        catch( ClassCastException e ) {
                continue targetLoop;
        }

Now we can make use of the ClassCastException, as alluded to above. We try casting the theApplet object into a VictimApplet. If theApplet is not a member of the VictimApplet class, or a subclass thereof, then Java will throw a ClassCastException. In that event, we catch the exception and continue on to the next iteration of targetLoop. (We could have left out the targetLoop label, but that would have made the code somewhat less readable.)

        targetApplet.hit();

Finally, if no exception was thrown, then we know that targetApplet is a proper victim. We call that Applet's hit() method, and continue with the next Applet. When all of the Applets have been tried, we are done.


ADDITIONAL READING
Java Documentation
Amazon.com Java Books
Netscape IFC
Tools to Create Java Applets
Java Sample Code
Java Language Course

ARTICLES

Java Articles
Java News Articles
Intro-level Java Articles
Java FAQ

MEMBERS RESOURCES

Java Newsgroup

For the latest technical information on Sun-Netscape Alliance products, go to: http://developer.iplanet.com

For more Internet development resources, try Netscape TechSearch.


Copyright © 1999 Netscape Communications Corporation.
This site powered by: Netscape Enterprise Server and Netscape Compass Server.