如何创建与 JavaFx WebView 一起使用的 JavaScript 包装器? JSNI 是一个选项吗?

How to create a JavaScript wrapper to be used with JavaFx WebView? Is JSNI an option?

我想结合使用 JavaFx WebEngine 和 JavaScript 库 d3.js。我已经能够从 Java 中访问 JavaScript 库。如 [1] 所示,使用 JSObjects 是可行的:

JSObject d3Object = (JSObject) webEngine.executeScript("d3");
JSObject chart= (JSObject) d3Object.call("select", ".chart");

如您所见,有一个通用方法 "call",我必须将要调用的 JavaScript 方法的名称作为字符串传递。为了更舒适地使用 JavaScript 库 d3.js,我想要一个 Java 包装器,例如

JSObject d3Object = (JSObject) webEngine.executeScript("d3");
D3Wrapper d3 = new D3Wrapper(d3Object);
Selection chart = d3.select(".chart");

创建这样的 Java 脚本包装器的推荐方法是什么?我发现已经有一个针对 GWT 应用程序的 D3 包装器。 d3 对象的主要包装器位于此处:

https://github.com/gwtd3/gwt-d3/blob/master/gwt-d3-api/src/main/java/com/github/gwtd3/api/D3.java

它似乎是基于 JSNI [2] 并且示例方法定义是

public static final native Selection select(String selector)/*-{
    return $wnd.d3.select(selector);
}-*/;

在Java中调用方法时将执行注释中的本机代码。如何在我的 JavaFx 桌面应用程序中利用现有的包装器代码?我以前从未使用过 GWT,我不想 运行 一个额外的网络服务器。我真的需要深入研究 GWT 和 运行 JavaFx WebEngine 中的完整 GWT 应用程序(如果可能的话)吗?或者我能以某种方式只将 GWT 的 JSNI 部分与 JavaFx WebEngine 一起使用吗?

这里有一篇关于 GWT 调试模式的文章,看起来很复杂:http://www.quora.com/How-does-GWT-live-javascript-debugging-in-Eclipse-work-and-how-could-it-be-applied-to-Clojure 所以恐怕没有简单的方法可以将 WebEngine 插入这样的工作流程中?我真的需要手动重写每个包装 类 "already provides by gwt-d3" 吗?如果本机 JavaScript 代码将由 Annotations 给出,我可以重用 gwt-d3 中的包装器 类 并通过反射处理它们。

如果将 JSNI 与 JavaFx 组合没有任何意义,那么为 d3.js 编写自己的包装器的优雅方式是什么?是否有 Java 库可以帮助我编写 Java 脚本包装器?

事实证明,JSNI 不是(可行的)选项。我决定从 gwt-d3 的现有包装器代码开始,并通过搜索和替换操作对其进行转换……并进行一些手动微调。这样它就不再适用于 GWT,但适用于 JavaFx。我将为转换后的代码创建一个新的 GitHub 项目。

我的包装器 classes 继承自抽象基础 class JavaScriptObject,它与 JavaFx WebEngine 对话并处理 JSObject 操作。可以在这里找到与 gwt-d3 作者的相关讨论:https://github.com/gwtd3/gwt-d3/issues/124

编辑

我刚刚创建了一个新的 GitHub 项目:

https://github.com/stefaneidelloth/javafx-d3

请随时加入并帮助修复剩余的错误。