JavaFX WebView在重新加载时重新创建窗口
我正在创建一个页面,可以从Java在WebView中打开,也可以在外部浏览器中手动打开。若页面是从Java加载的——我需要它来执行特定的回调,因为Java被用作后端,但若页面是手动加载的,它应该从它的资源中加载不同的数据。所以我尝试注册一个JS“JavaInit”对象,它可以在文档加载时调用。HTML看起来有点像这样:JavaFX WebView在重新加载时重新创建窗口,webview,javafx,reload,onload,javafx-webengine,Webview,Javafx,Reload,Onload,Javafx Webengine,我正在创建一个页面,可以从Java在WebView中打开,也可以在外部浏览器中手动打开。若页面是从Java加载的——我需要它来执行特定的回调,因为Java被用作后端,但若页面是手动加载的,它应该从它的资源中加载不同的数据。所以我尝试注册一个JS“JavaInit”对象,它可以在文档加载时调用。HTML看起来有点像这样: <html> <head> <script type='text/javascript' src="http://code.
<html>
<head>
<script type='text/javascript' src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script type="text/javascript">
DefaultInit = {
init: function(x) {
return "Default init: " + x;
}
};
$(function() {
var text;
if (window["JavaInit"] && JavaInit.init)
text = JavaInit.init("passed text");
else
text = DefaultInit.init("passed text");
$("#title").html(text);
});
</script>
</head>
<body>
<h1 id="title"></h1>
</body>
</html>
public class Test extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
WebView web = new WebView();
Scene scene = new Scene(web, 400, 300);
primaryStage.setScene(scene);
primaryStage.show();
initWeb(web);
}
private static void initWeb(WebView web) {
WebEngine eng = web.getEngine();
((JSObject)eng.executeScript("window")).setMember("JavaInit", new JavaInit());
URL url = Test.class.getResource("/test.html");
eng.load(url.toString());
}
public static class JavaInit {
public String init(Object o) {
return "Java init: " + o;
}
}
}
它完全按照要求工作,但只有一次,在任何人调用“重新加载页面”之前。重新加载后,引擎似乎会重新创建“窗口”对象,所有注册成员都会消失
可以将#setMember放置在“状态属性”侦听器中:
private static void initWeb(WebView web) {
WebEngine eng = web.getEngine();
eng.getLoadWorker().stateProperty().addListener((val, oldState, newState) -> {
if (newState == State.SUCCEEDED)
((JSObject)eng.executeScript("window")).setMember("JavaInit", new JavaInit());
});
URL url = Test.class.getResource("/test.html");
eng.load(url.toString());
}
但是只有在启动window.onload之后才会调用它,并且始终调用默认init。可以通过以最小延迟调用init代码来修复:
$(function() {
setTimeout(function() {
var text;
if (window["JavaInit"] && JavaInit.init)
text = JavaInit.init("passed text");
else
text = DefaultInit.init("passed text");
$("#title").html(text);
});
});
然后从JS将控件处理回Java(如果存在的话),然后返回注册函数,程序每次都可以正常工作
但是,创建initdelay希望Java能够成功注册所有成员,这似乎有点错误。那么有人知道实现这种功能的“更合适”的方法吗?在生产中是否可能需要更多的时间,JS是否可以在注册成员之前调用延迟函数?或者是否有任何保证WebEngine将连续处理Java事件和JS执行
谢谢 我也有同样的问题,我需要在JS中启动onload事件之前设置成员。我在标题中添加了JS中的警报:
alert("command:inject");
在Java代码中:
webEngine.setOnAlert(new EventHandler<WebEvent<String>>() {
@Override
public void handle(WebEvent<String> event) {
// set members here
}
});
webEngine.setOnAlert(新的EventHandler(){
@凌驾
公共无效句柄(WebEvent事件){
//在这里设置成员
}
});
看起来,on alert句柄是同步运行的,所以当onload启动时,脚本将启动,它将看到在on alert handler中设置的成员,这些成员都是相同的问题。。。有人知道更好的解决方案吗?可能是