2

我在 Eclipse SWT 应用程序中嵌入了 JavaFX 的 WebView,需要加载 html 内容。我需要阻止当前线程的执行,直到 web 引擎完成加载内容。任何熟悉这种情况并可以提供一些提示和/或最佳实践来实现这一点的人?似乎 SWT 和 JavaFX 都在同一个 UI 线程中运行。

谢谢!

4

3 回答 3

1

加载未完成时显示模式窗口。您不能阻塞应用程序线程,因为 SWT/JavaFX 操作相同

于 2013-10-08T12:51:44.487 回答
1

JavaFX Web 引擎在每个实现中异步加载。loadworker 的 stateproperty 的任何侦听器都会在 JavaFX 线程上接收回调。这个线程也运行你的 UI,这就是为什么你永远不应该阻塞 JavaFX 线程。在 JavaFX 等基于事件的 UI 系统中,如果您想做一些繁重的工作,您可以在自己的线程中执行此操作。永远不要阻塞 JavaFX 线程。

我回答的原因是因为我实际上有一个类似但不同的情况,我确实需要同步加载。我的第一个想法是将负载包装在我自己的线程中并制作该块,但需要从 JavaFX 线程调用加载操作。但是,我想出了绕过这个障碍的方法:

首先,我启动一个新线程,在其中声明一个信号量(许可为 0),从该线程启动一个启动引擎的 Platform.runLater(...),向 stateproperty 添加一个侦听器并加载一个 URL,然后尝试获取信号量。这会阻塞,因为信号量没有许可。在侦听器的回调中,我启动另一个新线程,我在其中完成繁重的工作,并从那里设置一些全局数据变量,然后释放信号量。这终止了我的后一个新线程,然后通知前一个新线程数据已加载,因此它可以继续。这也永远不会阻塞 JavaFX 线程。

将其包装在函数中时,您可以模拟同步加载操作,但在使用时应谨慎:仅从 JavaFX 线程外部调用该函数。但是,这非常有意义,因为您永远不应该在 JavaFX 线程上调用同步(也称为阻塞)加载。

于 2013-10-10T13:53:03.583 回答
1

我遇到了同样的问题,我需要以同步方式从某个页面加载 HTML,所以我想出了以下解决方案:

import org.w3c.dom.Document;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class SynchronousExample  extends Application {

private static String HTML = "";
private static Stage stage;

@Override
public void start(Stage primaryStage) throws Exception {
    System.out.print( SynchronousExample.loadUrl("http://google.com") );

}

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

private static void attachDocumentPropertyListener(WebView webView){
    webView.getEngine().documentProperty().addListener(new ChangeListener<Document>() {
          @Override public void changed(ObservableValue<? extends Document> prop, Document oldDoc, Document newDoc) {
            String html = webView.getEngine().executeScript(
              "document.documentElement.outerHTML"
            ).toString();

            HTML = html;
            //after page load autmatically close the window
            if(stage != null){
                stage.close();
            }
          }
        });
}

public static String loadUrl(String url){
    WebView webView = new WebView();
    attachDocumentPropertyListener(webView);
    webView.getEngine().load(url);
    stage = new Stage();
    Scene scene = new Scene(webView);
    stage.setWidth(1);
    stage.setHeight(1);
    stage.setScene(scene);
    stage.showAndWait();
    // here HTML will be available
    return HTML;
}

}
于 2016-04-25T22:02:15.153 回答