Team LiB
Previous Section Next Section

Java

Many think that JavaScript is a boiled-down form of Java because of the similarity in their names. The fact that JavaScript was originally called “LiveScript” suggests the mistake in drawing such a conclusion. While Java and JavaScript are both object-oriented languages, they are both commonly used on the Web, and the syntax of both resembles the syntax of C, they are in truth very different languages. Java is a class-based object-oriented language, whereas JavaScript is prototype-based. Java is strongly typed, whereas JavaScript is weakly typed. Java is compiled into platform-independent bytecode before execution, while JavaScript source code is generally interpreted directly by the browser. Java programs execute in a separate context called a “sandbox,” whereas JavaScript is interpreted in the context of the browser.

This last difference—in execution context—is very important. Java applets are nearly platform-independent, stand-alone programs designed to run in a restricted execution environment. There is a lot of theory that goes into the Java sandbox, but in essence applets run in a “virtual machine” that is somewhat isolated from the user’s browser and operating system. This isolation is designed to preserve platform independence as well as the security of the client’s machine.

Java applets are most often used to implement applications that require comprehensive graphics capabilities and network functionality. Java packages installed on the client machine provide networking code, graphics libraries, and user interface routines, often making it a much more capable language than JavaScript for some tasks. Common applications include applets that display real-time data downloaded from the Web (for example, stock tickers), interactive data browsing tools, site navigation enhancements, games, and scientific tools that perform calculations or act as visualization tools.

Including Applets

Before delving into the details of applet interaction, a brief review of how to include applets in your pages is in order. Traditionally, applets are included with the <<applet>> tag. The tag’s code attribute is then set to the URL of the .class file containing the applet, and the height and width attributes indicate the shape of the rectangle to which the applet’s input and output are confined; for example:

<<applet code="myhelloworld.class" width="400" height="100"
 name="myhelloworld" id="myhelloworld">>
<<em>>Your browser does not support Java!<</em>>
<</applet>>

Note how the <<applet>> tag’s name attribute (as well as id attribute) is also set. Doing so assigns the applet a convenient handle JavaScript can use to access its internals.

Although the use of <<applet>> is widespread, it has been deprecated under HTML 4 and XHTML. More appropriate is the <<object>> tag. It has a similar syntax:

<<object classid="java:myhelloworld.class" width="400" height="100"
 name="myhelloworld" id="myhelloworld">>
<<em>>Your browser does not support Java!<</em>>
<</object>>
Note 

There are some problems with the use of the <<object>> syntax for including applets, the least of which is lack of support in older browsers. We will use the <<applet>> syntax, but you should be aware that it is preferable standards-wise to use <<object>> whenever possible.

Initial parameters can be included inside the <<applet>> or <<object>> tag using the <<param>> tag, as shown here:

<<applet code="myhelloworld.class" width="400" height="100"
 name="myhelloworld" id="myhelloworld">>
<<param name="message" value="Hello world from an initial parameter!" />>
<<em>>Your browser does not support Java!<</em>>
<</applet>>

Java Detection

Before attempting to manipulate an applet from JavaScript, you must first determine whether the user’s browser is Java-enabled. Although the contents of an <<applet>> tag are displayed to the user whenever Java is turned off or unavailable, you still need to write your JavaScript so that you do not try to interact with an applet that is not running.

The javaEnabled() method of the Navigator object returns a Boolean indicating whether the user has Java enabled. This method was first made available in IE4 and Netscape 3, the first versions of the browsers that support JavaScript interaction with Java applets. Using a simple if statement with this method should provide the most basic Java detection, as shown here:

if ( navigator.javaEnabled() )
{
  // do Java related tasks
}
else
  alert("Java is off");

Once support for Java is determined, then JavaScript can be used to interact with included applets.

Accessing Applets in JavaScript

The ability to communicate with applets originated with a Netscape technology called LiveConnect that was built into Netscape 3. This technology allows JavaScript, Java, and plug-ins to interact in a coherent manner and automatically handles type conversion of data to a form appropriate to each. Microsoft implemented the same capabilities in IE4, though not under the name LiveConnect. The low-level details of how embedded objects and JavaScript interact are complicated, unique to each browser, and even vary between different versions of the same browser. The important thing is that no matter what it is called, the capability exists in versions of IE4+ (except under Macintosh) and Netscape 3+ (although early versions of Netscape 6 have some problems), and Mozilla-based browsers.

Applets can be accessed through the applets[] array of the Document object or directly through Document using the applet’s name. Consider the following HTML:

<<applet code="myhelloworld.class" width="400" height="100"
 name="myhelloworld" id="myhelloworld">>
<<em>>Your browser does not support Java!<</em>>
<</applet>>

Assuming that this applet is the first to be defined in the document, it can be accessed in all of the following ways, with the last being preferred:

document.applets[0]
// or
document.applets["myhelloworld"]
// or the preferred access method
document.myhelloworld

The JavaScript properties, defined primarily under the browser object model and later by the DOM, of an Applet object are listed in Appendix B and consist of an unsurprising assortment of information reflecting the attributes of the (X)HTML <<applet>> tag for which it was defined. The relevant aspect to this JavaScript-Java communication discussion is the fact that all properties and methods of the applet’s class that are declared public are also available through the Applet object. Consider the following Java class definition for the previous myhelloworld example. The output (when embedded as before) is shown in Figure 18-1.

Click To expand
Figure 18-1: The output of the myhelloworld applet in Internet Explorer
import java.applet.Applet;
import java.awt.Graphics;
public class myhelloworld extends Applet
{
    String message;
    public void init()
    {
        message = new String("Hello browser world from Java!");
    }
    public void paint(Graphics myScreen)
    {
        myScreen.drawString(message, 25, 25);
    }
    public void setMessage(String newMessage)
    {
        message = newMessage;
        repaint();
    }
}

Now comes the interesting part. Because the setMessage() method of the myhelloworld class is declared public, it is made available in the appropriate Applet object. We can invoke it in JavaScript as

document.myhelloworld.setMessage("Wow. Check out this new message!");

Before proceeding further with this example, it is very important to note that applets often require a significant amount of load time. Not only must the browser download the required code, but it also has to start the Java virtual machine and walk the applet through several initialization phases in preparation for execution. It is for this reason that it is never a good idea to access an applet with JavaScript before making sure that it has begun execution. The best approach is to use an onload handler for the Document object to indicate that the applet has loaded. Because this handler fires only when the document has completed loading, you can use it to set a flag indicating that the applet is ready for interaction. This technique is illustrated in the following example using the previously defined myhelloworld applet:

<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">>
<<html xmlns="http://www.w3.org/1999/xhtml">>
<<head>>
<<title>>Applet Interaction Example<</title>>
<<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />>
<</head>>
<<script type="text/javascript">>
<<!--
var appletReady = false;
function changeMessage(newMessage) {
  if (!navigator.javaEnabled()) {
    alert("Sorry! Java isn't enabled!");
    return;
  }

  if (appletReady)
    document.myhelloworld.setMessage(newMessage);
  else
    alert("Sorry! The applet hasn't finished loading");
}
// -->>
<</script>>
<<body onload="appletReady = true;">>
<<applet code="myhelloworld.class" width="400" height="100"
 name="myhelloworld" id="myhelloworld">>
<<em>>Your browser does not support Java!<</em>>
<</applet>>
<<form action="#" method="get" onsubmit="return false;" name="inputForm"
 id="inputForm">>
<<input type="text" name="message" id="message" />>
<<input type="button" value="Change Message"
 onclick="changeMessage(document.inputForm.message.value);" />>
<</form>>
<</body>>
<</html>>

The output of this script after changing the message is shown in Figure 18-2.

Click To expand
Figure 18-2: JavaScript can call public methods of Java applets.

There are tremendous possibilities with this capability. If class instance variables are declared public, they can be set or retrieved as you would expect:

document.appletName.variableName

Inherited variables are, of course, also available.

Note 

Java applets associated with applets defined in <<object>> tags receive the public properties and methods just as those defined in <<applet>> tags do. However, using <<object>> instead of <<applet>> is potentially less cross-browser compatible because Netscape 4 does not expose this HTML element to scripts.

Issues with JavaScript-Driven Applets

Experienced programmers might be asking at this point why one would choose to embed a Java applet alongside JavaScript in a page. One reason might be to avoid having to re-implement code in JavaScript that is readily available in Java. Another reason is that many people feel that user interfaces written in (X)HTML/CSS are easier to implement than in Java (though some people believe the opposite!). One major benefit of using a Web-based interface to drive an embedded applet is that changes to the interface can be made without the hassle of recompiling the Java code.

Discovering Interfaces

Many new programmers wonder how to find out what “hooks” are made available by a particular applet. An easy way to find out is to examine the source code (the .java file) associated with the applet. If it is not available, you can use a for/in loop on the appropriate Applet object to print out its properties. Anything that is not usually a property of an Applet browser object is a part of the interface defined by the applet’s class. However, this method is discouraged because it gives you no information about the type of arguments the applet’s methods expect. Generally, it’s not a good idea to drive an applet from JavaScript unless you know for sure how the interface it exposes should be used.

Type Conversion

The issue of type conversion in method arguments has serious bearing on JavaScript-driven applets. While most primitive JavaScript types are easily converted to their Java counterparts, converting complicated objects can be problematic. If you need to pass user-defined or non-trivial browser objects to applets, close examination of each browser’s type conversion rules is required. A viable option is to convert the JavaScript object to a string before passing it to an applet. The applet can then manually reconstruct the object from the string. A better option might be to retrieve the objects directly using the Java classes mentioned in the following section.

Security

A final issue is the fact that most browsers’ security models will prevent an applet from performing an action at the behest of JavaScript that the script could not otherwise perform on its own. This makes sense when one considers that Java is (in theory) designed to protect the user from malicious code. Experimentation with the restrictions placed on JavaScript-driven applets reveals inconsistent security policies among different browsers and versions.

Accessing JavaScript with Applets

Although it may come as a surprise, it is possible for Java applets to drive JavaScript. Internet Explorer, Netscape, and Mozilla-based browsers are capable of using the netscape Java package, which defines a family of class libraries for JavaScript interaction. In particular, the JSObject class (netscape.javascript.JSObject) allows an applet to retrieve and manipulate JavaScript objects in the current page. In addition, it affords an applet the ability to execute arbitrary JavaScript in the browser window as if it were a part of the page.

On the (X)HTML side of things, all that is required to enable this functionality is the addition of the mayscript attribute to the <<applet>> tag in question. The mayscript attribute is a nonstandard security feature used to prevent malicious applets from modifying the documents in which they are contained. Omitting this attribute (theoretically) prevents the applet from crossing over into “browser space,” though enforcement by browsers is spotty.

While this is a powerful capability, Java-driven JavaScript is rarely used in practice. Details about these classes can be found in Java documentation for the specific browsers.


Team LiB
Previous Section Next Section