简体   繁体   中英

webEngine.executeScript(); Throwing Exception

I'm writing a JavaFX App, which Interacts with the JavaScript, Using WebView and WebEngine (.executeScript() Method).

Here, I have this part of code from Medow.java, which loads map.html(Contains JavaScript Code), And This Code Works Pretty well:

add_button.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent ea5) {


            //  webEngine.executeScript("document.fun();");  // For Drawing Shapes
            if (add == false) {

                webEngine.executeScript("document.fun();");  // For Drawing Shapes
                add = true;
            }
//            }
            else {
                webEngine.executeScript("document.reSet();"); // To remove Drawing Shapes
                add = false;
            }

        }
    });

In Here

webEngine.executeScript();

Is Invoking Appropriate JavaScript function's

But Now, I want my Java Code to Invoke Some JS function, when the Program Starts, So I'm directly writing :

webEngine.executeScript("document.draw();");

right Under/after the code, which loads the map.html file.

So, now as Both of the webEngine.execute("document.fun();"); and webEngine.executeScript("document.draw();"); are nearly similar, I cannot Understand what Difference does, it makes to be inside the <button>.setOnAction block and to be outside it, Because both WebEngine and webView are declared as Global Variables.

cannot invoke document.draw() function using HTML's onLoad options, because i need to pass some Values To function draw from java.

The Exception Generated is :

   netscape.javascript.JSException: TypeError: undefined is not a function (evaluating 'document.draw()')

how can i make this work? thank you

While Continuously trying to figure out whats the cause, I Discovered That the HTMLDocument Object, created using webEngine.load() , is for some reason visible only inside the handle method, And nowhere else, even though its been defined outside.

What happens here is that you want to call a JavaScript function before the content is loaded completely. Therefore the function draw is not defined. So the only way is to wait until the page is loaded. There are two ways that might prove useful: Add a changelistener on the state and execute the JavaScript once the loading has succeeded: String htmlURL = ... webView.getEngine().load(htmlURL);

webView.getEngine().stateProperty().addListener(new ChangeListener<Worker.State>() {
    @Override
    public void changed(ObservableValue<? extends Worker.State> ov, Worker.State t, Worker.State t1) {
        if (t1 == Worker.State.SUCCEEDED) {
            // this will be run as soon as WebView is initialized.
            webView.getEngine().executeScript("document.draw()");               
        }
    }
});

The other way is more of a solution within JavaScript. You first have to register a bridge between Java and your html page (has to be done in the SUCCEEDED state change as well, see WebView callback from Javascript ):

JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("app", this);

Now this JavaObject is referenced in your JavaScript. Let's say that you have a method on the class that is of the above type of this :

public void executeOnPageLoaded() {
  ...
}

Then you can call this method from Javascript. If you are using jQuery it could look like this:

$( document ).ready(function() {
    console.log( "ready!" );
    app.executeOnPageLoaded();
});

This second approach is more complex but in the long run may give you more flexibility.

When you start working with JavaScript in the WebView is is a good idea to have Firebug lite in there as well, so investigate what is happening but mainly to have a means to seed the console output of JavaScript. See Java FX application onload event

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM