Chapter 38

Integrating JavaScript and Java

by Rick Darnell


CONTENTS

In Chapters 34 through 37, you learned about how to make Java and JavaScript a part of your Web pages. Standing alone, they are significant developments in their capability to stretch the behavior of your pages far beyond what was ever imagined for the World Wide Web.

They can become even more powerful when harnessed together. As you'll recall from earlier discussions, although Java is powerful enough to add animation, sound and other features within the confines of an applet, it's very cumbersome to directly interact with an HTML page. JavaScript isn't big or powerful enough to match Java's programming power, but it is uniquely suited to work directly with the elements that comprise an HTML document. By combining the best features of both, your applet can interact with your Web page, offering a new level of interactivity for Java and JavaScript.

Setting the Stage

In order for Java and JavaScript to interact on your Web pages, they both have to be active and enabled in the user's browser. To make sure both features are active in Netscape Navigator, follow these simple steps:

  1. From the menu bar, choose Options | Network Preferences.
  2. From the Preferences box, select the Languages tab (see Figure 38.1).
  3. Both Java and JavaScript are enabled by default. If this has changed, make sure both boxes are selected.

Figure 38.1 : The Languages tab from Network Preferences controls whether Java applets and JavaScript commands are processed for HTML documents.

The process to make sure both languages are active in Microsoft Internet Explorer is similar to the steps for Navigator.

  1. From the menu bar, choose View | Options.
  2. From the Preferences box, select the Security tab (see Figure 38.2).
  3. Make sure Enable Java Programs is selected. The scripting languages available in Internet Explorer, JavaScript, and Visual Basic Script are automatically enabled. There is no way to disable them.

Figure 38.2 : Internet Explorer controls which language features are enabled from the Security tab in the Options dialog box.

Netscape Navigator also includes a Java Console for displaying applet-generated messages (see Figure 38.3). In addition to system messages such as errors and exceptions, it is where any messages generated by the applet using the java.lang.System package, including System.out.println, are displayed. To display the console, select Options | Show Java Console from the menu bar.

Figure 38.3 : The Java Console displays any system messages generated by the applet.

Microsoft Internet Explorer can show the results of system messages also but not in real time like the Navigator Java Console. All messages are saved in javalog.txt in C:\Windows\Java. To make sure this feature is active, select View | Options. In the Advanced tab of the dialog box that appears, make sure that the Java Logging box is selected.

Communicating with Java

The first and most commonly used feature of communication is to modify applet behavior from JavaScript. This is really quite easy to do with the right information, and allows your applet to respond to events on the HTML page, including interaction with forms. JavaScript-to-Java syntax is identical to other JavaScript object syntax, so if you're already familiar with this scripting language, adding Java control is an easy step.

Calling Java Methods

Using the new JavaScript Packages object, JavaScript can invoke native Java methods directly.

Note
Groups of related classes are combined in a construct called a package. Classes from a package are usable by outside classes by using the import command.
An example in all applets is the java package. One section of the package, java.awt.Graphics, is imported into every applet to give the paint method the additional methods it needs to add items to the applet screen. Because all applets are outside of the java package, its classes or subsets of those classes are imported into the applet for local use.

Note
Invoking native Java methods from JavaScript is only possible within Netscape Navigator 3.0 or later. It doesn't work on Microsoft Internet Explorer 3.0.

The syntax to call a Java package directly is


[Packages.]packageName.className.methodName

The object name is optional for the three default packages-java, sun, and netscape. These three can be referenced by their package name alone:


java.className.methodName

sun.className.methodName

netscape.className.methodName

Together with the package name, the object and class names can result in some unwieldy and error-prone typing. This is why you can also create new variables using the Package product:


var System = Packages.java.lang.System;

System.out.println("Hello from Java in JavaScript.");

Controlling Java Applets

Controlling an applet with a script is a fairly easy matter, but it does require a knowledge of the applet you're working with. Any public variable, method, or property within the applet is accessible through JavaScript.

Tip
If you're changing the values of variables within an applet, the safest way is to create a new method within the applet for the purpose. This method can accept the value from JavaScript, perform any error checking, then pass the new value along to the rest of the applet. This helps prevent unexpected behavior or applet crashes.

You need to know which methods, properties and variables are public. Only the public items in an applet are accessible to JavaScript.

Tip
There are two public methods which are common to all applets which you can always use-start and stop. These provide a handy means to control when the applet is active and running.

Note
There are five basic activities common to all applets, as opposed to one basic activity for applications. An applet has more activities to correspond to the major events in its life cycle on the user's browser.
None of the activities have any definitions. You must override the methods with a subclass within your applet.
Initialization-Occurs after the applet is first loaded. This can include creating objects, setting state variables, and loading images.
Starting-After initialization or stopping, an applet is started. The difference between initialization and starting is that initialization only happens once, while starting can occur many times.
Painting-This method is how the applet actually gets information to the screen, from simple lines and text to images and colored backgrounds. Painting can occur a lot of times in the course of an applets life.
Stopping-Stopping suspends the applet execution and stops it from using system resources. This can be important since an applet continues to run even after a user leaves the page.
Destroying-This is the extreme form of stop. Destroying an applet begins a clean-up process in which running threads are terminated and objects are released.

With this information in hand, getting started begins with the <APPLET> tag. It helps to give a name to your applet to make JavaScript references to it easier to read This isn't absolutely necessary as JavaScript creates an array of applets when the page is loaded. However, it does make for a much more readable page.


<APPLET CODE="UnderConstruction" NAME="AppletConstruction" WIDTH=60 HEIGHT=60>

</APPLET>

To use a method of the applet from JavaScript, use the following syntax:


document.appletName.methodOrProperty

Tip
Netscape Navigator 3.0 includes an applets array which is used to reference all of the applets on a page. These are used according to the following syntax.
document.applets[index].methodOrProperty
document.applets[appletName].methodOrProperty
These two methods also identify the applet you want to control, but the method using the applet's name without the applets array is the easiest to read and requires the least amount of typing.
Like the other arrays, a property of applets is length, which returns how many applets are in the document.
This array of applets is not currently available in the Microsoft Internet Explorer implementation of JavaScript.

One of the easy methods of controlling applet behavior is starting and stopping its execution. This can be accomplished using the start and stop methods-common to every applet. Use a form and two buttons to add the functions to your Web page (see Figure 38.4):


<FORM>

<INPUT TYPE="button" VALUE="Start" onClick="document.appletName.start()">

<INPUT TYPE="button" VALUE="Stop" onClick="document.appletName.stop()">

</FORM>

Figure 38.4 : One of the simplest methods of controlling an applet is to use buttons to start and stop it.

You can also call other methods, depending on their visibility to the world outside the applet. Any method or variable with a public declaration can be called by JavaScript.

Tip
Any variable or method within the applet which doesn't include a specific declaration of scope is protected by default. If you don't see the public declaration, it's not.

The syntax to call applet methods from JavaScript is simple and can be integrated with browser events such as the preceding button code snippet:


document.appletName.methodName(arg1,arg2,arg3)

Communicating with JavaScript

With the addition of a new set of classes provided with Netscape Navigator 3.0, Java can take a direct look at your HTML page through JavaScript objects. This requires the use of the netscape.javascript.JSObject class when the applet is created.

Tip
netscape.javascript.JSObject is included with the other class files under the Netscape directory. In Windows, this is \Program Files\Netscape\Navigator\Program\java\classes\java_30. In order for your Java program to compile, create a folder set called \netscape\javascript elsewhere on your hard drive, such as under the \java\lib folder. Copy the file to the new folder, and make sure your CLASSPATH variable includes C:\java\lib\ in its list. After you restart the computer, the Java compiler should be able to find the new classes. This new package extends the standard Java Object class, so the newly created JSObjects are treated the same as other Java objects are.

Tip
For normal use, the java package is all you need to use. The netscape package includes methods and properties for Java to reach out to JavaScript and HTML and is covered later in this chapter. The last package, sun, includes platform-specific and system utility classes.

Classes in the java Package
There are five subsets of classes within the java package:
lang-These classes and interfaces are the core of the Java language. This subset includes the Runnable interface (used for threading) and the basic data types (Boolean, character, class, integer, object, string, etc.). It also includes the System class, which provides access to system-level behaviors.
util-This group of utility interfaces and classes aren't crucial to running Java, but they provide ways to make programming easier. It includes utilities to generate random numbers, stacks, hash tables, and dates.
awt-The Abstract Windowing Toolkit (also known as Another Windows Toolkit) contains the graphical items to help create user interfaces and other graphical items. It includes interfaces for a layout manager and menu container, along with classes for form elements, colors, keyboard and mouse events, fonts, images, menus, and windows.
Io-Used for passing information in and out of applets and applications, this subset includes classes for sending and receiving input streams and files, not including networking activity (see net).
Net-This subset of classes has the tools and operations for working over a network. This group includes methods and interfaces to handle URLs, URL content, and socket
connections.

To include the JSObject class as part of your applet, use the import command as you would normally include any other class package.


import netscape.javascript.JSObject;

An important addition is also necessary in the applet tag-MAYSCRIPT. This is a security feature which gives specific permission for the applet to access JavaScript objects.


<APPLET CODE="colorPreview.class" WIDTH=50 HEIGHT=50 NAME="Preview" MAYSCRIPT>

Without it, any attempt to access JavaScript from the applet results in an exception. If you wish to exclude an applet from accessing the page, simply leave out the MAYSCRIPT parameter.

Java and JavaScript Values

JSObject gives Java the ability to look at and change objects defined through JavaScript. This requires certain assumptions, especially when passing or receiving values from Java. Every JavaScript value is assigned some form from java.lang.Object to ensure compatibility.

Note
A Java float is a 32-bit floating point number. A version for larger numbers or greater precision behind the decimal point is the double, which is 64 bits long. Bytes, shorts, ints, and longs are all integers of various bit lengths, beginning with 8 bits for the byte and going up to 64 bits for the long. A char is a 16-bit number representing a single Unicode character.

Looking at the JavaScript Window

In order to get a handle on JavaScript objects, including form items and frames, you must create an object to hold the current Navigator window first. getWindow provides the means.

First, you'll need to create a new: variable of type JSObject:


JSObject jsWin;

Then, using the JSObject class, assign the window to the variable:


jsWin = JSObject.getWindow(this);

This type of work is typically accomplished within the applet's init() method.

After you have a handle on the window, you can start to break it apart into its various components with getMember. This method returns a specific object from the next level of precedence. For example, to get a handle on a form on a Web page with a form called response, the following set of statements can be used:


jsWin = JSObject.getWindow(this);

JSObject jsDoc = (JSObject) jsWin.getMember("document");

JSObject responseForm = (JSObject) jsDoc.getMember("response");

In JavaScript, this form is referred to as window.document.response. Note that each JavaScript object is assigned to its own variable in Java and is not a property of a parent object. The form in Java is contained in responseForm, not jsWin.jsDoc.responseForm.

Note
All parts of an HTML document exist in JavaScript in set relationships to each other. This is called instance hierarchy since it works with specific items on the page rather than general classes of items.
At the top of the pyramid is the window object. It is the parent of all other objects. Its children include document, location, history, which share a precedence level. document's children include objects specific to the page, such as forms, links, anchors, and applets.
The Java netscape package recognizes and uses this hierarchy through its getWindow and getMethod methods. getWindow gets the window object (the highest object), while getMethod returns individual members of the next level.

So far, you've only retrieved broad objects, such as windows and forms. Getting a specific value from JavaScript follows the same principles, although now you need a Java variable of the proper type to hold the results instead of an instance of JSObject.

Tip
Don't forget about passing numbers between JavaScript and Java. All JavaScript numbers are converted to a float. You can cast it to another Java type if needed once it's in the applet.

Using the preceding form, let's say there's a text field (name), a number (idNum), and a checkbox (member). Each of these values is retrieved from JavaScript using the following commands:


jsWin = JSObject.getWindow(this);

JSObject jsDoc = (JSObject) jsWin.getMember("document");

JSObject responseForm = (JSObject) jsDoc.getMember("response");

JSObject nameField = (JSObject) responseForm.getMember("name");

JSOBject idNumField = (JSObject) responseForm.getMember("idNum");

JSOBject memberField = (JSObject) responseForm.getMember("memberField");

String nameValue = (String) nameField.getMember("value");

Float idNumValue = (Float) idNumField.getMember("value");

Boolean memberValue = (Boolean) memberField.getMember("checked");

This chunk of code becomes a bit unwieldy, especially when there are several values needed from JavaScript. If you need to access more than several elements on a page, it helps to create a new method to handle the process.


protected JSObject getElement(String formName, String elementName) {

    JSObject jsDoc = (JSObject) JSObject.getWindow().getMember("document");

    JSObject jsForm = (JSObject) jsDoc.getMember(formName);

    JSObject jsElement = (JSObject) jsElement.gerMember(elementName);

    return jsElement;

}

This simple method creates the intervening JSObjects needed to get to the form element, making the retrieval as easy as knowing the form and element name.

To change a JavaScript value, use the JSObject setMember method in Java. The syntax is setMember(name, value), with the name of the JavaScript object and its new value.


JSObject nameField = getElement("response","name");

nameField.setMember("name","Your Name Here");

This snippet uses the getElement method just defined to get the name element from the response form, and then uses the JSObject method setMember to set its value to Your Name Here. This is equivalent to this.name = newValue in JavaScript.

The two methods covered in this section (getWindow, getMember), are the basic methods used when interfacing with JavaScript. Together, it makes receiving values from an HTML page by way of JavaScript a straightforward task, even if it is a little cumbersome in the number of statements needed to accomplish it.

Getting Values Using Indexes

If your applet is designed to work with a variety of HTML pages which may contain different names for forms and elements, you can use the JavaScript arrays with the JSObject slot methods. If the desired form is always the first to appear on the document and the element is the third, then the form name is forms[0] and the element is elements[2].

After retrieving the document object using getWindow and getMember, use getSlot(index) to return a value within it. For example, in an HTML document containing three forms, the second is retrieved into Java using the following commands:


JSOBject jsWin = JSObject.getWindow(this);

JSObject jsDoc = (JSObject) jsWin.getMember("document");

JSObject jsForms = (JSObject) jsDoc.getMember("forms");

JSObject jsForm1 = (JSObject) jsForms.getSlot(1);

Using setSlot, the same process is used to load a value into an array. The syntax is


JSObject.setSlot(index,value);

where the index is an integer and the value is a string, Boolean or float.

Tip
The one rule which must stand firm in this case is the placement of the form and elements within it. When the applet is used with more than one document, the forms and elements must be in the same relative place every time to avoid exceptions and unpredictable results.

Using JavaScript Methods in Java

The netscape class package provides two methods to call JavaScript methods from within an applet-call and eval. The syntax between the two is slightly different, but the outcome is the same. Note that you need a handle for the JavaScript window before you can use these methods.

There are two ways to invoke these methods. The first uses a specific window instance, while the second uses getWindow to create a JavaScript window just for the expression.


jsWin.callOrEval(arguments)

JSOBject.getWindow().callOrEval(arguments)

The call method separates the method from its arguments. This is useful for passing Java values to the JavaScript method. The syntax is call("method", args), where the method is the name of the method you want to call and the arguments you want to pass are contained in an array.

eval, on the other hand, uses a string which appears identical to the way a method is called within JavaScript. The syntax is eval("expression"), where the expression is a complete method name and its arguments, such as document.writeln("Your name here.'"). Including it in the eval expression results in eval("document.writeln(\"Your name here.\");").

Tip
To pass quotation marks as quotation marks to JavaScript within a Java string, use the backslash character before each occurrence.

Now you have a whole set of tools to get from JavaScript to Java and back again. The marriage of these two Web technologies can open up a whole new world of how to interact with your users. Using simple statements and definitions-already a part of both languages-a previously static Web page can communicate with an applet imbedded in it, and in return react to the output of the applet. It's just one more set of capabilities in your toolbox that you can use to meet your users' needs.

Summary

The last logical step with Java and JavaScript is allowing them to work and communicate with each other. Accessing an applet's methods and public variables from JavaScript and allowing the Java applet to take a look and modify HTML through JavaScript objects extends the capability of both languages, although it still doesn't allow either one to be the complete equal.

As described in Chapter 36, "Including Java Applets in Your Web Pages," Java and JavaScript are tailored to different types of applications. But by being able to coordinate activities between the two, you can extend the interactivity of your Web pages to more powerful and useful levels.