2

I want to learn more about JavaFX and so I tried to set up Webview. I copied the webview example from the Oracle website and added Upcall functionality. But it isn't working. Actually I have no idea how to debug a website in Webview. So here is the java code:

package boersensim;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;


public class Main extends Application {
private Scene scene;
@Override public void start(Stage stage) {
    // create the scene
    stage.setTitle("Web View");
    scene = new Scene(new Browser(),750,500, Color.web("#666970"));
    stage.setScene(scene);
    //scene.getStylesheets().add("webviewsample/BrowserToolbar.css");
    stage.show();
}

public static void main(String[] args){
    launch(args);
}
}
class Browser extends Region {

final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();

public Browser() {
    //apply the styles
    getStyleClass().add("browser");
    // load the web page
    webEngine.load("test.html");
    //add the web view to the scene
    getChildren().add(browser);

    JSObject jsobj = (JSObject) webEngine.executeScript("window");
    jsobj.setMember("java", new Bridge());
}
private Node createSpacer() {
    Region spacer = new Region();
    HBox.setHgrow(spacer, Priority.ALWAYS);
    return spacer;
}

@Override protected void layoutChildren() {
    double w = getWidth();
    double h = getHeight();
    layoutInArea(browser,0,0,w,h,0, HPos.CENTER, VPos.CENTER);
}

@Override protected double computePrefWidth(double height) {
    return 750;
}

@Override protected double computePrefHeight(double width) {
    return 500;
}
}

class Bridge {
public void exit() {
    //Platform.exit();
    System.out.print("Hello!UPCALL");
}
}

The corrosponding HTML is:

Click<a href="#" onclick="java.exit();">here</a>to exit the application

When I click the link nothing happens.

Thanks to you in advance, Daniel

3 Answers 3

3

set Bridge() on page loaded event

webEngine.setJavaScriptEnabled(true);
webEngine.getLoadWorker().stateProperty().addListener(
            new ChangeListener<Worker.State>() {
                public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
                    if (newState == Worker.State.SUCCEEDED) {                        
                        JSObject jso = (JSObject) webEngine.executeScript("window");
                        jso.setMember("java", new Bridge());
                    }

                }
            });
Sign up to request clarification or add additional context in comments.

Comments

2

I also followed this tutorial (probably the one you used): https://blogs.oracle.com/javafx/entry/communicating_between_javascript_and_javafx

And found that it makes the JVM crash. So I reported an issue on the JavaFX jira, and I got the following reply:

It is a requirement since 7u5 that the methods called from JS be accessible in Java sense, i.e. >public members of public classes. (This is mentioned in the last comment to the article). In this >particular test case Bridge should be declared a public class.

The crash was fixed in JDK8. Now an exception is thrown.

And that works.

1 Comment

If I had only seen this response 3 hours ago! I had a static inner class without the public modifier, and the JVM crashes. Added public to the class and now it works. Thank you!
0

Three things to be change in you code Daniel,
1) Make your class Bridge public
2) Enable JavaScript like this webEngine.setJavaScriptEnabled(true);
3) set Member Bridge() on page loaded event like bellow

webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {

        @Override
        public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
            // TODO Auto-generated method stub
             if (newValue == Worker.State.SUCCEEDED) {                        
                 JSObject jso = (JSObject) webEngine.executeScript("window");
                 jso.setMember("java", new Bridge());
             }

        }
    });

Welcome, Daniel

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.