Reputation: 1552
i used this code
public WebMap() {
webView = new WebView();
final WebEngine webEngine = webView.getEngine();
String url = getClass().getResource("map.html").toExternalForm();
webEngine.load(url);
final Deferred d = new Deferred();
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
@Override
public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
d.resolve(webEngine);
}
}
}
);
readyWebEngine = d.promise();
}
I don't call webEngine.executeScript directly but i use
readyWebEngine.then(new PromiseFunc() {
@Override
public Promise apply(Object oWebEngine) {
WebEngine webEngine = (WebEngine)oWebEngine;
webEngine.executeScript(script); // <=============================
// return value doesn't matter
return (new Deferred()).promise();
}
});
So that the script
string isn't evaluated until the promise is resolved (fulfilled) by the call to d.resolve()
Let's assume that the promise library is correct
The code works well for me, but a colleague of mine gets this error which is frustrating
netscape.javascript.JSException: ReferenceError: Can't find variable: gotoLatLng
[com.sun.webpane.platform.WebPage.twkExecuteScript(Native Method), com.sun.webpane.platform.WebPage.executeScript(WebPage.java:1438), javafx.scene.web.WebEngine.executeScript(WebEngine.java:811), packagename.WebMap.WebMap$1.apply(WebMap.java:36), packagename.WebMap.promise.Deferred$1$1.apply(Deferred.java:23), packagename.WebMap.promise.Deferred.resolve(Deferred.java:40), packagename.WebMap.WebMap$2.changed(WebMap.java:57), packagename.WebMap.WebMap$2.changed(WebMap.java:52), com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:196), com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:100), javafx.beans.property.ReadOnlyObjectWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyObjectWrapper.java:195), javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:161), javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:130), javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:163), javafx.scene.web.WebEngine$LoadWorker.updateState(WebEngine.java:975), javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1086), javafx.scene.web.WebEngine$LoadWorker.access$600(WebEngine.java:968), javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:955), com.sun.webpane.platform.WebPage.fireLoadEvent(WebPage.java:2356), com.sun.webpane.platform.WebPage.fwkFireLoadEvent(WebPage.java:2204), com.sun.webpane.webkit.network.URLLoader.twkDidFinishLoading(Native Method), com.sun.webpane.webkit.network.URLLoader.access$1300(URLLoader.java:44), com.sun.webpane.webkit.network.URLLoader$6.run(URLLoader.java:691), com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76), com.sun.glass.ui.win.WinApplication._runLoop(Native Method), com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:17), com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:67), java.lang.Thread.run(Thread.java:744)]
The html page containing the javascript code is well tested. Let's assume there is no javascript errors there
The error netscape.javascript.JSException: ReferenceError: Can't find variable: gotoLatLng
doesn't occure to me because javascript code is executed after the loadWorker's newState == State.SUCCEEDED.
The probleme is that in the stack trace of my coworker's program , we can see that the WebEngine.executeScript(WebEngine.java:811)
was called by
packagename.WebMap.promise.Deferred.resolve(Deferred.java:40), packagename.WebMap.WebMap$2.changed(WebMap.java:57), packagename.WebMap.WebMap$2.changed(WebMap.java:52), com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:196), com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:100),
So, executeScript is called by the listener of the load changed event
when newState == State.SUCCEEDED
which means that the page is completely loaded and javascript inside s is loaded (variables should be defined).
Sorry because i don't have access to my coworker's code, but it's based on mine. Now i am not sure whether this code executes javascript code at the right moment
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
@Override
public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
webEngine.executeScript(script);
}
}
}
);
Any help?
Upvotes: 3
Views: 3412
Reputation: 2183
How about
$(function(){
alert("command:ready");
});
And then
engine.onAlert = new EventHandler<WebEvent<String>>() {
@Override
void handle(WebEvent<String> event) {
if("command:ready".equals(event.getData())){
//TODO: initialize
}
}
}
(seen here http://habrahabr.ru/company/codeorchestra/blog/198776/)
Upvotes: 4