TomRaikes
TomRaikes

Reputation: 340

Calling a Java method from a JavaFX webview

In my project I have an HTML document that is displayed in a JavaFx WebView. I have a Javascript function that should call the Java method getData (currently it only prints the passed variable so that I can confirm the data is being passed from the WebView back to the Java application):

    public void getData(String s){
        System.out.println(s);
    }

This is how I am attempting to add the functionality to call Java methods into my WebView webpage:

    JSObject win = (JSObject) webEngine.getDocument();
    win.setMember("app", new Bridge());

And here is the JavaScript function that I'm using to call getData:

     function interOp(val){
        app.getData(val);
     }

This function is called on the onchange event on a <select> tag. The guides I have followed seem to do exactly this, however when I run my program nothing is printed on the console.

Upvotes: 3

Views: 3787

Answers (4)

Armando B
Armando B

Reputation: 1

i saw that if i use approach

JSObject win = (JSObject) webEngine.getDocument();
win.setMember("app", new Bridge());"

it's work but if i resize window, event is not catched.

I also needed to use

-javaagent:javaagent-shaded.jar

in my run command (i copied it from eclipse command) to use Java 11:

java \
-javaagent:javaagent-shaded.jar \
-Dfile.encoding=UTF-8 \
-p /home/odroid/Scaricati/TestFX/bin:\
/usr/share/java/javafx-base.jar:\
/usr/share/java/javafx-controls.jar:\
/usr/share/java/javafx-fxml.jar:\
/usr/share/java/javafx-graphics.jar:\
/usr/share/java/javafx-media.jar:\
/usr/share/java/javafx-swing.jar:\
/usr/share/java/javafx-swt.jar:\
/usr/share/java/javafx-web.jar \
-m TestFX/application.Main

Upvotes: 0

browsermator
browsermator

Reputation: 1354

My solution was to create the object before passing it... so this:

JSObject win = (JSObject) webEngine.getDocument();
win.setMember("app", new Bridge());"

becomes this:

Bridge bridgeREF = new Bridge();
JSObject win = (JSObject) webEngine.getDocument();
win.setMember("app", bridgeREF);

This came from a bug report I read here: https://bugs.openjdk.java.net/browse/JDK-8170515

Otherwise, the javascript call seemed to work half the time... needed a refresh sometimes. It was really odd.

Though my code is/was a little different... here's how I register the java class "JavaApp" with the JavaFX window:

        Platform.runLater(new Runnable() {
        @Override
        public void run() {

  JavaApp appREF = new JavaApp(webEngine); 
  webEngine.getLoadWorker().stateProperty().addListener(
        new ChangeListener<State>() {
          @Override public void changed(ObservableValue ov, State oldState, State newState) {

              if (newState == Worker.State.SUCCEEDED) {

                  JSObject win = (JSObject) webEngine.executeScript("window");
                    win.setMember("app", appREF);  
            }

            }
        });
   //other code for loading html, listeners, etc...
   }

The reference to the class should be created outside of the anonymous listener, else the garbage collector might get it. Which is what (I think) was causing the erratic behavior I was experiencing... your java class may or may not need the reference to webEngine.. I use that for loading another url after sending a file.

I don't think it matters whether you use Window or Document... except that window might be more persistent depending on whether you use full page loads or not.

Upvotes: 1

K&#252;roro
K&#252;roro

Reputation: 668

I think it varies depending on how you call the Java method from the web page, I'm pointing out the events. I think the onchange and onfocus events are not supported, only mouse-related events. But I'm not really sure about that.

And about JSObject class, webEngine.executeScript("window"); should work.

You can see a full working example from my question here.

Hope it helped you.

Upvotes: 0

TomRaikes
TomRaikes

Reputation: 340

I have found a resolution for this issue: instead of using webEngine.getDocument();, which returns an HTMLdocument object, use webEngine.executeScript("window"); which gives a window object.

Upvotes: 3

Related Questions