尝试在JavaFX WebView DOM和控制类

时间:2018-01-29 21:43:09

标签: javafx-webengine

在我的控制器类中,我设置了一个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是公共字符串属性

我有以下工作:

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

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

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

很抱歉,如果之前有人询问过,请在这里搜索约3天

1 个答案:

答案 0 :(得分:0)

使用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);
}