All Categories :
Java
Chapter 37
Integrating Java and JavaScript
by Rick Darnell
CONTENTS
You've learned a lot so far about how to make Java a part of your
Web pages. Standing alone, Java is a significant development because
of its ability to stretch the behavior of your Web pages far beyond
what was ever imagined for the World Wide Web.
Java can become even more powerful when harnessed with JavaScript.
As you know from other chapters, although Java is powerful enough
to add animation, sound, and other features to 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 Java and JavaScript, your
applet can interact with your Web page, offering a new level of
interactivity.
For Java and JavaScript to interact on your Web pages, they both
must be active and enabled in the user's browser.
To make sure that both features are active in Netscape Navigator
when the user views Java applets, include these simple directions:
- Choose Options, Network Preferences from the menu bar. The
Preferences dialog box appears.
- Select the Languages tab from the Preferences dialog box (see
Figure 37.1).
- Both Java and JavaScript are enabled by default. If this has
changed, make sure that both checkboxes are selected.
Figure 37.1: The Languages tab in the Network Preferences dialog box controls whether or not Java applets and JavaScript commands are processed for HTML documents.
The steps to include to make sure that both languages are active
in Microsoft Internet Explorer are similar to the steps for Navigator:
- Choose View, Options from the menu bar. The Options dialog
box appears.
- Select the Security tab from the Options dialog box (see Figure
37.2).
- Make sure that the Enable Java Programs checkbox is selected.
The scripting languages available in Internet Explorer, JavaScript,
and VBScript are automatically enabled; there is no way to disable
them.
Figure 37.2: Internet Explorer controls which language features are enabled from the Security tab in the Options dialog box.
Note |
Netscape Navigator also includes a Java Console for displaying applet-generated messages (see Figure 37.3). In addition to system messages such as errors and exceptions, the Java Console 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 Netscape Navigator menu bar.
Microsoft Internet Explorer can show the results of system messages also, but not in real time as Navigator's Java Console can do. All messages are saved in javalog.txt in C:\Windows\Java. To make sure that this feature is active, select View, Options from the menu bar, select the Advanced tab in the Options dialog box, and make sure that the Java Logging checkbox is selected.
|
Figure 37.3: The Java Console displays any system messages generated by the applet.
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 it allows your applet to
respond to events on the HTML page, including interacting with
forms.
Java object syntax is very similar 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
With Navigator 3.0, Netscape is providing a brand-new, never-before-seen
object called Packages; the
Packages object allows JavaScript
to invoke native Java methods directly. This object is used in
much the same way as the Document
or Window objects are in
regular JavaScript.
Note |
As you'll recall from earlier discussions, groups of related classes are combined in a construct called a package. Classes from a package can be used by outside classes by using the import command.
Just to confuse things, that's not the case with the JavaScript version of Packages. In JavaScript, Packages is the parent object used to invoke native Java methods, such as Packages.System.out.println("Say Howdy").
|
Caution |
Invoking native Java methods from JavaScript is possible only within Netscape Navigator 3.0 or later. Microsoft Internet Explorer doesn't include support for the JavaScript-to-Java packages in its 3.0 release, but may include its own version of this capability in later versions.
The source of the problem is that JavaScript is implemented individually for each browser; what Netscape includes for JavaScript isn't the same as what Microsoft includes. In the fast-paced world of browsers, however, you can expect Microsoft to catch up quickly.
|
Internet Explorer still includes support for all the now-standard
features of JavaScript, including control and manipulation of
windows, documents, and forms.
Here is the syntax to call a Java package directly:
[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, as
shown here:
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. The following code assigns a Java package to the variable
System and then uses the
System variable to call a
method in the package:
var System = Package.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 some 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 to do so is to create a new method within the applet for the purpose. This method can accept the value from JavaScript, perform any error checking, and then pass the new value along to the rest of the applet. This arrangement helps prevent unexpected behavior or applet crashes.
|
You have to know which methods, properties, and variables in the
applet are public. Only the public items in an applet are accessible
to JavaScript.
Tip |
Two public methods are common to all applets and you can always use them-start() and stop(). These methods provide a handy way to control when the applet is active and running.
|
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. Here
are the five activities common to all applets:
- Initialization. Occurs after the applet is first loaded.
This activity can include creating objects, setting state variables,
and loading images.
- Starting. After being initialized or stopped, an applet
is started. The difference between being initialized and starting
is that the former only happens once; the latter can occur many
times.
- Painting. The paint()
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 applet's
life.
- Stopping. Stopping suspends applet execution and stops
the applet from using system resources. This activity can be an
important addition to your code because an applet continues to
run even after a user leaves the page.
- Destroying. This activity 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. The following snippit of code
shows the basic constructor for an HTML applet tag that sets the
stage for JavaScript control of a Java applet. The tag is identical
to the tags you used in previous chapters to add applets, except
that a new attribute is included for a name:
<APPLET CODE="UnderConstruction" NAME="AppletConstruction" WIDTH=60 HEIGHT=60>
</APPLET>
Assigning a name to your applet isn't absolutely necessary because
JavaScript creates an array of applets when the page is loaded.
However, doing so makes for a much more readable page.
Caution |
Like the JavaScript Packages object, the JavaScript applets array is currently available only in Netscape Navigator 3.0 or later. This doesn't leave Microsoft Internet Explorer completely out in the cold-JavaScript can still reference an applet in Explorer using the applet's name.
|
To use a method of the applet from JavaScript, use the following
syntax:
document.appletName.methodOrProperty
Tip |
Netscape Navigator 3.0 uses an applets array to reference all the applets on a page. The applets array is 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 other arrays, one of the properties 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 3.0 implementation of JavaScript.
|
One of the easy methods of controlling applet behavior is starting
and stopping its execution. You start and stop an applet using
the start() and stop()
methods that are common to every applet. Use a form and two buttons
to add the functions to your Web page (see Figure 37.4). The following
code snippet is a basic example of the HTML code needed to add
the buttons, with the name of the applet substituted for appletName.
Figure 37.4: One of the simplest methods of controlling an applet is to use buttons that start and stop it.
<FORM>
<INPUT TYPE="button" VALUE="Start" onClick="document.appletName.start()">
<INPUT TYPE="button" VALUE="Stop" onClick="document.appletName.stop()">
</FORM>
You can also call other methods, depending on their visibility
to the world outside the applet. JavaScript can call any method
or variable with a public
declaration.
Tip |
Any variable or method within the applet that 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 button code
snippet just shown. The basic syntax for calling an applet method
from Java is shown here:
document.appletName.methodName(arg1,...,argx)
To call the stop() method
from the underConstructionApplet
applet within an HTML page, the syntax is as follows (assuming
that the applet is the first one listed on the page):
document.underConstructionApplet.stop();
Here's how you do it with Navigator (again, assuming that the
applet is the first one listed on the page):
document.applets[0].stop();
Integrating the start() and
stop() methods for this applet
with the applet tag and button code snippet used earlier results
in the following code:
<APPLET CODE="UnderConstruction" NAME="underConstructionApplet" WIDTH=60 ÂHEIGHT=60></APPLET>
<FORM>
<INPUT TYPE="button" VALUE="Start" ÂonClick="document.underConstructionApplet.start()">
<INPUT TYPE="button" VALUE="Stop" ÂonClick="document.underConstructionApplet.stop()">
</FORM>
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. To implement this functionality, you must
import the netscape.javascript.JSObject
class when the applet is created.
Tip |
In most applets, the java package is all you need. The netscape package includes methods and properties for Java to reach out to JavaScript and HTML (as covered later in this chapter). The last package, sun, includes platform-specific and system utility classes.
|
Tip |
The netscape.javascript.JSObject class is included with the other class files in the Netscape folder in the java_30 file. In Windows, the complete location is \Program Files\Netscape\Navigator\Program\java\classes. To enable the Java compiler to find the packages, you'll have to create a new set of folders under \Java\Lib called \netscape\javascript and then copy java_30 to the new location. The netscape.javascript.JSObject class extends the standard Java Object class, so the newly created JSObject objects are treated as other Java objects.
|
To include the JSObject class
as part of your applet, use the import
command as you normally do to include any other class package:
import netscape.javascript.JSObject;
Another important addition is necessary in the applet tag-MAYSCRIPT.
This security feature gives specific permission for the applet
to access JavaScript objects. Here's how to include the tag:
<APPLET CODE="colorPreview.class" WIDTH=50 HEIGHT=50 NAME="Preview" MAYSCRIPT>
Without the MAYSCRIPT parameter,
any attempt to access JavaScript from the applet results in an
exception. If you want to exclude an applet from accessing the
page, simply leave out the MAYSCRIPT
parameter.
Java and JavaScript Values
The JSObject class 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. To ensure compatibility,
every JavaScript value is assigned some form from java.lang.Object:
- Objects. Any object sent or received from Java remains
in its original object wrapper.
- Java numbers. Because JavaScript doesn't support the
variety of numerical types Java does (byte,
char, short,
int, long,
float, and double),
numerical types lose their specific type and become a basic JavaScript
number.
- JavaScript numbers. There's no way to tell what kind
of number Java may be receiving from JavaScript, so all JavaScript
numbers are converted to Java float
types.
- Booleans and strings. These types are passed essentially
unchanged. Java booleans
become JavaScript booleans
and vice versa. The same is true for strings.
Looking at the JavaScript Window
To get a handle on JavaScript objects-including form items and
frames-you must first create an object to hold the current Navigator
window. The getWindow() method
provides the means.
First, you have 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);
Tip |
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, you can
use the following set of statements:
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 in jsWin.jsDoc.responseForm.
Note |
All parts of an HTML document exist in JavaScript in set relationships to each other. This arrangement is called instance hierarchy because 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, and history, which share a precedence level. The document object'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. The first gets the window object (the highest object); the latter returns individual members of the next level.
|
So far, you've retrieved only 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 the value is in the applet.
|
Using the form described earlier in this section, suppose that
there is a text field (name),
a number (idNum), and a checkbox
(member). You can retrieve
each of these values 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 you
need several values from JavaScript. If you need to access more
than several elements on a page, it can help to create a new method
to handle the process.
The getElement() method defined
in the next code snippet accepts the name of a form and element
on an HTML page as arguments and returns a JSObject
that contains it:
protected JSObject getElement(String formName, String elementName) {
JSObject jsDoc = (JSObject) JSObject.getWindow().getMember("document");
JSObject jsForm = (JSObject) jsDoc.getMember(formName);
JSObject jsElement = (JSObject) jsElement.getMember(elementName);
return jsElement;
}
This simple method creates the intervening JSObject
objects needed to get to the form element, making the retrieval
as easy as knowing the form and element name. If the form or form
element is not included on the page, the method throws an exception
and halts the applet.
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.
The following 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 the this.name
= newValue statement in JavaScript.
JSObject nameField = getElement("response","name");
nameField.setMember("name","Your Name Here");
The getWindow() and getMember()
methods just described are the basic methods used when interfacing
with JavaScript. Together, they make receiving values from an
HTML page with JavaScript a straightforward task-even if the process
is a little cumbersome in the number of statements required.
Getting Values Using Indexes
If your applet is designed to work with a variety of HTML pages
that 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 shown
here:
JSObject.setSlot(index,value);
There are two ways to invoke these methods. The first uses a specific
window instance; the second uses getWindow()
to create a JavaScript window just for the expression:
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.
By using simple statements and definitions-already a part of both
languages-you can make a previously static Web page communicate
with an applet embedded in it; in return, the Web page can react
to the output of the applet.
JavaScript-to-Java communication is a simple extension of JavaScript's
functionality. As long as your applets have names, any applet's
public method is accessible
to your HTML page. And using the new Netscape package netscape.javascript
makes the process a two-way street, allowing your Java applet
to invoke JavaScript functions and look at the structure of your
Web page as represented by the JavaScript document object.
This combination is one more set of capabilities in your toolbox
that you can use to meet your users' needs.