2017-03-02 15 views
0

JavaFx WebViewのJavaScriptからJavaメソッドを呼び出しています。 Javaメソッドはいくつかの機能を果たします。つまり、すぐには戻りません。メソッドがJavaScriptから終了するのを待つ自然な方法は何ですか?JavaFx WebViewがJavaメソッドの終了を待つ

答えて

0

すべてがFXアプリケーションスレッドで実行されるため、呼び出したJavaメソッドはバックグラウンドスレッドで長期実行プロセスを実行する必要があります。そうしないと、UIが応答しなくなります。メソッドが完了したときに呼び出すJavascript関数を渡すことができます。このjavascript関数をFXアプリケーションスレッドで呼び出す必要があることに注意してください。 1つの方法は、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); 
    } 
} 

(これよりももっと簡単な方法があるかもしれません:。私はWebViewのJavascriptを<の専門家ではないです - > Javaの通信が、これは私にはOKらしい)

関連する問題