logo
24.1
search
No matching documents found.
list
logo

JsLink

Webswing offers JavaScript integration API, which allows invoking JavaScript functions from the Swing application code and vice versa.

Similar functionality is available to Applets and to make the transition to Webswing as easy as possible Webswing supports the same standard API available for Applets documented here. In Webswing, this API is available to all applications.

You can see this feature in action in the extended SwingSet3 demo application included in Webswing distribution. It demonstrates basic use case scenarios as calling Java service from JavaScript or using JavaScript function callback from Java.

Swingset3 jslink demo

Eval JavaScript from Swing

Lets start with a simple case of evaluating the JavaScript snippet from Swing app.

First, we need to get instance of netscape.javascript.JSObject class. We can use the standard static method, as documented by Oracle. The only difference is that in Webswing, we don't need to pass the Applet instance as the parameter. This way, it is available for non-applet Swing applications as well.

Note: for development, you can use the lib/plugin.jar from your JRE, but use it only as compile time dependency. Do not include it in your build.

JSObject global = JSObject.getWindow(null);

The variable global now represents the JavaScript global object. Now we can evaluate any JavaScript on this object.

Object res = global.eval("var hello = 'Hello world'; return hello;");
assert res instanceof String && assert res.equals("Hello world");

This is the simplest possible example of invoking JavaScript from Webswing. So let's see what happens under the hoods. The eval method will send a message to browser through the websocket channel and the current thread goes to sleep until the evaluation response message is received. If the evaluation fails or is not received in 3 seconds netscape.javascript.JSException is thrown.

Note: evaluation timeout is set to 3 seconds by default. It can be changed by setting webswing.syncCallTimeout system property (in milliseconds).

JavaScript Return Type Mapping

JavaScript type Java Type
null or undefined null
number java.lang.Number
string java.lang.String
boolean java.lang.Boolean
JavaObjectRef* refered Java object
other netscape.javascript.JSObject

*JavaObjectRef is JavaScript object created by this API when Java object is passed to JavaScript using setMember, setSlot or call methods. See Invoking Java from JavaScript chapter

Tip: When returning data from eval, serialize them to JSON rather then sending a JavaScript object directly. Querying the content using JSObject interface is costly, as each method call requires a server round trip.

JSObject methods [javadoc]

Method name Description
eval evaluates the JavaScript in argument and returns result.
call calls a function on object represented by this JSObject.
setMember creates or sets property on object represented by this JSObject with value from argument.
getMember returns property from object represented by this JSObject.
removeMember deletes property from object represented by this JSObject.
setSlot sets value of array represented by this JSObject on specified index.
getSlot returns the value from array represented by this JSObject on specified index.

Invoking Java from JavaScript

Before we can make any Java calls from JavaScript, we need to expose a Java object instance and store a reference to it in variable. Assume we have a singleton PingService class with one method called ping(), which we want to call from JavaScript. Let's expose this service to JavaScript:

public class PingService{
	static PingService singleton = new PingService();

    public String ping(){
        return "pong";
    }
}

JSObject global = JSObject.getWindow(null);
global.setMember("pingService", PingService.singleton);

The above setMember method will send a singleton's object reference to JavaScript and expose all his public methods as JavaScript functions. This singleton reference will be stored in pingService property of global object.

Note: Make sure you keep a reference to your service object in Java to avoid garbage collection, otherwise, you will get an exception when calling service from JavaScript.

Now let's call the ping method from JavaScript. As you can see below the ping function does not return the result directly, but it returns a Promise, which resolves to value returned by Java method. If the result is not returned from Java within 3 seconds or the Java method throws an exception, the promise is rejected and the error is handled in the catch block.

pingService.ping().then(
    function(result){
        alert(result);
    }
).catch(
    function(error){
        console.log(error);
    }
)

Note: To adjust the Java call timeout limit, set the javaCallTimeout property to your Webswing JavaScript. See embedding documentation

Applet specifics

To simplify transition of Applets, Webswing will automatically expose the Applet object to JavaScript. Applet object reference will be stored in the Webswing instance variable as defined by data-webswing-instance="myWebswing" element attribute (See embedding documentation). For example:

myWebswing.applet.getAppletInfo().then(
    function(result){
        alert("my applet info:"+result);
    }
)

Security configuration

JsLink framework can be disabled in Webswing configuration by setting the allowJsLink property to false.