Search code examples
javajavascriptjavafx-8javafx-webengine

JavaFX+WebView/Javascript : setTimeOut does not work call stack comes from Java


I have a JavaFX application that loads my own HTML/JS application in a WebView. Depending on the event, I need to call Javascript from Java, and Java from Javascript.

Every is good when going from JS to Java but I've got weird behaviors when going from Java to Javascript.

  • Here's, basically, how I setup the communication between the 2 languages:

_

var javaObjectInjected = typeof javaObject !== "undefined";

if(javaObjectInjected && !javaObjectInitialized) {
    jThalesEventBusInitialized = true;

    const jsAdapter = {
        publishToJs: onPublishToJs
    };

    javaObject.setJsAdapter(jsAdapter);
}
  • My Java code will invoke the method publishToJs on the provided jsAdapter. This will result in the execution of onPublishToJs.

_

function onPublishToJs(topic, data) {
    alert('Yeah! We are inside JS'); //output_1

    setTimeout(
        function() {
            alert('inside setTimeOut'); //output_2
        },
        1000
    );
}

I do get output_1 but not output_2. It's like the callback on setTimeOut was discarded.

Are there any known limitations when invoking JS from Java?


Solution

  • I refactored my code and instead of injecting jsAdapter to the Java world using javaObject.setJsAdapter(jsAdapter), I exposed jsAdapter to Java as a new member of window.

    With this new code structure, I got exceptions when invoking jsAdapter from Java because I was doing it from the EDT instead of the JavaFX Application Thread.

    Eventually, I wrapped the jsAdapter calls in Platform.runLater(() -> ...) and that was it.

    When working with Javascript loaded from a JavaFX WebView, make sure to always perform Javascript calls from the JavaFX Application Thread.