尝试在 JavaFX WebView DOM 和控制 class 之间同步状态

Trying to synchronize states between JavaFX WebView DOM and controlling class

在我的控制器 class 中,我设置了一个 WebView 对象

    @FXML
    private WebView newsletterPreview;
    // some stuff...
    urlString = url.toExternalForm();
    WebEngine engine = newsletterPreview.getEngine();
    bridge = new JSBridge(engine, this);

JSBridge 代码片段 ...

     private String headlineCandidate;

     public String getHeadlineCandidate() {
         return headlineCandidate;
     }
     //mo stuff... 
     public JSBridge(WebEngine engine, ENewsLetterDialogController controller) {
    engine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
        if (newState == State.SUCCEEDED) {
            window = (JSObject) engine.executeScript("window");
            window.setMember("bridge", this);
            engine.executeScript(loadDomListenerScript());
        }
    });
}
private String loadDomListenerScript() {
   return WOWResourceUtils.resourceToString(LISTENER_SCRIPT);

}
 public void captureHeadline(String element) {
    this.headlineCandidate = element;
    System.out.println(headlineCandidate);

}

侦听器脚本片段..

    //listener script
    "use strict";
    document.addEventListener('click', function(e) {
    e = e || window.event;
    var target = e.target || e.srcElement, text = target.textContent || 
    text.innerText;
    window.bridge.captureHeadline(target.parentElement.outerHTML);
    });

其中 LISTENER_SCRIPT 作为资源嵌入 Javascript,headlineCandidate 是一个 public 字符串 属性

我有以下工作:

我导航加载网页,我可以让 JSBridge class 回显我单击的任何元素的预期父元素 html(显然这是为了测试)。但是,我找不到将该信息返回给应用程序线程的好方法,因此我可以(例如)在用户单击正确的 HTML 元素时启用按钮。是的,这种设计是基于对页面的某些假设。这是用例的一部分。

根本问题似乎是 WebView 与应用程序在不同的线程上,但我找不到同步两者的好方法

我应该尝试从应用程序线程进行轮询吗?

对不起,如果之前有人问过,在这里搜索了大约 3 天

使用 Platform.runLater 将数据从非 JavaFX 线程传送到 JavaFX 线程:

// Java method invoked as a result of a callback from a 
// JavaScript event handler in a webpage.
public void callbackJava(String data) {
    // We are currently not on the JavaFX application thread and
    // should not directly update the scene graph.
    // Instead we call Platform.runLater to ship processing of data
    // to the JavaFX application thread.
    Platform.runLater(() -> handle(data));
}

public void handle(String data) {
    // now we are on the JavaFX application thread and can 
    // update the scene graph.
    label.setText(data);
}