0
我打电话从JavaScript在一个JavaFX的WebView的Java方法。 Java方法做了一些工作,即不立即返回。什么是等待JavaScript完成该方法的自然方式?了JavaFx的WebView等待Java方法来完成
我打电话从JavaScript在一个JavaFX的WebView的Java方法。 Java方法做了一些工作,即不立即返回。什么是等待JavaScript完成该方法的自然方式?了JavaFx的WebView等待Java方法来完成
因为一切都在FX应用程序线程执行,你需要调用Java方法运行在后台线程长期运行过程中(否则你将会使UI反应迟钝)。您可以在JavaScript函数完成时调用该方法来调用它:请注意,该函数需要在FX应用程序线程上调用。一种方法是将呼叫打包在Platform.runLater()
中,但使用Task
会使事情变得更简洁。
这里是一个SSCCE:
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
public class WebViewCallbackTest extends Application {
private static final String HTML =
"<html>"
+ " <head>"
+ " <script>"
+ ""
+ " function doCall() {"
+ " javaApp.doLongRunningCall('updateResults');"
+ " }"
+ ""
+ " function updateResults(results) {"
+ " document.getElementById('results').innerHTML = results ;"
+ " }"
+ ""
+ " </script>"
+ " </head>"
+ " <body>"
+ " <div>"
+ " Result of call:"
+ " </div>"
+ " <div id='results'></div>"
+ " </body>"
+ "</html>";
private Button button;
private JSObject window;
@Override
public void start(Stage primaryStage) {
WebView webView = new WebView();
webView.getEngine().loadContent(HTML);
BorderPane root = new BorderPane(webView);
window = (JSObject) webView.getEngine().executeScript("window");
window.setMember("javaApp", this);
button = new Button("Run process");
button.setOnAction(e -> webView.getEngine().executeScript("doCall()"));
HBox controls = new HBox(button);
controls.setAlignment(Pos.CENTER);
controls.setPadding(new Insets(5));
root.setBottom(controls);
Scene scene = new Scene(root, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
public void doLongRunningCall(String callback) {
Task<String> task = new Task<String>() {
@Override
public String call() throws InterruptedException {
Thread.sleep(2000);
return "The answer is 42";
}
};
task.setOnSucceeded(e ->
window.call(callback, task.getValue()));
task.setOnFailed(e ->
window.call(callback, "An error occurred"));
button.disableProperty().bind(task.runningProperty());
new Thread(task).start();
}
public static void main(String[] args) {
launch(args);
}
}
(可能有比这更简单的方法:我不是在网页视图的Javascript <的专家 - > Java的通信,但是这似乎挺合我意。)