JavaFX Script — JavaScript Bridge

When JavaFX content is hosted as an applet on a web page, the JavaFX Script code can interact with the web page, and JavaScript code on the web page can interact with the JavaFX Script code. This document provides an overview of the supported functionality.

Calling From JavaScript to JavaFX Script

JavaScript code on the web page can access the JavaFX Script applet and perform many operations, such as calling JavaFX Script functions, getting and setting variables, passing data from JavaScript to JavaFX Script, and descending into the JavaFX Script scene graph. Note: this functionality requires Java SE 6 Update 10 at minimum. Attempting to call from JavaScript to JavaFX Script with earlier versions of Java Runtime Environment software will throw exceptions, which can be caught by using the JavaScript try { ... } catch (e) { .. } syntax.

The following examples illustrate some of the available functionality. The source code for all of these examples can be found in the file demos.zip.

Accessing Script-Level Variables

The scope of the main JavaFX Script code can be accessed by using the synthetic script field which is exposed from JavaFX Script applets to the JavaScript engine.

JavaFX Script Code:

Source Code
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.Scene;
import javafx.stage.Stage;

public var color = Color.YELLOW;
public function run(args: String[]) {
     Stage {
          scene: Scene {
               fill: Color.DARKGRAY
               content: [
                    Circle {
                         centerX : 125
                         centerY : 125
                         radius: 100
                         fill: bind color
                    }
               ]
          }
     }
}

JavaScript Code: (Assuming the applet is instantiated with the id "myApplet")

Source Code
function makeRed() {
    var app = document.getElementById("myApplet");
    app.script.color = app.Packages.javafx.scene.paint.Color.RED;
}

function makeBlue() {
    var app = document.getElementById("myApplet");
    app.script.color = app.Packages.javafx.scene.paint.Color.BLUE;
}

Calling Script-Level Functions


JavaFX Script Code:

Source Code
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.Scene;
import javafx.stage.Stage;

var color = Color.YELLOW;
    
public function setColor(red: Number, green: Number, blue: Number) : Void {
     color = Color { red: red, green: green, blue: blue };
}
    
public function run(args: String[]) {
     Stage {
          scene: Scene {
               fill: Color.DARKGRAY
               content: [
                    Circle {
                         centerX : 125
                         centerY : 125
                         radius: 100
                         fill: bind color
                    }
               ]
          }
     }
}

JavaScript Code: (Assuming the applet is instantiated with the id "myApplet")

Source Code
function makeRed() {
    var app = document.getElementById("myApplet");
    app.script.setColor(1.0, 0.0, 0.0);
}
    
function makeBlue() {
    var app = document.getElementById("myApplet");
    app.script.setColor(0.0, 0.0, 1.0);
}

Descending Into the Scene Graph From JavaScript

The main Stage of the JavaFX applet can be accessed through the stage field on the applet. From the stage field, you can descend into the scene and deeper into the scene graph.

JavaFX Script Code:

Source Code
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.Scene;
import javafx.stage.Stage;

public function run(args: String[]) {
     Stage {
          scene: Scene {
               fill: Color.DARKGRAY
               content: [
                    Circle {
                         centerX : 125
                         centerY : 125
                         radius: 100
                         fill: Color.YELLOW
                    }
               ]
          }
     }
}

JavaScript Code: (Assuming the applet is instantiated with the id "myApplet")

Source Code
function makeRed() {
    var app = document.getElementById("myApplet");
    app.stage.scene.content[0].fill = app.Packages.javafx.scene.paint.Color.RED;
}
    
function makeBlue() {
    var app = document.getElementById("myApplet");
    app.stage.scene.content[0].fill = app.Packages.javafx.scene.paint.Color.BLUE;
}

Complex Data Type Conversions

A rich set of data type conversions is supported between JavaFX Script and JavaScript code.

  • All primitive types (numbers, booleans, Strings) can be passed from JavaScript to JavaFX Script and returned from JavaFX Script to JavaScript.

  • Automatic conversions from floating-point to integer number types, from String to number types, and other type pairs are supported.

  • JavaScript code can pass a JavaScript array to a JavaFX Script function taking a sequence as argument, and the values will be automatically converted. This process provides a convenient way to pass animation data, charting data, etc. from the web page to a JavaFX Script applet used for visualization.

  • JavaFX Script can return a sequence to JavaScript, and the resulting object can be accessed by using normal JavaScript array syntax: the [] operator and the length field. Note that such sequences are immutable from JavaScript.

  • Access to Java objects alongside JavaFX Script objects is supported.

In general, accessing JavaFX Script from JavaScript provides a superset of the Java/JavaScript functionality documented in the LiveConnect Specification for Java SE 6 Update 10.

The following example shows how to pass animation data from the web page to JavaFX Script.

JavaFX Script Code:

Source Code
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.animation.*;

var timeline: Timeline;
var x: Number = 125.0;
var y: Number = 125.0;
    
public function animate(times: Number[],
                        xyCoords: Number[]) {
     var t = Timeline {
          keyFrames: for (i in [0..(sizeof times - 1)]) {
               KeyFrame {
                    time: Duration.valueOf(times[i]);
                    values: [
                         x => xyCoords[2*i],
                         y => xyCoords[2*i+1],
                    ]
               }
          }
     }
    
     if (timeline != null) {
          timeline.stop();
     }
    
     timeline = t;
     timeline.play();
}
    
public function run(args: String[]) {
     Stage {
          scene: Scene {
               fill: Color.DARKGRAY
               content: [
                    Circle {
                         centerX: bind x
                         centerY: bind y
                         radius: 15
                         fill: Color.BLUE
                    }
               ]
          }
     }
}

JavaScript Code: (Assuming the applet is instantiated with the id "myApplet")

Source Code
function clockwise() {
     var app = document.getElementById("myApplet");
     app.script.animate([250, 500, 750, 1000],
                        [225, 225,
                         25, 225,
                         25, 25,
                         225, 25]);
}
    
function counterclockwise() {
     var app = document.getElementById("myApplet");
     app.script.animate([250, 500, 750, 1000],
                        [25, 25,
                         25, 225,
                         225, 225,
                         225, 25]);
}

A comprehensive set of tests showing various data type conversions is in DataTypeTests.html and DataTypeTests.fx in the file demos.zip.

Calling From JavaFX Script to JavaScript

JavaFX Script code can interact with JavaScript code on the web page, in a similar way to how Java code can interact with JavaScript. This interaction enables you to call JavaScript functions defined on the web page, modify the Document Object Model (DOM) of the web page dynamically, and generally write JavaFX Script apps that integrate well within the web page.

If your JavaFX Script code is running in the context of an applet on a web page, the following functionality is supported.

Showing a Document in the Web Browser

The javafx.stage.AppletStageExtension class can be used to display a document in a frame of the browser or in a new browser window.

JavaFX Script Code:

Source Code
import javafx.stage.AppletStageExtension;

// Show a document in a new browser window
AppletStageExtension.showDocument("http://my.company.com/");

// Show a document in a frame of the current browser window
AppletStageExtension.showDocument("http://my.company.com/", "LEFT_FRAME");

Evaluating a String of JavaScript

The AppletStageExtension class can be used to easily evaluate a string of JavaScript code in the context of the browser window.

JavaFX Script Code:

Source Code
AppletStageExtension.eval("someJavaScriptFunction()");

Experimental: Interacting Directly With JavaScript Objects

JavaFX Script code running as an applet can work with JavaScript objects directly by using the netscape.javascript.JSObject API directly, as documented in the new LiveConnect Specification. These APIs are supported on all versions of the Java Runtime Environment that support the JavaFX runtime. However, the bootstrapping mechanism for accessing these APIs is currently considered experimental and might change in a future version of JavaFX software.

JavaFX Script Code:

Source Code
var window: netscape.javascript.JSObject =
     FX.getArgument("javafx.applet") as netscape.javascript.JSObject;

// Now can interact with the JSObject APIs and call JavaScript
// functions, etc. defined in the window scope

When JavaScript code is called from JavaFX Script code, the same conversion rules apply as described earlier for return values from JavaFX Script to JavaScript. For example, when a JavaFX Script sequence is passed to JavaScript, that sequence can be accessed by using JavaScript array syntax from JavaScript code.

Experimental: Manipulating the DOM

JavaFX Script contained within an applet can use the object-oriented Common DOM APIs to query and modify the DOM of the web page. However, the bootstrapping mechanism for accessing these APIs is currently considered experimental and might change in a future version of JavaFX. Note: This functionality requires Java SE 6 Update 10 at minimum, due to significant rewrites in the implementation of the Common DOM APIs in that release.

You can fetch the HTMLDocument object containing the JavaFX applet as follows.

Java Code: (as a helper method)

Source Code
import java.applet.Applet;
import org.w3c.dom.html.HTMLDocument;
    
public class DOMHelper {
     public static HTMLDocument getDocument(Applet applet) {
         try {
             Class c =
                 java.lang.Class.forName("com.sun.java.browser.plugin2.DOM");
             java.lang.reflect.Method m =
                 c.getMethod("getDocument",
                             new Class[] { java.applet.Applet.class });
             return (HTMLDocument) m.invoke(null, new Object[] { applet });
         } catch (Exception e) {
             return null;
         }        
     }
}

JavaFX Script Code:

Source Code
var document : org.w3c.dom.html.HTMLDocument = 
    DOMHelper.getDocument(javafx.lang.FX.getArgument("javafx.applet")
                          as java.applet.Applet);
if (document != null) {
     // Use the document
}

From this point, you can descend into the document and query and modify various elements on the page.

For more information, consult the Common DOM release notes in Java SE 6 Update 10 and related documentation like the Common DOM API reference.

Rate This Article
Discussion

We welcome your participation in our community. Please keep your comments civil and on point. You may optionally provide your email address to be notified of replies—your information is not used for any other purpose. By submitting a comment, you agree to these Terms of Use.

 

English
日本語
한국어
简体中文
русский
Português do Brasil