JavaScript: The Definitive GuideJavaScript: The Definitive GuideSearch this book

Chapter 22. Using Java with JavaScript

Contents:

Scripting Java Applets
Using JavaScript from Java
Using Java Classes Directly
LiveConnect Data Types
LiveConnect Data Conversion
JavaScript Conversion of JavaObjects
Java-to-JavaScript Data Conversion

As we discussed in Chapter 14, Netscape 3 and later and Internet Explorer 4 and later both allow JavaScript programs to read and write the public fields and invoke the public methods of Java applets embedded in HTML documents. Netscape supports JavaScript interaction with Java applets through a technology known as LiveConnect. Internet Explorer instead treats every Java object (including applets) as an ActiveX control and uses its ActiveX scripting technology to allow JavaScript programs to interact with Java. Because Netscape's technology is specifically designed for communication between JavaScript and Java, it has some features that IE's ActiveX technology cannot provide. In practice, however, the two technologies are fairly compatible. Although this chapter is based on Netscape's LiveConnect, the key features it describes work in IE as well.[73]

[73]Note that Netscape 6 was released with poor support for LiveConnect but that it is fully implemented in Netscape 6.1 and later.

This chapter begins with a discussion of how you can use JavaScript to script Java applets, how your Java applets can invoke JavaScript code, and how (in Netscape only) you can use JavaScript to work directly with Java system classes. It then documents the nitty-gritty details of how LiveConnect works. It assumes you have at least a basic familiarity with Java programming (see Java in a Nutshell, by David Flanagan, and Learning Java, by Patrick Niemeyer and Jonathan Knudsen, both published by O'Reilly).

22.1. Scripting Java Applets

As discussed in Chapter 14, all Java applets embedded in a web page become part of the Document.applets[] array. Also, if given a name or id, an applet can be accessed directly as a property of the Document object. For example, the applet created by an <applet> tag with a name attribute of "chart" can be referred to as document.chart.

The public fields and methods of every applet are accessible to JavaScript as if they were the properties and methods of a JavaScript object. For example, if an applet named "chart" defines a field named lineColor whose type is String, a JavaScript program can query and set this field with code like this:

var chartcolor = document.chart.lineColor;  // Read an applet field
document.chart.lineColor = "#ff00ff";       // Set an applet field 

JavaScript can even query and set the values of fields that are arrays. Suppose that the chart applet defines two fields declared as follows ( Java code):

public int numPoints;
public double[] points; 

A JavaScript program might use these fields with code like this:

for(var i = 0; i < document.chart.numPoints; i++)
    document.chart.points[i] = i*i; 

This example illustrates the tricky thing about connecting JavaScript and Java: type conversion. Java is a strongly typed language with a fair number of distinct primitive types. JavaScript is loosely typed and has only a single numeric type. In the previous example, a Java integer is converted to a JavaScript number and various JavaScript numbers are converted to Java double values. There is a lot of work going on behind the scenes to ensure that these values are properly converted as needed. Later in this chapter, we'll consider the topic of data type conversion in detail.

In addition to querying and setting the fields of a Java applet, JavaScript can also invoke the methods of an applet. Suppose, for example, that the chart applet defines a method named redraw( ). This method takes no arguments and simply serves to notify the applet that its points[] array has been modified and it should redraw itself. JavaScript can invoke this method just as if it was a JavaScript method:

document.chart.redraw( ); 

JavaScript can also call methods that take arguments and return values. The underlying LiveConnect or ActiveX scripting technology does the work of converting JavaScript argument values into legal Java values and converting Java return values into legal JavaScript values. Suppose the chart applet defines Java methods like these:

public void setDomain(double xmin, double xmax);
public void setChartTitle(String title);
public String getXAxisLabel( ); 

JavaScript can call these methods with code like this:

document.chart.setDomain(0, 20);
document.chart.setChartTitle("y = x*x");
var label = document.chart.getXAxisLabel( ); 

Finally, note that Java methods can return Java objects as their return values, and JavaScript can read and write the public fields and invoke the public methods of these objects as well. JavaScript can also use Java objects as arguments to Java methods. Suppose the Java applet defines a method named getXAxis( ) that returns a Java object that is an instance of a class named Axis and a method named setYAxis( ) that takes an argument of the same type. Now, suppose further that Axis has a method named setTitle( ). We might use these methods with JavaScript code like this:

var xaxis = document.chart.getXAxis( );  // Get an Axis object
var newyaxis = xaxis.clone( );           // Make a copy of it
newyaxis.setTitle("Y");                   // Call a method of it...
document.chart.setYAxis(newyaxis);        // and pass it to another method

There is one complication when we use JavaScript to invoke the methods of a Java object. Java allows two or more methods to have the same name, as long as they have different argument types. For example, a Java object could declare these two methods:

public String convert(int i);     // Convert an integer to a string
public String convert(double d);  // Convert a floating-point number 

JavaScript has only one numeric type and doesn't distinguish between integers and floating-point values, so when you use JavaScript to pass a number to the method named "convert", it cannot tell which one you intended to call. In practice, this problem doesn't arise often, and it is usually possible to work around it by simply renaming the methods as needed. The latest versions of LiveConnect (in Netscape 6.1 and later) also allow you to disambiguate cases like this by including the argument types in the method name. For example, if the two methods above were defined by document.applets[0], you could disambiguate them like this:

var iconvert = document.applets[0]["convert(int)"];  // Get int method
iconvert(3);  // Invoke the method like this




Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.