JavaFx 的 Javascript 函数监听器功能

标签 java javascript javafx

我的公司正在寻求将我们的嵌入式浏览器切换到 JavaFx。但是,我们当前的浏览器目前具有监听 javascript 函数并在调用时回调 java 的功能。它看起来像这样:

embeddedBrowser.registerFunction("ajavascriptFunction", new BrowserFunction() {

public JSValue invoke(JSValue... args) {
    //Do callback work
}
});

这不需要修改 html 端(一个要求),实际上只需要了解 javascript 函数名称(我可能能够研究更多信息,但这是高度推荐的)。

有没有办法以同样的方式使用 JavaFx

最佳答案

我认为这可以满足您的需求。我从this question那里借用了一个想法弄清楚javascript:

import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

public class JavaScriptFunctionListener extends Application {

    @Override
    public void start(Stage primaryStage) {
        WebView webView = new WebView();
        WebEngine engine = webView.getEngine();

        engine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
            if (newState == Worker.State.SUCCEEDED) {
                addFunctionHandlerToDocument(engine);
            }
        });

        // Just a demo: in real life can load external HTML resource:
        engine.loadContent(
                "<html><head><script>"
                + "var count = 0 ;"
                + "function someFunction(x) {"
                + "    count ++ ;"
                + "    document.getElementById(x).innerHTML = 'Count: '+count ;"
                + "}"
                + "</script></head>"
                + "<body>"
                + "    <input type=\"button\" value=\"Click Me\" onclick=\"someFunction('display');\"/>"
                + "    <div id='display'></div>"
                + "</body>"
                + "</html>"
        );

        Button registerButton = new Button("Register handler for 'someFunction'");
        registerButton.setOnAction(event -> {
            registerFunction("someFunction", engine);
            // registering the same function twice will break everything
            // so don't allow this to happen again:
            registerButton.setDisable(true);
        });

        HBox controls = new HBox(5, registerButton);
        controls.setPadding(new Insets(10));
        controls.setAlignment(Pos.CENTER);

        BorderPane root = new BorderPane(webView, null, null, controls, null);
        Scene scene = new Scene(root, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    private void registerFunction(String functionName, WebEngine engine) {
        engine.executeScript(
            "var fun = " + functionName + " ;"
            + functionName + " = function() {"
            + "    app.functionCalled('" + functionName + "');"
            + "    fun.apply(this, arguments)"
            + "}"
        );
    }

    private void addFunctionHandlerToDocument(WebEngine engine) {
        JSObject window = (JSObject) engine.executeScript("window");
        window.setMember("app", this);
    }

    public void functionCalled(String name) {
        System.out.println(name + " was called");
    }

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

关于JavaFx 的 Javascript 函数监听器功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29172001/

相关文章:

java - 在javafx 8中使用namedArg注释将对象作为参数传递

java - 如何在 Java 中测试一个类是否正确实现了 Serializable(不仅仅是 Serializable 的实例)

javascript - 具有嵌套 json 属性的行

java - Derby 的另一个实例可能已经使用嵌入式数据库启动了数据库

javascript - FFT 实现错误(Nayuki vs Octave)

javascript - 解决nodejs选项中的变量

java - 手动关闭应用程序并调用方法? [JavaFX]

Javassist 注释 MemberValue 不带 Name

java - dynjs 与 Node 上 javascript 中字符串函数的性能比较

java - 知识产权共享