【问题标题】:Trying to synchronize states between JavaFX WebView DOM and controlling class尝试在 JavaFX WebView DOM 和控制类之间同步状态
【发布时间】:2018-01-29 21:43:08
【问题描述】:

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

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

JSBridge 代码 sn -p ...

     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);

}

监听脚本 sn-p..

    //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与Application位于不同的线程上,但我找不到同步两者的好方法

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

抱歉,之前有人问过,在这里搜索了大约 3 天

【问题讨论】:

  • jewlsea 的建议非常有效

标签: javafx-webengine


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    相关资源
    最近更新 更多