我在Eclipse SWT应用程序中嵌入了JavaFX的WebView,需要加载html内容。 我需要阻止当前线程的执行,直到webengine完成加载内容。任何熟悉这种情况的人都可以提供一些提示和/或最佳实践来实现这一目标吗?似乎SWT和JavaFX都在同一个UI线程中运行。
谢谢!
答案 0 :(得分:1)
加载未完成时显示模态窗口。您无法阻止应用程序线程,因为SWT / JavaFX在相同的
上运行答案 1 :(得分:1)
每个实现都会异步加载JavaFX Web引擎。 loadworker的stateproperty的任何监听器都会在JavaFX线程上收到回调。这个线程也运行你的UI,这就是你永远不应该阻止JavaFX线程的原因。在基于事件的UI系统(如JavaFX)中,如果您想做一些繁重的工作,可以在自己的线程中执行此操作。永远不要阻止JavaFX线程。
我回答的原因是因为我实际上有一个类似但又不同的情况,我做需要负载同步。我的第一个想法是将负载包装在我自己的线程中并生成该块,但是需要从JavaFX线程调用加载操作。但是,我想出了解决这个障碍的方法:
首先,我启动一个新线程,我在其中声明一个信号量(带0个许可证),从中我启动一个启动引擎的Platform.runLater(...),向stateproperty添加一个监听器并加载一个URL,然后试图获取信号量。这会阻塞,因为信号量没有许可证。在监听器的回调中,我启动另一个新线程,在其中我做了大量的工作,并从那里设置了一些全局数据变量,之后我释放了信号量。这将终止我后一个新线程,然后通知前一个新线程数据已加载,因此可以继续。这永远不会阻止JavaFX线程。
在函数中包装它时,可以模拟同步加载操作,但在使用它时应该小心:只从JavaFX线程外部调用该函数。但是,这非常有意义,因为您永远不应该在JavaFX线程上调用同步(即阻塞)加载。
答案 2 :(得分:0)
我遇到了同样的问题,我需要以同步的方式从某个页面加载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;
}
}