JavaFx系列之WebView插件中JavaScript和Java相互调用,并传递值

十点数据 1年前 ⋅ 4130 阅读

在编写JavaFx工作流的过程中,由于工作流用的是jquery实现,其中有一些数据,需要通过JavaScript传递到后台Java对象,并保存。 大概原则是:首先在Java中创建一个对象,把该对象设置到网页去。而对于另一个方向,JavaScript创建一个对象并从网页中提取出来。下面用代码演示。首先是Java的代码

package sample;

import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

import java.io.File;
import java.net.URL;

@SuppressWarnings("restriction")
public class Main extends Application {

    /** 用于与Javascript引擎通信。 */
    private JSObject javascriptConnector;

    /** 用于从Javascript引擎进行通信。 */
    private JavaConnector javaConnector = new JavaConnector();;

    @Override
    public void start(Stage primaryStage) throws Exception {
        URL url = new File("H:\\WorkSpace_Browse\\WorkBrowerV1.2\\src\\main\\java\\sample\\test.html").toURI().toURL();

        WebView webView = new WebView();
        final WebEngine webEngine = webView.getEngine();

        // 设置Java的监听器
        webEngine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
            if (Worker.State.SUCCEEDED == newValue) {
                // 在web引擎页面中设置一个名为“javaConnector”的接口对象
                JSObject window = (JSObject) webEngine.executeScript("window");
                window.setMember("javaConnector", javaConnector);

                // 获取Javascript连接器对象。
                javascriptConnector = (JSObject) webEngine.executeScript("getJsConnector()");
            }
        });

        Scene scene = new Scene(webView, 300, 150);
        primaryStage.setScene(scene);
        primaryStage.show();

        // 这里加载页面
        webEngine.load(url.toString());
    }

    public static void main(String[] args) {
        launch(args);
    }

    public class JavaConnector {
        /**
         * 让JavaScript调用的方法
         *
         * @param value 网页传过来的值
         */
        public void toLowerCase(String value) {
            System.out.println(value);
            if (null != value) {
                // 这里收到了JavaScript传来的数据,再传送一个值回去给JavaScript
                javascriptConnector.call("showResult", value.toLowerCase());
            }
        }
    }
}

首先,加载网页后,将javaConnector对象设置到HTML页面中,使Javascript能够直接调用;

JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("javaConnector", javaConnector);

随后,在网页检索javascriptConnector对象,使用回调JavaScript,同时传值到JavaScript;

javascriptConnector = (JSObject) webEngine.executeScript("getJsConnector()");

调用javaConnector的toLowerCase(String value) 方法,将值传入到Java,然后通过javascriptConnector对象发回,其实还有更方便的方法返回给JavaScript,这里就不写了。下面给出网页的代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Sample</title>
    </head>
    <body>
        <main>

            <div><input id="input" type="text"></div>
            <button onclick="sendToJava();">to lower case</button>
            <div id="result"></div>

        </main>

        
            function sendToJava () {
                var s = document.getElementById('input').value;
                javaConnector.toLowerCase(s);
            };

            var jsConnector = {
                showResult: function (result) {
                    document.getElementById('result').innerHTML = result;
                }
            };

            function getJsConnector() {
                return jsConnector;
            };
        
    </body>
</html>

sendToJava函数调用,由上述Java设置的javaConnector的方法:

function sendToJava () {
    var s = document.getElementById('input').value;
    javaConnector.toLowerCase(s);
};

然后是Java调用的函数,jsConnector对象里面的showResult函数:

var jsConnector = {
     showResult: function (result) {
             document.getElementById('result').innerHTML = result;
     }
};

function getJsConnector() {
     return jsConnector;
};

JavaScript和后台java之间调用,以及之间的互相传入可以有多种类型,具体可以去官网查找相应的api或者demo。

全部评论: 0

    我有话说: