JavaFX WebEngine JavaScript上调

复制和粘贴

在Java中Windows 10 pro x64 jre 1.8.0_60,以下代码产生预期的输出(单击html按钮后):

Hello World

但是在JavaWindows 10 pro x64 jre 1.8.0_152中似乎存在某种断开连接,因为单击按钮后它将不会输出任何内容到控制台

为什么在最新版本的Java(在152时)上,我的代码却给出了不可预测的,通常是不需要的结果。我试图给出最少的代码来创建下面的方案。

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

public class Main extends Application {

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

@Override
public void start(Stage primaryStage) {
    WebView browser = new WebView();
    final WebEngine webEngine = browser.getEngine();
    webEngine.setJavaScriptEnabled(true);
    webEngine.load("https://api.ipify.org/?format=json");
    webEngine.getLoadWorker().stateProperty().addListener(
            new ChangeListener<Worker.State>() {
                @Override
                public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
                    if (newState == Worker.State.SUCCEEDED) {
                        JSObject jso = (JSObject) webEngine.executeScript("window");
                        webEngine.executeScript(
                                "var button = document.createElement(\"button\");\n" +
                                        "button.innerHTML = \"Do Something\";\n" +
                                        "var body = document.getElementsByTagName(\"body\")[0];\n" +
                                        "body.appendChild(button);\n" +
                                        "button.addEventListener (\"click\", function() {java.exit();});");
                        jso.setMember("java", new Bridge());

                    }
                }
            });
    BorderPane panel = new BorderPane(browser);
    Scene scene = new Scene(panel, 700, 700);
    primaryStage.setScene(scene);
    primaryStage.show();
}

public class Bridge {
    public void exit() {
        System.out.println("Hello World");
    }
}}
VGR

您正在传递new Bridge()给setMember方法。由于没有变量保存Bridge实例,因此在您按下按钮之前会对其进行垃圾回收。

WebEngine文档中

请注意,在上面的示例中,应用程序拥有对该JavaApplication实例的引用这是从JavaScript进行回调以执行所需方法所必需的。

在下面的示例中,应用程序不包含对Java对象的引用:

JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("app", new JavaApplication());

在这种情况下,由于属性值是本地对象"new JavaApplication()",因此该值可能在下一个GC周期中被垃圾回收。

用户单击链接时,不能保证执行回调方法exit

将Bridge对象放在一个字段中,以防止对其进行垃圾回收:

new ChangeListener<Worker.State>() {
    private final Bridge bridge = new Bridge();

    @Override
    public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
        if (newState == Worker.State.SUCCEEDED) {

            // ...

            jso.setMember("java", bridge);
        }
    }

为什么它没有在Java的早期版本中发生?因为不同的Java版本可以自由更改垃圾回收的时间和行为。您很幸运,但是在以后的版本中,您的运气用光了。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何从WebEngine中的javascript调用JavaFX的UI变量?

获取JavaFX WebEngine解释的文档

(JavaFX WebEngine) JavaScript 到 Java 的调用不一致

JavaFX WebEngine:我需要我的 ChangeListener 知道它的触发器 WebEngine

尝试将本地页面加载到JavaFX WebEngine中

JavaFX 2.0+ WebView / WebEngine将网页呈现为图像

JavaFX 8 WebEngine打印方法无法在横向打印

使用JavaFX浏览器/ WebEngine构建Swing项目(Gradle)

javafx 16 WebEngine 异常“SSL 握手失败”

JavaFX WebEngine我无法同时下载和加载页面

webEngine JavaFX 与 Swing 一起使用的问题

如何等待JavaFx应用程序中的WebEngine /浏览器初始化?

JavaFX WebView / WebEngine上的自定义上下文菜单

如何从javafx.scene.web.WebEngine#loadContent加载的html页面访问CSS和图像文件?

JavaFx WebEngine-用(本地)文件覆盖网站的样式表

如何在javaFX浏览器中通过webEngine释放消耗的内存

查找哪个键触发了DOM“ keydown”事件(使用JavaFX WebEngine)?

Javafx WebEngine:后台工作者实际上会发生什么?UI挂在loadContent(大HTML文档)上

JavaFX在图表轴上调整文本大小

Qt WebEngine失败

如何在JavaFX堆积面积图上调整范围?

在iPad上调试Javascript

从javascript传递值到JavaFX

Qt WebEngine似乎已初始化

如何在Qt WebEngine中禁用CSP?

PyQt WebEngine 设置 http 标头

javascript在事件上调用函数

javafx中使用了什么JavaScript引擎?

JavaFX WebView中的HTML / JavaScript调试