In order to call JavaFX from Javascript in WebView, we can create a JSObject in JavaFX, and then calling it's setMember() method to make it known to Javascript. After that, Javascript can call it's public methods and access it's public field.
JavaFX code:
package javafxweb; import java.net.URL; import javafx.application.Application; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.concurrent.Worker.State; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.HPos; import javafx.geometry.Insets; import javafx.geometry.VPos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.HBox; import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.scene.web.WebEngine; import javafx.scene.web.WebView; import javafx.stage.Stage; import netscape.javascript.JSObject; /** * * @web http://java-buddy.blogspot.com/ */ public class JavaFXWeb extends Application { private Scene scene; MyBrowser myBrowser; Label labelFromJavascript; /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("java-buddy.blogspot.com"); myBrowser = new MyBrowser(); scene = new Scene(myBrowser, 640, 480); primaryStage.setScene(scene); primaryStage.show(); } class MyBrowser extends Region{ HBox toolbar; VBox toolbox; WebView webView = new WebView(); WebEngine webEngine = webView.getEngine(); public MyBrowser(){ final URL urlHello = getClass().getResource("hello.html"); webEngine.load(urlHello.toExternalForm()); webEngine.getLoadWorker().stateProperty().addListener( new ChangeListener<State>(){ @Override public void changed(ObservableValue<? extends State> ov, State oldState, State newState) { if(newState == State.SUCCEEDED){ JSObject window = (JSObject)webEngine.executeScript("window"); window.setMember("app", new JavaApplication()); } } }); JSObject window = (JSObject)webEngine.executeScript("window"); window.setMember("app", new JavaApplication()); final TextField textField = new TextField (); textField.setPromptText("Hello! Who are?"); Button buttonEnter = new Button("Enter"); buttonEnter.setOnAction(new EventHandler<ActionEvent>(){ @Override public void handle(ActionEvent arg0) { webEngine.executeScript( " updateHello(' " + textField.getText() + " ') " ); } }); Button buttonClear = new Button("Clear"); buttonClear.setOnAction(new EventHandler<ActionEvent>(){ @Override public void handle(ActionEvent arg0) { webEngine.executeScript( "clearHello()" ); } }); toolbar = new HBox(); toolbar.setPadding(new Insets(10, 10, 10, 10)); toolbar.setSpacing(10); toolbar.setStyle("-fx-background-color: #336699"); toolbar.getChildren().addAll(textField, buttonEnter, buttonClear); toolbox = new VBox(); labelFromJavascript = new Label(); toolbox.getChildren().addAll(toolbar, labelFromJavascript); labelFromJavascript.setText("Wait"); getChildren().add(toolbox); getChildren().add(webView); } @Override protected void layoutChildren(){ double w = getWidth(); double h = getHeight(); double toolboxHeight = toolbox.prefHeight(w); layoutInArea(webView, 0, 0, w, h-toolboxHeight, 0, HPos.CENTER, VPos.CENTER); layoutInArea(toolbox, 0, h-toolboxHeight, w, toolboxHeight, 0, HPos.CENTER, VPos.CENTER); } } public class JavaApplication { public void callFromJavascript(String msg) { labelFromJavascript.setText("Click from Javascript: " + msg); } } }
hello.html
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset=utf-8> <title>Hello Java-Buddy!</title> <script> function updateHello(user){ document.getElementById("helloprompt").innerHTML="Hello: " + user; } function clearHello(user){ document.getElementById("helloprompt").innerHTML="Hello <a href='http://java-buddy.blogspot.com/'>Java-Buddy</a>"; } function callJavaFX(){ var msg = document.getElementById("textto").value; app.callFromJavascript(msg); } </script> </head> <body> <img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxGfYYk9MPmsy4Fb5yBONPauX59KlswhZvZL_XoWgvPMp2SwHsLorHIo4aWZJsUc9oynuzwstK5MfzjmjmNevnJFjJt1HIhcl-iRH3dnK2twWSeX6MdjSbAz4nyMzaNQE1p-Pajqfg3KKN/s150/duke_44x80.png"/> <p id="helloprompt">Hello <a href="http://java-buddy.blogspot.com/">Java-Buddy</a></p> <p><textarea id="textto"> </textarea></p> <p><input type="button" value="Click to send message to Javascript" onclick="callJavaFX()"></p> </body> </html>
I am unable to get the value from JavaScript.. i.e. when i am clicking on get value from Java script i am not getting the value...
ReplyDeleteThanks buddy , it works :)
ReplyDeleteTNX BROV... :D :D u solvd my Day
ReplyDeleteHey...... This is Not Working In Java 8.0_121, sometimes is working , but some times is not
ReplyDeletecan you please help me to resolve this.
See https://stackoverflow.com/questions/41903154/javafx-webview-callback-from-javascript-failing-after-garbage-collection
Delete'new JavaApplication()' should be saved in a field.