最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Calling a Java method from a JavaFX webview - Stack Overflow

programmeradmin3浏览0评论

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.

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.

Share Improve this question edited Mar 14, 2016 at 11:34 TomRaikes asked Mar 14, 2016 at 10:54 TomRaikesTomRaikes 3601 gold badge7 silver badges18 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 4

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.

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

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

bees 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/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.

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.

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 mand (i copied it from eclipse mand) 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
发布评论

评论列表(0)

  1. 暂无评论