Sun Java Solaris Communities My SDN Account Join SDN
 
Java Plug-in 1.3 Documentation

Java Plug-in Scripting

 

Using JavaBeans with Microsoft ActiveX Components

JavaBeans components may be used as embedded objects or Microsoft ActiveX components within applications such as Microsoft Office, Internet Explorer, and Visual Basic. This document provides an overview of the Java Plug-in that acts as a bridge and instructions on how to package and register JavaBeans as ActiveX components.

This mechanism permits applets to be accessed from Javascript within Internet Explorer. Unfortunately the current Netscape Plug-in APIs do not permit scripting of Plug-ins within Netscape Navigator. However Sun and Netscape are working together to implement a new interface ("OJI") that will permit full scripting of Java Plug-in in future releases of Netscape Navigator.

Overview

To use a JavaBean as an embedded object, you package the JavaBean and then use it as an ActiveX component. A registry file (text file) and a type library are created by the packager. This registry contains an object id, the executable path for the component, bridge information, and a type library path. The TypeLib file is a binary file that describes each component's properties, events, and methods.

Packaging and Registration

Step 0:  Start the Packager

To open the packager, run the following command from your Java Plug-in installation directory (in most cases this will be c:\program files\javasoft\jre\1.3\):

bin\java.exe -cp lib\jaws.jar sun.beans.ole.Packager

The packager will guide you through five steps to package your JavaBean.

Step 1:  Specify the JAR File

Specify the JAR file that contains the JavaBean to be packaged and press Next.

Step 2:  Select the JavaBeans Component

The packaging tool lists all the JavaBeans inside the JAR file you specified in step 1. Select the JavaBean to be packaged and press Next.

Step 3:  Specify an ActiveX Name

The packaging tool suggests an ActiveX name for the JavaBean. This name will be used in the ActiveX environment to refer to the component. The packager gives you a default name (the name of the JavaBean minus its java package name prefix).

Step 4:  Specify an Output Directory

The packager creates a registry file (.reg) and a type library (.tlb) in a directory that you specify. Note that the registry file contains information on the location of the type library file. If you move the type library file, you will need to manually update the registry file and register it again. The location of the beans.ocx (Java Plug-in ActiveX component) is determined from the registry settings of the Java Plug-in installation. Again, if you move the beans.ocx, you will need to manually modify this file.

.

Step 5:  Start Generation

The packager can automatically register the component for you on the local machine. If you choose to register the registry file, the JavaBeans component will be automatically useable in an ActiveX container.

Command Line Options

The packager can be invoked from the command line with the following arguments:

java sun.beans.ole.Packager
-jar <jar file path>
-n <JavaBean name as referenced in the JAR manifest file> 
-ax <ActiveX name to be associated with the JavaBean> 
-o <output directory>

You may specify options in any order. You must use the -jar option; the packager will use the following default values for options that you do not specify.

-n The packager uses the first JavaBean available in the JAR file. This option is recommended when the specified JAR file contains more than one JavaBean.
-ax The packager uses the JavaBean name (minus the package name prefix). For example, sunw.demo.buttons.ExplicitButton becomes ExplicitButton.
-o The packager generates the typelib and reg file in the current directory. Specify your desired directory.

The packager displays status messages in the standard output of the command prompt (usually the window in which you started the packager).

Using JavaBeans as ActiveX Components

The following example uses the Microsoft Visual Basic development environment to illustrate how two sample JavaBeans, ExplicitButton and Juggler, may be used as ActiveX components.

Importing JavaBeans into Visual Basic

From within Visual Basic, select the "Tools" menu and "Custom Controls" item and add the ExplicitButtonBeanControl and JugglerBeanControl as shown below.

After importing the custom controls, Juggler and ExplicitButton will appear on the toolbar.

Example:

You can work with Juggler and ExplicitButton in the same way as you would with ordinary ActiveX components. For example, instantiate a Juggler and two ExplicitButtons in the Visual Basic form. Label the ExplicitButtons "Start" and "Stop" in the Properties window (by editing the "Label" property).

Alternatively, you can invoke the customizer on the JavaBean (if the JavaBean has a customizer) by right-clicking on the component and selecting the Properties menu as shown below:

Once the customizer is open, modify the label of the button. Notice that the label changes in the Visual Basic properties tool bar. This occurs because the button fires a PropertyChangeEvent which is caught by the bridge and forwarded to the container (in this case Visual Basic).

The customizer is also available through the normal PropertyPages mechanism of the ActiveX specifications. Please refer to your ActiveX container documentation on how to open the property pages of an ActiveX component.

Double-click on the "Start" button and add the event-handling Visual Basic code, Juggler1.start, to the ExplicitButton1_actionPerformed subroutine as illustrated below.

Juggler1 is the value for the "name" property for the Juggler JavaBean component running on the same page.

Now, double-click on the "Stop" button and add the event handling Visual Basic code, Juggler1.stop, to the ExplicitButton2_actionPerformed subroutine.

Run the program and test your work by pressing the "Start" and "Stop" buttons to start and stop the juggler.

Add an ActiveX scrollbar component and use it to control the juggler's animation speed. Set the scroll-bar maximum value property to 0 and the minimum value to 200. Now, double-click on the scrollbar to edit the HScroll1_Change subroutine as shown below.

Run the program. You can now increase and decrease Juggler's animation speed by moving the scrollbar right and left.

Minimum Requirements for Distributing Packaged JavaBeans

When packaged JavaBeans are distributed across machines (including the Internet), the following requirement must be met for the packaged JavaBeans to work.

Java Plug-in 1.3 must be installed and each packaged JavaBeans consists of at least a JAR file, a TLB (Type Library) file and a REG (Registry) file. They must be reachable from the target machine, and the settings in the REG file should be imported into the target machine's registry.

Note: The REG file contains the path of the JAR file and TLB file. If you move the JAR and TLB files to different locations on different machines, make sure the corresponding registry settings are updated accordingly.

Internet Explorer Support

Starting with version 3.0, Microsoft Internet Explorer supports ActiveX components that can be downloaded and run within an HTML page.

The Java Plug-in can be used to run Java Applets or JavaBeans components inside IE 3.0 using all the features of JDK 1.1. To use the Java Plug-in in Intenet Explorer, the bridge can be used as it is used in Visual Basic:

Package the JavaBeans component
Paint it using an HTML authoring tool like FrontPage 97 or Notepad
Run it inside Internet Explorer

The JavaBeans component (JAR file, type library and registration) will have to be installed on each target machine using either a custom installation or technologies like CAB files (see CAB SDK from Microsoft).

Alternatively, the bridge is able to support non-registered JavaBeans components on a target machine if the information about the JavaBean is stored in the properties of the ActiveX control (using the PARAM tags). For that, the bridge uses a unique CLSID, (the generic CLSID of the bridge) that allows it to run in any ActiveX container application, but not to run any particular JavaBeans component. Please refer to the Java Plug-in HTML Specification.

How to Script Applets

You can use scripting in Java Plug-in applets. Currently, you can do scripting only for applets running in Internet Explorer. This document assumes that you understand the HTML tags required for Java Plug-in. Please refer to the Java Plug-in HTML Specification for more information on these tags. You also should be familiar with the scripting languages.

A script, represented by a special script tag within the HTML document, invokes methods that have been implemented in the applet's Java program. Using scripting, you have the capability to call applet methods from within the HTML page. There are two scripting languages that you can use for scripting Java Plug-in applets:

VBScript Visual Basic scripting language
JavaScript The Java scripting language

In addition to invoking a method on an applet, you can also use scripts to:

Get and set properties in applets
Run JavaBeans components that have been built to be scripted

Using Scripts to Invoke a Method

You often want to use scripts to invoke methods on an applet. For example, you might have an HTML button that, when clicked, starts an animation sequence. You do this through a combination of HTML tags and scripting in the HTML file, plus the actual code in the applet itself.

You need to include the following in your applet's HTML page:

Within the OBJECT tag, an ID parameter that specifies the name of the applet
Tags specifying a scripting language and scripting method associated with a particular action
A SCRIPT tag for the scripting method that the action will invoke

These tags are explained in the following sections.

Specify the Applet

You must designate an ID parameter within the OBJECT tag for your HTML page. Recall that the OBJECT tag includes such parameters as classid, width, height, and so on.

The ID parameter is the symbolic name of the applet. Once you establish a symbolic name for an applet through the ID parameter, you can reuse this name later in the scripts to refer to this applet.

For example, suppose you have an applet called Fractal. You add the ID parameter to the OBJECT tag and set ID to the symbolic name of the applet. You might set the tag as follows:

ID="Fractal"

Now, you can use the name Fractal within scripts to refer to the Fractal applet.

Using the same Fractal applet example, your HTML page would begin with a FORM tag, followed by an OBJECT tag, that together might look as follows:

<form name="Form1">
<OBJECT ID="Fractal" WIDTH=500 HEIGHT=120
CLASSID="CLSID:8AD9C840-044E-11d1-B3E9-00805F499D93"
<PARAM NAME="code" value="CLSFractal.class">
<PARAM NAME="codebase" value="1.0.2">
<PARAM NAME="level" value="5">
...
</OBJECT>

Associate the Action to the Script

The HTML page defines components that are intended to invoke actions triggered by the user. You use the INPUT tag to define these components. You specify the TYPE of the component, such as button, its NAME, and VALUE. To have the button or other component actually invoke the intended action, you need to add tags that specify:

What the user does to trigger the action, such as onClick for when the user clicks on the button
The name of the script method that the HTML page will invoke when the specified trigger action occurs
The language in which the script method is written

For example, suppose your HTML page creates a button that, when clicked, starts a particular animation sequence. Your HTML tag creates the button and gives that button a name and a value.

To do this you want to add two tags. One tag indicates that on a certain action, such as click, a corresponding script method should be called. You might have the tag onClick="method name". The method name is a script method within the same HTML page. You also want to use the language tag to specify the script's language. The language can be either VBScript for Visual Basic script, or JScript for JavaScript.

Thus, you might have the following in your HTML page:

<input type="button" name="Button1" value="Start"
onClick="startVBFractal" language="VBScript">

This INPUT tag creates a button, names the button "Button1", and gives it the value "Start". It also specifies the scripting method that will be called when a user clicks the button, and the scripting method's language. In this example, the scripting method is startVBFractal, and the scripting language is VBScript. When the user clicks this button, the HTML page branches to the script method startVBFractal, which is written in Visual Basic script.

The Script Tag and Method

You must include a SCRIPT tag for the method that the onClick tag specified. The SCRIPT tag must have the same name as the name used in the onClick tag. It also has a parameter that specifies the script language. More importantly, the script method calls the Java applet method. It identifies the method by using the name of the applet as specified by the ID tag, followed by the actual method name as implemented in the applet code.

For example, the same HTML page might have the following SCRIPT tag:

<SCRIPT language="VBScript">
sub startVBFractal
	document.Form1.Fractal.startFractal()
end sub
</script>

This example SCRIPT tag begins by specifying that the scripting language is Visual Basic. This is followed by the VBScript sub statement, which starts the definition of a scripting method. The sub statement supplies a label or name for the scripting method, calling it startVBFractal. This name must match the method name given for the input component's action parameter.

For this example, both the onClick parameter and the sub statement specify the identical scripting method. The scripting method startVBFractal merely calls the actual method, startFractal, implemented in the applet code. It qualifies the method name by using the form name, then the applet name, then the method name itself, as follows:

document.Form1.Fractal.startFractal()

Example with JavaScript

As mentioned earlier, you can also use the JavaScript language to script your Java applets or JavaBeans components running inside the Java Plug-in in Internet Explorer. The following example shows a JavaScript code setting the Label property on the ExplicitButton JavaBeans component (available from the Beans Development Kit).

<SCRIPT LANGUAGE "JavaScript" FOR="window" EVENT="onLoad()">
ExplicitButton1.setLabel("Don't Press Me !")
</SCRIPT>

Using Scripts to Catch Events

You can also use scripts to catch events thrown by JavaBeans components. Only JavaBeans components can raise ActiveX events while running within the Java Plug-in 1.3. If your component is a Java applet and you wish to raise ActiveX events, you need to add a bridgeevents PARAM in your OBJECT tag that has the value "yes" to force the Java Plug-in to raise ActiveX events. This assumes that your Java applet has been programmed using the JDK 1.1 AWT event mode. In this example, it is assumed that the JavaBeans component has implemented the most recent JDK AWT event-handling interface.

You need to include the following in your applet's HTML page:

Within the OBJECT tag, an ID parameter that specifies the name of the scripting function or subroutine
Also within the OBJECT tag, a type parameter that specifies that the application is a JavaBeans component
A SCRIPT tag for the scripting method that the action will invoke. This tag includes the scripting language.

The example that follows illustrates a JavaBeans component that has implemented the AWT event-handling interface. This HTML page puts up a button on the screen and waits for a button action. When the user clicks the button, it triggers an event which the JavaBeans component catches. There is a scripting function that invokes the code implemented on the JavaBeans component and, when the event occurs, the scripting function displays a message.

The key parts of the HTML page follow. First, you have the OBJECT tag, which in our example looks as follows:

<OBJECT ID="ExplicitButton1" WIDTH=209 HEIGHT=246
CLASSID="CLSID:8AD9C840-044E-11d1-B3E9-00805F499D93">
<PARAM NAME="code" value="sunw.demo.buttons.ExplicitButton">
<PARAM NAME="archive" value="buttons.jar">
<PARAM NAME="type" value="application/x-java-bean;version=1.1">
<param name="width" value="209">
<param name="width" value="209">
</OBJECT>

To begin with, you must specify the symbolic name of the script function in the ID parameter to the OBJECT tag. In this case, the name of the function is ExplicitButton1:

<OBJECT ID="ExplicitButton1"

Also, with the OBJECT tag, include a parameter that indicates that this is a JavaBeans component. This is accomplished by the following line:

<PARAM NAME="type" value="application/x-java-bean;version=1.1">

Note for Internet Explorer 3 users:
To raise ActiveX events while running inside Internet Explorer 3, always add the following line even if you are running a JavaBeans component:
<PARAM NAME="bridgeevents" value="yes">

You must be sure to declare the script function itself. This begins with the SCRIPT LANGUAGE tag that indicates the scripting language. In this example, the language is VBScript.

<SCRIPT LANGUAGE="VBScript">
<!--
Sub ExplicitButton1_actionPerformed(ActionEvent1)
call window.alert("OK !")
end sub
-->
</SCRIPT>

Define the script function starting with the Sub tag. The name of the script function must match the name used in the ID parameter, ExplicitButton1. In the example above, the function name also references the actionPerformed AWT method and passes it an action event parameter.

When the event occurs, the scripting function will display a window alert and the message "OK !".

Example with JavaScript

To catch events using the JavaScript language, the remarks above about the OBJECT tag parameters are still valid, the change is reduced to the scripting code actually catching the event.

<SCRIPT  LANGUAGE="JavaScript"
    FOR="ExplicitButton1"
    EVENT="actionPerformed(ActionEvent1)"
<!--
window.alert("Don't do that !")
-->
</SCRIPT>

Java Plug-in ActiveX Capabilities--Technical Details

The Java Plug-in for Internet Explorer on Windows runtime is implemented using the COM threading model. When you run several JavaBeans components inside a multi-threaded ActiveX container (currently only Internet Explorer), each JavaBeans component is likely to run in a separate thread. If your Beans are making direct connections or sharing objects it's probably a good idea to think about concurrent access.

Runtime Environment

At runtime, the Java Plug-in does not need any particular CLASSPATH or PATH settings; the Registry is used to get all necesary information the bridge might need.

The registry key used by the Java Plug-in are:

HKEY_LOCAL_MACHINE\\Software\\JavaSoft\\Java Plugin\\1.1\\JavaHome

This key refers to the installation directory of the bridge where it should find the .class it needs. If you choose not to set this key, you must set the CLASSPATH.

The Java Plug-in will use by default the JRE with which it was installed (currently 1.1.6). By using the Java Plug-in Control Panel, you can specify an alternate JDK or JRE to use. If the Java Plug-in cannot load the selected JRE, it will always revert to the default JRE. If the default has been manually removed, it will try to use the PATH to find the JDK; if this fails, the Java Plug-in will fail to load.

Persistent Storage

In order to run successfully on the ActiveX bridge, a JavaBeans component must be serializable through either serialization or externalization. The current interfaces supported by the bridge are IPersistStorage, IPersistStreamInit, and IPersistPropertyBag.

When a JavaBean is asked to serialize itself, it must perform all serialization in one thread.

The bridge may choose to persist the JavaBean through textual property persistence. All public properties will be persisted though the values the accessor methods return. If a particular property is a Java Object, the PropertyEditor getAsText/setAsText methods will be used. If they are not implemented, serialization will be used on the property.

As stated for Code Generation in the JavaBeans specification version 1.01, The JavaBean designer may specify that a JavaBean cannot be restored by simply saving and restoring its properties. This can be done by using the Feature Descriptor's attribute/value mechanism (see the JavaBeans specification paragraph 5.4.1).

If the JavaBean descriptor property "hidden-state" is set to true, the JavaBean will always be persisted through serialization or externalization.

Events

All source interfaces that are declared as default in the EventSetDescriptor array returned by the BeanInfo will be merged into one interface which is declared as being the ActiveX default source interface. It is an ActiveX requirement that at least the default source interface is accessible by ActiveX containers.

Each method returned by the getListenerMethodDescriptors API of the EventSetDescriptor is mapped to an ActiveX event. he event name is the method name.

Consider, for example the java.awt.event.ActionListener source interface:

public interface ActionListener extends EventListener {
/**
* Invoked when an action occurs.
*/
public void actionPerformed(ActionEvent e);
}

The ActiveX event name generated from this interface definition is actionPerformed.

Since all default interfaces of your JavaBean are merged to a unique interface, do not use interfaces that contain the same method name.

The new AWT event model specifies that all event notifications come with a unique event object containing all information describing the event. Although this is required, the event object fields should be immutable. This is an example of the event signature:

Private Sub ExplicitButton1_actionPerformed
(ByVal ActionEvent1 As Object)
End-Sub

The ActionEvent1 is an Automation object that can be used from any scripting environment to get information on the event.

Note for the JavaBeans bridge for ActiveX users: In the 1.0 release of the JavaBeans bridge for ActiveX, users had the choice between cracking or uncracking events. This feature has disappeared in the 1.1 release.

Properties

All properties are accessible though the bridge with the same access right as defined in the PropertyDescriptor. The ActiveX bridge will automatically invoke the accessor methods defined in the PropertyDescriptor.

If the property is bound or constrained, the [bindable] or [requestedit] flags are set in the description of the OLE property. The IPropertyNotifySink interface will forward the PropertyChangeEvent. If the OLE container denies the property change and the property is constrained, the PropertyVetoException is thrown by the bridge.

Native properties will be mapped to their OLE type as described below:

Table 5.1: Java to Automation Mappings

Java Type Automation Type
boolean VT_BOOL
char VT_UI1
double VT_R4
float VT_R2
int VT_I4
byte, short VT_I2
long VT_I4 (truncated)
java.lang.String VT_BSTR
java.awt.Color VT_COLOR
java.awt.Font VT_FONT
Arrays (only 1 Dimension) VT_ARRAY | type
All others VT_DISPATCH

Note: Arrays of multiple dimension are not supported in this release.

All property names will have their first letter recapitalized for consistency with ActiveX conventions (label becomes Label).

For simple types and string, font, and color, most ActiveX containers like Visual Basic will allow direct manipulation of the properties in their PropertySheet. For all other properties like Arrays or Objects, the properties will not be accessible in the PropertySheet but can still be invoked using the scripting language offerred by the container.

Methods

All methods declared in the BeanInfo via a MethodDescriptor will be automatable from OLE Automation-capable containers. Overloaded methods are currently not accepted by automation; the bridge will use name mangling (repaint, repaint2, repaint3... use a type library browser to find which overloaded method you wish to call).

Please note that the bridge currently does not support static methods.

Arguments and return values are automatically marshalled by the bridge (refer to Table 5-1 for translation values). Exceptions thrown by the method will be caught by the bridge, packaged in the EXCEPINFO structure and returned to the OLE container.

Ambient Properties

The bridge supports four ambient properties that get translated to the JavaBeans properties if the JavaBeans component implements these properties. These ambient properties will be read and set on the JavaBeans component when the component is first painted on the canvas (InitNew) and each time a change notification for the ambient properties is received.

Properties that map standard control properties are shown below.

Table 5.2: Standard DISPID Assignment

Java Type and Name Dispatch DISPID
java.awt.Color , background DISPID_BACKCOLOR
java.awt.Color, foreground DISPID_FORECOLOR
java.awt.Font, font DISPID_FONT
boolean, enable DISPID_ENABLED 

ActiveX container ambient property changes of the previous types will be forwarded by the bridge to the JavaBean via a property set on the property.

Introspection

Introspection is not used at runtime, only at packaging time. However, in Internet Explorer for Java applets or JavaBeans components that do not have a dedicated CLSID, introspection will be used. All methods and properties will be accessible as described earlier. With Java Plug-in 1.3, only the source interfaces that are declared as being part of the default set will be packaged as a unique ActiveX source interface.

Customization

Customizers, when defined, are available at design time in Visual Basic though the Property pages of the component or by invoking the menu item Properties by right-clicking on the JavaBeans component.

Packaging

The Java Plug-in supports JavaBeans packaged in JAR files only. The packager will add a stub .class file in this JAR file. You can still use the JAR file once packaged with the Beanbox application on any platform if the classpath includes the bridge Java classes (sun.beans.ole.*).

Registry File

The packager will generate the type library file (repository of the capabilities of the JavaBean) and the registry file. The registry indicates the executable location, the type library location, and other information. You may edit the registry file. Register the registry file as follows:

regedit FileName.reg

Contained in the registry file is information about the executable location. This is where you have copied the beans.ocx file. One beans.ocx is enough to run all the packaged JavaBeans. You don't need to duplicate this .ocx file for each JavaBean.

[HKEY_CLASSES_ROOT\CLSID\{23BE13F0-4B64-11CB-BB1D-00805F2ADE08}\InprocServer32]
@= "c:\\perso\\beans\\beans.ocx"

The registry file has at least three lines of information as shown below:

JAR file location from where to load the JavaBean
Name of the JavaBean inside the JAR file
Name of the class responsible for interfacing the ActiveX native code and the JavaBean. You can change it but this is recommended only for experienced Java programmers. The interface of the class has to be the same.
[HKEY_CLASSES_ROOT\CLSID\{23BE13F0-4B64-11CB-BB1D-00805F2ADE08}\JarFileName]
@= "g:\\workspaces\\beans\\jars\\buttons.jar"
[HKEY_CLASSES_ROOT\CLSID\{23BE13F0-4B64-11CB-BB1D-00805F2ADE08}\JavaClass]
@= "sunw.demo.buttons.ExplicitButton"
[HKEY_CLASSES_ROOT\CLSID\{23BE13F0-4B64-11CB-BB1D-00805F2ADE08}\InterfaceClass]
@= "sun/beans/ole/OleBeanInterface"

Here is the location of the bitmap and the icon for the ocx. Use a gif->ico or gif->bmp translator program to move your gifs to Windows-specific format and put the path for these files here. If you want to load them from an executable, follow the example below where 1 is the ResourceID for the bitmap.

[HKEY_CLASSES_ROOT\CLSID\{23BE13F0-4B64-11CB-BB1D-00805F2ADE08}\ToolboxBitmap32]
@= "g:\\workspaces\\bridge\\classes\\beans.ocx,1"
[HKEY_CLASSES_ROOT\CLSID\{23BE13F0-4B64-11CB-BB1D-00805F2ADE08}\DefaultIcon]
@= "g:\\workspaces\\bridge\\classes\\hotjava.ico"

Here is the location of the type library generated by the packaging step. Change this information only if you move files around.

[HKEY_CLASSES_ROOT\TypeLib\{23BE13F1-4B64-11CB-BB1D-00805F2ADE08}]
@= "ExplicitButton Bean Control Type Library"
[HKEY_CLASSES_ROOT\TypeLib\{23BE13F1-4B64-11CB-BB1D-00805F2ADE08}\1.0]
@= "ExplicitButton Bean Control"
[HKEY_CLASSES_ROOT\TypeLib\{23BE13F1-4B64-11CB-BB1D-00805F2ADE08}\1.0\0\win32]
@= "g:\\workspaces\\bridge\\classes\\ExplicitButton.tlb"
[HKEY_CLASSES_ROOT\TypeLib\{23BE13F1-4B64-11CB-BB1D-00805F2ADE08}\1.0\FLAGS]
@= "2"
[HKEY_CLASSES_ROOT\TypeLib\{23BE13F1-4B64-11CB-BB1D-00805F2ADE08}\1.0\HELPDIR]
@= "g:\\workspaces\\bridge\\classes"

Advanced Automation Usage

Array Manipulation

Indexed properties and other arrays are accessible through the bridge as SafeArrays. Arrays of all types (except Java long) can be obtained or passed to a Java component from any OLE-compliant scripting environment. Here is an example of how to retrieve an array of short from a hypothetical JavaBeans property called ShortArray and display all its values in a Visual Basic Dialog Box:

        Rem // Declare the array variable
        Dim myArray as Variant
        NL = Chr(10);
        Rem // Do a property get on my JavaBeans component
        myArray = MyJavaBeansComponent.ShortArray
        // Construct the message box text
        Msg = "Array from " & LBound(myArray) & " to " & UBound(myArray)
        For j = LBound(myArray) to UBound(myArray)
        Msg = Msg & NL & "Element " & j & " = " & myArray(j)
        Next
        Rem // Display the message Box
        MsgBox Msg

Indexed properties can also be set using an index and a value or by setting the entire array in one property set. Let's examine examples of the two methods:

        Rem // Set the 4th element of the array to the value 36
        MyJavaBeansComponent.setShortArrayWithIndex(2, 36)


        Rem // Set the entire indexed property
        Dim myArray(2)
        Dim var as Variant
        myArray(0) = 9
        myArray(1) = 18
        myArray(2) = 36
        var = myArray
        MyJavaBeansComponent.ShortArray(var)

Object Creation

Two methods allow you to create new Java objects from any scripting facility. These methods are accessible from all Java objects visible in the scripting environment but not the JavaBean itself. This means that any object that a JavaBean returns as a result of a method invocation (for example, a property get or event fire) supports these methods.

The first method, getNew, takes one argument of type string that identifies the class name of the object you want to instantiate. The GetNew implementation will try to load the class using the system classloader and instantiate it using the newInstance method of the Class class.

Here is an example in Visual Basic of creating a new Button inside an actionPerformed event listener method implementation:

        Private Sub button1_actionPerformed(ByVal ActionEvent1 as Object)
        Dim newButton as Object
        Rem // Invoke the getNew on the Event object
        Rem // note that the button1 does not support the getNew
        set newButton = ActionEvent1.getNew("java.awt.Button");
        MsgBox newButton.toString()
        End Sub

The second method for creating new Java objects is getConstructor and is provided as part of the JDK1.1 reflection APIs. Using the reflection APIs, one can obtain the list of constructors for a particular class and then can invoke one of these constructors using the Method.Invoke API. getConstructor takes two arguments of type string; the first argument is the class of the object, the second argument is a list of parameters delimited by semi-colons (;). Refer to the JDK 1.1 reflection API documentation for a complete reference. The bridge will try to find a constructor that satisfies the following pattern :

public arg1(arg2);

where arg1 and arg2 are the arguments of the getConstructor method. For example, in the java.awt.Button class definition, you will find the constructor:

        Private Sub button1_actionPerformed(ByVal ActionEvent1 as Object)
        Dim constructor as Object
        Rem // Invoke the getConstructor on the Event object
        set constructor = ActionEvent1.getConstructor
        ("java.awt.Button", "java.lang.String");
        End Sub

The object returned by the getConstructor method is either null if the constructor cannot be found following the design pattern described above, or an IDispatch reference on the Method object (see java.lang.reflect.Method). You can use this method object to create a one to many instances of the class you need by invoking the newInstance method on it. If you look in the class java.lang.reflect.Constructor, you'll see that the newInstance method takes an array of Object as the list of parameters to be passed to the constructor. Here is an complete example of how to invoke the Button constructor described earlier:

        Private Sub button1_actionPerformed(ByVal ActionEvent1 as Object)
        Dim constructor as Object
        Rem // Invoke the getCosntructor on the Event object
        set constructor = ActionEvent1.getConstructor
        ("java.awt.Button", "java.lang.String");

        Rem // Now we have the constructor, let's build the array of
        Rem // arguments used by the constructor (only 1 of type string)
        Dim parms(1)
        parms(0) = "My New Button Label"

        // Let's try to invoke the constructor
        Dim newButton as Object
        set newObject = constructor.newInstance(parms)

        // Let's display something with it
        MsgBox newObject.toString()
        End Sub

Direct Connections Between JavaBeans

It is possible to make direct connections between JavaBeans running in the bridge inside the same application. This requires a script for the initial hookup but once accomplished, the two components communicate directly without going through the bridge or COM. This will allow a JavaBeans component to directly receive events of other JavaBeans components running in the same container without paying the price of the bridge and the COM layers.

Consider a JavaBean that implements the java.awt.event.ActionListener interface to receive button events. To do so, the JavaBean can directly implement the listener interface or much more cleanly provide an adaptor class that implements the listener interface. The example below illustrates the latter approach using a new feature of JDK1.1--nested classes.

        Class JavaBeansExample {
        .... Some Code....
        /*
        * Small adaptor class that implement the ActionListener
        * @return ActionListener interface implementation
        */
        public java.awt.event.ActionListener getActionListener() {
        return new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent e) {
        Dialog myDialog = new Dialog(new Frame(), "Event Received");
        myDialog.reshape(200,200,400,400);
        myDialog.show();
        }
        };
        }
        .... Some Code....

Invoking the getActionListener method on this JavaBean returns an object that implements the ActionListener interface. The interface implementation actionPerformed method creates a new dialog box to notify the user that the ActionEvent has been received. The ExplicitButton JavaBean that is delivered as part of the Beans Development Kit sources the ActionListener interface. You can link the interface implementation of the first JavaBeans component to an ExplicitButton instance of get the dialog box to pop up when the user presses the button. The hookup can be done when the Visual Basic form is loaded:

        Private Sub Form_Load()
        ExplicitButton1.addActionListener(JavaBeans1.getActionListener)
        End Sub

If the JavaBeansExample component directly implements java.awt.event.ActionListener, the code would look like:

        Class JavaBeansExample implements java.awt.event.ActionListener {
        ... Some Code ...
        public void actionPerformed(java.awt.event.ActionEvent e) {
        Dialog myDialog = new Dialog(new Frame(), "Event Received");
        myDialog.reshape(200,200,400,400);
        myDialog.show();
        
        ... Some code...
        }

And the method hookup would be :

        Private Sub Form_Load()
        ExplicitButton1.addActionListener(JavaBeans1.Object)
        End Sub

Either approach is valid. When the user presses the JavaBeans ExplicitButton, the event is caught by the JavaBeanExample component which then displays a dialog box. These direct connections are not limited to events. An object created by one JavaBeans component can be passed as a method parameter to another JavaBean. Note that the original object is passed and not a copy.

Direct Connection in Internet Explorer

The same direct connection can also be set up while running inside Internet Explorer. The following code which is executed when Internet Explorer fires the Window onLoad event (all components in the page are loaded), demonstrates the same hookup between the two components in the previous example.

<SCRIPT LANGUAGE="VBScript">
<!--
Sub  window_onLoad()
 x = test1.getActionListener
 button1.addActionListener x
end sub
-->
</SCRIPT>

OLE Automation Server

It is possible to take a JavaBeans component and make it an OLE Automation Server (no UI). The JavaBeans Bridge for ActiveX has built-in support for this feature, so no change is needed in the JavaBeans component.

Here is an example in Visual Basic of creating a new TickTock and invoking its methods through OLE Automation:

        Rem // Load the JavaBeans as an OLE Automation Server.
        Rem // "TickTock.Bean.1" is the ProgID of the JavaBean component
        Dim TickTock As Object
        Set TickTock = CreateObject("TickTock.Bean.1")
        
        Rem // Invoke method on TickTock
        MsgBox TickTock.getClass.toString
          & " JavaBean returned " & TickTock.getSeconds
        
        Rem // Release the object
        Set TickTock = Nothing

The result will be the following:

Unregister JavaBeans over ActiveX

In some cases, it is necessary to unregister a packaged JavaBeans component over ActiveX, so we provide two utilities for performing this task in DOS and Win32. UnregBean is a command prompt-based program. It takes the ProgID of the JavaBeans component to perform the unregistration. During JavaBeans packaging time, you are asked for an ActiveX name. The ProgID is normally the ActiveX name + ".Bean.1". For example, if the ActiveX name is Select, the ProgID should be "Select.Bean.1".

UnregBean -h -d -i <ProgID> -u <ProgID>
-h The UnregBean displays a help message.
-d The UnregBean displays information about all the JavaBeans over ActiveX in the current machine. Since the list may be extensive, we suggest using "unregbean | more".
-i The UnregBean displays information about a specific JavaBeans over ActiveX in the current machine using the ProgID.
-u The UnregBean unregisters a specific JavaBeans over ActiveX in the current machine using the ProgID.

The UnregBean displays output messages in the standard output of the command prompt.

WUnregBean is a Win32-based utility for unregistration.

CLSID, ProgID, Version-Independent ProgID and the path of the JAR file are displayed. To unregister a JavaBeans over ActiveX, simply click the "Unregister JavaBeans" button, and the utility will perform the task.

To remove the stubs in the JAR file during unregistration, UnregBean and WUnregBean require JDK 1.1 to be installed in the target machine. However, if JDK is not installed, UnregBean and WUnregBean will still unregister the selected JavaBeans, but stubs will not be removed from the JAR file.