JAVA,  JAVASCRIPT AND  PLUG-I INTERACTION USING  CLIENT-SIDE  LIVECONNECT

REAZ HOQUE, TECHNOLOGY EVANGELIST
 
ABSTRACT
 
This Netscape TechNote describes how to use LiveConnect. First, we will explore how to use JavaScript to communicate with a Java applet and a Navigator plug-in. Next, we will see how to use Java to communicate with JavaScript and a plug-in.  Please note that this TechNote assumes that you are already familiar with Java and JavaScript basics and that you want to extend your knowledge to advanced Java/JavaScript programming. The examples presented here work in Navigator 3.0 and 4.0, exceptions are stated below.


TABLE OF CONTENTS
 

Introduction
Calling a Java Applet From JavaScript (for Navigator 4.0+)
Communicating with a Plug-in From JavaScript
Calling JavaScript from Java
Communicating with a Plug-in from Java
Conclusion
Resources
 

INTRODUCTION
 
LiveConnect is a technology that lets JavaScript, Java and plug-in talk to one another.  You can use JavaScripts to communicate with Netscape Navigator plug-ins and Java applets and Java applets communicate with JavaScript and plug-ins. To use LiveConnect, you need a browser that supports this technology such as Netscape Navigator 3.0 and higher. LiveConnect can also be used on the server, but this this TechNote will talk about only the client side LiveConnect.  To learn more about server-side LiveConnect, please see documentation on server-side LiveConnect.

LiveConnect is interesting to the developers because it is an invisible architecture that runs in the background.  All the things that happens when you, for example, try to communicate with an applet from JavaScript, happen in the Navigator engine in the background.  Therefore there is not much extra work to be done to use LiveConnect!

As a JavaScript programmer, you don't need to do anything special with your code to use LiveConnect.  You use the same JavaScript statements and functions.  However, for Java applets and plug-ins, you need to make sure that these objects are LiveConnect aware.  We will explore what that means in detail later in this TechNote.

So what can you do with LiveConnect?  Suppose you have a Java applet that animates text, and you wish to set that text using JavaScript.  Using HTML, create a text box which takes text input from the user.  With LiveConnect, you can transfer that text to the applet which will then display the new text. Or if you have an audio and video player plug-in installed, using LiveConnect, you can click a button to cue separate video and audio files to play simultaneously.  In this scenario, the audio file can provide synched narration and score. Alternatively, clicking a button can bring up an audio-only introduction, which in turn can trigger a movie to run.

This powerful technique makes it possible to create live, multimedia savvy pages using core Netscape ONE technologies such as HTML, Java, JavaScript and Plug-ins. An article from Information Week stated:

"With LiveConnect, developers can finally do serious, interesting software development on the client side of the Web as well. The potential applications of LiveConnect are innumerable."
                                               - Internet view: An Application Infrastructure  by Jason Levitt
                                                 Information Week, June 3, 1996

LiveConnect (both client and server) makes it possible to design Web pages with a new and more dynamic level of interactivity by enabling:

Before we begin, please set the following preferences:

CALLING A JAVA APPLET FROM JAVASCRIPT

For JavaScript to be able to control a Java applet, the Java applet must provide public methods. The methods of an applet are the functions which are associated with its class. Public methods are functions which are externally visible and can be called by other Java classes and by JavaScript. Well-written Java applets will provide public methods to make basic properties readable and write able by other code. This makes it possible to customize and reuse existing Java applets without modifying the applet's source code.

The LiveConnect-enabled applet we will be talking about here takes text, URL, font size, font color and font type as its parameters and animates the text. Please take a look at the example before you look at the code below.

Here are the public methods which make it possible to control the applet from JavaScript:

(Note: there are two classes for this applet: fade.class and thoughts.class.  When we compile the .java file these files are created with one class in each)

public void setBackgroundColor(int R, int G, int B)
  {
        thoughts.SetBackground(R,G,B);
        bgChange=true;
        repaint();
  }

  public void setFontColor(int R, int G, int B)
  {
        thoughts.SetTextColor(R,G,B);
  }

  public void setAnimateSpeed(int speed)
  {
        thoughts.SetChangeFactor(speed);
  }

  public void setText(int which,String text)
  {
        bgChange=true;
        thoughts.theThoughts[which]=text;
        thoughts.Reset();
  }

  public void setUrl(int which,String url) throws MalformedURLException
  {
        thoughts.theUrls[which]=new URL(url);
  }

  public void setFont(int which,Font font)
  {
        bgChange=true;
        thoughts.theFonts[which]=font;
        thoughts.Reset();
  }

Each function is passed one or more parameters that manipulate the applet in a different way.  For example, to display text that will be animated by the applet, we pass the text, such as, "Hello World", to the function setText() like this: setText('Hello World').

CREATING THE USER INTERFACE:

Now we create the HTML page in which the applet is embedded.  This page will also need some form elements to communicate with the applet.  Here is how we embed the applet:
 
<applet code="Fade.class" name="fader" width=400 height=100>
<param name="text1" value="Look at this text carefully">
<param name="url1" value="http://www.netscape.com">
<param name="font1" value="Helvetica,PLAIN,36">
</applet>
 
Notice that we name the applet (name="fader") so that it is easier to call the applet from JavaScript.  You can however call unnamed applets using array indexing (for example,. document.applets[0], document.applets[1] etc.).

Now we create the following text boxes:

Text:
<input type="text" size=50 value="Look at this text carefully" name="text_val"
   onChange="fader.setText(0,myform.text_val.value)">

URL:
<input type="text" size=50 value="http://www.netscape.com/" name="url"
   onChange="fader.setUrl(0,myform.url.value)">

As you can see there are two text boxes which take the text to display and the URL address for handling mouse clicks on the applet's window area. To change the text that the applet displays, we use the OnChange event handler which calls the public Java applet's function setText(). Note how we pass the value of the text field to the event handler.  What happens here is simple, we retrieve the form named myform, its property text_val, and then the property of text_val called value. To assign the new URL address we use the same process, but call the setURL() function.

To change the font type, the event handler sets variable fontName to the value from the text box, then calls the JavaScript function doFont().  Here we are using the onBlur event handler so that right after the text box loses cursor focus, the value is passed on to the fontName variable. We will talk about this variable and the doFont() function in a little bit. Here is the code:

<br>Name:
<input type="text" size=50 value="Helvetica" name="font_Name"
   onBlur="fontName=myform.font_Name.value;doFont()">

Lastly, we have some pull down menus so that you can set the the background color, font size, font style and animation speed.

For the size of the font, we use the onChange event handler, so that when you choose one of the options from the menu, the handler argument gets invoked.  For the handler argument, we assign the selection value that is chosen to the variable fontSize. As before, we also call the doFont() function.  You may have noticed that we take the selection value and multiply it by 1.  Why? To make sure that JavaScript knows that the value for fontSize is actually an integer, not a string. Here is the code:

Size:
<select name="font"
   onChange="fontSize=this.options[this.selectedIndex].value*1;doFont()" >

<option value="12"> 12
<option value="18"> 18
<option value="24"> 24
<option value="36" selected> 36
</select>
 
When the user selects a font style from the style pull down menu, the onChange event handler assigns that selection value to the fontStyle variable and calls the doFont() function. Here is the code:

Style:
<select name="style"
  onChange="fontStyle=eval('Font.'+this.options[this.selectedIndex].value); doFont()" >

<option value="PLAIN">Plain
<option value="BOLD">Bold
<option value="ITALIC">Italic
</select>

To set the animation speed using the pull down menu called speed, we again use the onChange event handler.  When a selection is made, the event handler calls the applet's setAnimateSpeed() method and passes the selection value.  Note that we multiply again by 1 to make sure that an integer is passed to the function, not a string. Take a look at the code:

Animation Speed:
<select name="speed"
    onChange="fader.setAnimateSpeed(this[this.selectedIndex].value*1)" >

<option value="1"> 1
<option value="2"> 2
<option value="3"> 3
</select>

Similarly, to set the background color for the applet, the onChange event handler calls the Applet's public method setBackgroundColor().  The value of the selection is passed to this method which changes the applet's background color immediately. Here is the code: 

Background:
<select name="bg"
  onChange= "eval('fader.setBackgroundColor('+this[this.selectedIndex].value+')')" >

<option value="0,0,0">Black
<option value="255,0,0">Red
<option value="0,255,0">Green
<option value="0,0,255">Blue
<option value="255,255,255">White
</select>

WRITING THE BACKEND CODE:

Now let's look at some of the JavaScript code that works in the background:

<SCRIPT LANGAUGE="JavaScript1.2">

// Note that we are using JavaScript 1.2 extension
// in the script tag as the function doFont()
// uses JS 1.2 feature (function constructor).
// Therefore this example must be run in Navigator 4.0+.
 

var fader;
var Font=java.awt.Font;
var fontName='Helvetica';
var fontStyle=Font.PLAIN;
var fontSize=36;

function onload() {  // wait for the applet reflection

  fader=document.applets.fader

}

function doFont() {

  fader.setFont(0,Font(fontName,fontStyle,fontSize)) // this construct is 1.2 specific
 
/*
Note that we already defined font above.
You can also do "new Font(...)" when constructing.
*/
}
</SCRIPT>

First we declare some global variables (remember that these are the same variables that we assigned values to from the HTML form) and a JavaScript object called Font.  The Fontobject is created using the Java AWT (Abstract Window Toolkit) Font class.  The onload() function assigns the applet to the global variable fader as soon as the the page is loaded.

The doFont() JavaScript function uses the setFont() method of the applet to set the font name, style and size. Note that we used a function constructor here to convert the font object into a number.

Note:  The applet discussed here was one that was originally written by Giuseppe Gennaro.  Because the applet did not exhibit public methods, the applet was modified by Sankalp Acharya & Henri Torgemane of Netscape.  Take a look at the initial .java file and the modified .java  file to see how the LiveConnect-enabled Java file was effected. 
 

COMMUNICATING WITH A PLUG-IN FROM JAVASCRIPT

There are several plug-ins by various vendors that are LiveConnect aware.  These plug-ins can be manipulated via JavaScript or Java. In this example we will use the LiveAudio plug-in which comes with Communicator.  LiveAudio can play sound files such as .wav, .aif, .midi, etc.  In our example we will have JavaScript controls that will stop and play a LiveAudio file from an HTML page.

First we embed the LiveAudio file (a midi file) like this:
 
<EMBED
SRC="sound.mid"
HIDDEN=TRUE
NAME="Mysound"
MASTERSOUND
AUTOSTART=NO
LOOP=NO>

Note that we must use the <EMBED> tag inside the <BODY> of the HTML file.  We name the object just like any other object in the HTML file so that it is easier to call it from JavaScript. The attributes in the <EMBED> tag  manipulate the file and the plug-in just like a Java applet.  For example, if want to file to play in a loop you can set LOOP=YES.  Notice that we use the HIDDEN=TRUE so the small sound player widow in the HTML page is hidden.
 
The LiveAudio plug-in has callable public methods.  The information about these methods can be found at the LiveAudio homepage.  In our example we will only call the stop() and play() methods. So we create two buttons:

<form>
<input type="button" value="Play Sound" onClick="document.Mysound.play(false)">
<input type="button" value="Stop Sound" onClick="document.Mysound.stop()">
</form>

When the buttons are clicked the onClick event handlers call the play() and stop() methods which plays and stops the file respectively.
 

Why would a Java programmer use LiveConnect to communicate with JavaScript?  Today,  Java applets on the client side can directly communicate with other Java applets using either LiveConnect and BeanConnect.  With LiveConnect, you can make the connection possible via JavaScript. Most importantly, as you know, there are many JavaScript features (window control, browser information, etc.) that are not exposed to Java.  So with the communication between Java and JavaScript using LiveConnect, you have more flexibility to create interactive, live pages.

To give you an example of Java communicating with JavaScript, let's assume that there are two applets: one verifies user name and password from a database and another display an animated greeting.  You can now use JavaScript to capture the user name from the first applet after the user successfully logs on to a page.  Later you can pass that value to the other applet which can then animate the string.  It is also possible to pass the user name from the first applet to JavaScript which can set a cookie in the browser (for state maintenance).

To control JavaScript from Java, LiveConnect uses the netscape.javascript.JSObject class.  All the interactions with JavaScript are accomplished through this class.  Note that because all JavaScript objects must appear in a hierarchical manner in the browser window, the class must also appear in the hierarchy.

The class has the following methods:

The class also has a static method: To see how to use any of these methods, let's take the call method as an example.  This method does the same as the statement this.methodName(args[0], args[1], ...) in JavaScript. To use the method, you would follow the following instruction in Java:

public Object call(String methodName, Object args[])

To learn more about the netscape.javascript.JSObject class, see the JavaScript documentation.

To understand how JavaScript and Java can interact on an HTML page using LiveConnect, please refer to the Java example: HitManApplet.
 

COMMUNICATING WITH A PLUG-IN FROM JAVA
 
To demonstrate how to communicate with a plug-in from Java, we will again use the LiveAudio plug-in.  We will create an applet that has two buttons which call the play() and stop() methods.  Remember that these are the same public methods that we called from JavaScript.  Here we are just replacing the HTML buttons and JavaScript code with a Java applet. Before I walk you through the code, please take a look at the example.

First we need to embed the plug-in file, just like we did before.  Again we use the <EMBED> tag and name our embedded object as mySound.

Next we embedded the Java class file like this:

<applet MAYSCRIPT code="CallPlugin2.class" width=200 height=40>
<param name="plugin" value="Mysound">
</applet>

Here MAYSCRIPT opens the LiveConnect communication channel between the Java applet and the plug-in. Notice that we have assigned the value Mysound for the parameter named plugin.

Now, if you take a look at the .java  file for this applet, you will notice that we have the following line of code in the file:

 SoundPlayer plugin;
 Button play = new Button("Play Sound");
 Button stop = new Button("Stop Sound");

We first declared an object of class SoundPlayer. This class is not in the standard Java package. That is the reason we need to add the path of the plugin class into the class path before being able to compile it. The last two lines declare and instantiate our two buttons.

Next we create a function called init() which initiates the applet. In the function, we first declare two object of class netscape.javascript.JSObject. These objects are used as an interface between JavaScript and Java. We need javascript here to get the plugin object from the document. The first object, win refers to the JavaScript window object and second object, doc refers to the JavaScript document object. Take a look at the code:

   JSObject win,doc;

   win=JSObject.getWindow(this);
   doc=(JSObject)win.getMember("document");

We have another object called plugin. Here we first look at what the parameter 'plugin' contains (defined with <param name="plugin" value="Mysound"> ), then we access the member Mysound. In JavaScript we would call the same code in HTML like this: plugin=doc.Mysound. Here is the code:

    plugin=(SoundPlayer)doc.getMember(getParameter("plugin"));
 
 
Tip:  You can also do:  

    plugin = (Plugin) win.eval("document.plugin") 

The limitation on using JSObject.eval() comes when you need to pass objects into JavaScript and preserve them as objects (i.e. not convert them to strings).  There are two ways to do this: either put the object in a JavaScript variable using setProperty and then refer to that variable in the eval string, or pass the object as an argument through JSObject.call().

 

The last two lines in the function simply put the buttons in the applet:

   this.add("left",play);
   this.add("right",stop);

Now we create another function called handleEvent(). This function calls the play() plug-in method when the play button is clicked from the HTML page. At the end, the function returns true. On the other hand, when the stop button is clicked then the stop() method is called and the function returns true.  If no button is clicked then the function returns  false. Take a look at the code:

 public boolean handleEvent(Event e) {
   if (e.id==Event.ACTION_EVENT) {
     if (e.target==play) {
    plugin.play();
    return true;
  }
  if (e.target==stop) {
    plugin.stop();
    return true;
  }
   }
   return false;
 }

That's it!  We then compile the file and just embed the new complied .class file in the HTML page as shown earlier.
 

 
 CONCLUSION
 
As you can see these examples are pretty simple. All you have to remember is that, if the public methods of an object are available for a script or an applet to be invoked, that object is LiveConnect-enabled. That's all! Please download the example files.


RESOURCES
 
Other LiveConnect Examples
Accessing JavaScript from Java using LiveConnect
Java Applet to Plug-in Communication
 
Documentation
Java Documentation 
Netscape IFC
Tools to Create Java Applets
Java Language Course
Documentation: JavaScript 1.2
Documentation: JavaScript 1.1

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

Member's Resource
Java Newsgroup

Web Site
JavaScript Resources A 2 Z
Original Fade Applet

TN-JSCR-03-9707

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.