JavaFX/SWT WebView synchronous loadcontent()

安稳与你 提交于 2019-12-24 02:55:10

问题


I have embedded JavaFX's WebView in an Eclipse SWT application and need to load html content. I need to block the execution of the current thread until the webengine has finished loading the contents. Anyone familiar with this scenario and can give some hints and/or best practices to achieve this? It seems that both SWT and JavaFX run in the same UI thread.

Thanks!


回答1:


Show a modal window while the loading is not finished. You can not block the application thread because SWT/JavaFX operate on the same




回答2:


A JavaFX webengine loads asynchronously per implementation. Any listener to the loadworker's stateproperty receives callback on the JavaFX thread. This thread also runs your UI, which is why you should NEVER block the JavaFX thread. In event based UI systems such as JavaFX, if you want to do some heavy work, you would do this in your own thread. Never, ever block the JavaFX thread.

The reason I'm answering is because I actually have a similar yet different situation in which I do need the load to be synchronous. My first idea was to wrap the load in my own thread and make that block, but the load operation needs to be called from the JavaFX thread. However, I figured out a way around this obstacle:

First I start a new thread in which I declare a semaphore (with 0 permits) from where I launch a Platform.runLater(...) that initiates an engine, adds a listener to the stateproperty and loads a URL, followed by trying to aquire the semaphore. This blocks, because the semaphore has no permits. In the listener's callback, I start another new thread in which I do my heavy work and from there I set some global data variable, after which I release the semaphore. This terminates my latter new thread and then informs the former new thread that the data is loaded so it may continue. This never blocks the JavaFX thread either.

When wrapping that in a function, you can emulate a synchronous load operation, but you should be cautious when using it: only call the function from outside the JavaFX thread. However, that makes perfect sense, because you should never be calling a synchronous (aka blocking) load on the JavaFX thread.




回答3:


I had the same problem, and I needed to load the HTML from certain page in synchronous manner, so and I came up with the following solution:

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

}


来源:https://stackoverflow.com/questions/19247872/javafx-swt-webview-synchronous-loadcontent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!