【问题标题】:Java API for manipulating html/Javascript DOM elements in a desktop application?用于在桌面应用程序中操作 html/Javascript DOM 元素的 Java API?
【发布时间】:2017-05-20 04:16:09
【问题描述】:

H: 下给出了现有的 HTML 元素:

https://developer.mozilla.org/de/docs/Web/API

此处显示了可用的 JAVA API 类:

https://xerces.apache.org/xerces2-j/javadocs/api/org/w3c/dom/Element.html

不幸的是,org.w3c.dom 包遗漏了一些更具体的元素,例如 HTMLCanvasElement

我正在寻找一些更高级的 Java API,至少支持 HTMLCanvasElements(完整的 WEP API 支持会很棒)。


到目前为止我发现了什么:

A.对于javafx-d3 项目,我使用JavaFx WebView 来控制Java 中的一些JavaScript。 Java 和 JavaScript 之间的通信是基于 netscape.javascript.JSObject 的,原则上可以正常工作:

我能够将我从 JavaScript 世界获得的 JSObject 转换为 org.w3c.dom.Element ... 并使用它的 Java 方法来操作 DOM。

如果我想“更深入”,例如控制一个 HTMLCanvasElement,我必须基于 JSObject 编写自己的包装器。这是可能的,但感觉就像在重新发明轮子。


B. Google GWT 似乎提供了一些包装类,例如

com.google.gwt.dom.client.CanvasElementHTMLCanvasElement

但是我没有设法将 netscape.javascript.JSObject 转换为 GWT 包装类(从 com.google.gwt.core.client.JavaScriptObject 开始)。

如果可能的话,有人可以提供一个例子吗?

有人知道如何让下面的虚拟示例运行吗?

package main;

import elemental.client.Browser;
import elemental.html.AudioContext;
import elemental.html.AudioParam;
import elemental.html.Oscillator;
import elemental.html.Window;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class GwtElementDemo extends Application {

    private Scene scene;

    private Region browser;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {

        //set state title
        stage.setTitle("JavaFx demo");  


        browser = new Region();

         Window window = Browser.getWindow();
            AudioContext audioContext = window.newAudioContext();
            Oscillator osc = audioContext.createOscillator();
            osc.setType(Oscillator.SQUARE);
            osc.connect((AudioParam) audioContext.getDestination(), 0);
            osc.getFrequency().setValue(440.0f);
            osc.noteOn(0);

        //create the scene
        scene = new Scene(browser, 750, 500, Color.web("#666970"));
        stage.setScene(scene);
        stage.show();

    }   

}

GWT elemental 的 maven 依赖项:

<dependency>
         <groupId>com.google.gwt</groupId>
         <artifactId>gwt-elemental</artifactId>
          <version>2.8.0</version>
</dependency>

或者您知道用于 DOM 操作的替代/高级 JAVA API(即构建在 JSObject 层次结构上)?

【问题讨论】:

    标签: javascript java api dom gwt


    【解决方案1】:

    是的,有一个,非常接近您已经找到的。它被称为 GWT 元素。虽然是 GWT,但它真的是直接在 DOM 上,非常完整,真的很像直接在 DOM 上的如履薄冰。我正在使用它在 https://github.com/nielsbaloe/vertxui 编写一个 100% java 100% 异步框架 VertxUI。

    【讨论】:

    • 您似乎对 GWT elemental 有很多经验。您是否看到了如何完成我在上面添加的 JavaFx 应用程序示例以在 JavaFx 场景中显示一些 GWT 元素内容的方法?我可以使用任何浏览器构造函数吗?
    • 我刚刚发现了一个将 GWT elemental 移植到 JavaFx 的项目。还没试过:github.com/my2iu/gwt
    • 我在 GWT elemental 方面并没有真正的经验,它开箱即用就非常好用。我只使用文档、控制台和窗口,换句话说:浏览器中 javascript 上可用的原语。我不知道其余的。我在 JavaFX 方面没有任何经验(这对我来说有点死)。祝你好运,看看上面的链接!
    • 附言。使用 GWT elemental 确实回答了您最初的问题。我真的不明白您为什么要查看 JavaFX,它不是用于操作 HTML 的 API,作为您的原始问题。它是一个基于 HTMl 等的独立范例。Elemental 为您提供了真正完整的 Web API,包括 CanvasElement(以及大约 200 个以上的类)。
    • 我没有给你投反对票。也许我的问题的表述不够清楚。只是为了澄清一下:我不想创建一个 Web 应用程序,而是一个经典的 桌面应用程序,在嵌入式浏览器组件中使用一些 java 脚本。我的大部分代码仍将直接在 JVM 上以 Java 运行。 GWT(元素)的目标是不同的(如果我理解正确的话).... 将所有内容编译为 JavaScript 以创建 Web 应用程序。如果我的主要目标是创建一个 Web 应用程序,我想我会直接用 JavaScript 编写代码。
    【解决方案2】:

    我是您在 cmets 中提到的尝试将 Elemental 移植到 JavaFx 的人。我用它制作了一个名为 Animation Companion 的小应用程序,但它并不是那么好。 JavaFx 提供的 WebKit 引擎缺少很多功能,并且将大量数据从 Java 移动到 JavaScript 并返回非常慢。 JavaFx 人重写了 WebKit 以依赖 JavaFx 进行渲染,有时会出现一点不匹配,如果你太用力推动 UI 会导致事情崩溃或耗尽资源。此外,Elemental 本身有点过时,有很多 WebKit 特定的功能、缺失的功能和其他错误。

    我的 github 上的测试 JavaFx 代码要求您首先构建元素。我不完全记得如何做到这一点。我认为您只需进入基本目录并在那里运行ant,然后您会在某处获得gwt-elemental.jar 文件输出,您可以将测试链接到该位置。我暂时在 http://www.user00.com/gwt-elemental.jar 放置了一个预构建版本。您还需要来自 GWT 2.7 的 gwt-user.jar 的一些文件。我暂时在 http://www.user00.com/gwt-user-pruned.jar 上提供了这些文件。从那里,您可以使用以下内容启动网页:

    Stage stage = ...
    
    // Create the WebView
    BorderPane border = new BorderPane();
    WebView webView = new WebView();
    final WebEngine engine = webView.getEngine();
    border.setCenter(webView);
    
    Scene scene = new Scene(border);
    stage.setScene(scene);
    stage.show();
    
    // Redirect the alert handler to send output to stderr
    engine.setOnAlert(new EventHandler<WebEvent<String>>() {
       @Override
       public void handle(WebEvent<String> msg) {
          System.err.println(msg.getData());
       }});
    
    // Start up the Gwt module when the page has finished loading. Grab the window
    // and document objects and stash them somewhere for use later.
    engine.getLoadWorker().stateProperty().addListener(
          new ChangeListener<Worker.State>() {
             @Override
             public void changed(ObservableValue<? extends State> ov,
                   State oldState, State newState) {
                if (newState == Worker.State.SUCCEEDED) {
                   Window win = (Window)GwtFxBridge.wrapJs(engine.executeScript("window"));
    
                   // The web page is loaded, and you have the global window
                   // JS object, so you can start your UI now
                 }
             }
          });
    
    // Load the main Gwt application web page
    try {
       engine.load(new File("ui/index.html").toURI().toURL().toExternalForm());
    } 
    catch(MalformedURLException e)
    {
       throw new IllegalArgumentException("Misconfiguration error. Cannot find empty web page", e);
    }
    

    我真的不建议走这条路。对它的支持还不够,您必须非常了解您的 JavaScript 和 Java 才能调试您将面临的问题。我认为颠倒事物更有意义。运行 nw.js 以将 JavaScript 作为驱动应用程序的主要 VM 运行,然后在需要执行 Java 操作时调用 Java。您甚至可以使用 GWT 从 Java 代码生成 JavaScript。

    【讨论】:

    • 感谢您的详细回答。使用您的 jar,我运行了一个 JavaFx 应用程序,该应用程序能够使用 gwt elemental api 控制 DOM。 win.alert("Hello World");正在工作,我能够检索文档的高度。 window.newAudioContext() 不起作用...这可能是由于您提到的限制。
    • 我还发现了我的项目 java-fx 的 WebView 的一些性能问题,有关该主题的更多信息可以在这里找到:stackoverflow.com/questions/10762979/…
    • 使用商业 JxBrowser 代替 WebView 可能是一种选择。也许还有其他选择。
    • nwjs.io 看起来很有趣!我目前在一些 Eclipse 插件中使用 WebView 作为从 Java 到 JavaScript 的桥梁 .... 以便能够使用 JavaScript 库 d3.js 在 Eclipse (github.com/stefaneidelloth/treez) 中进行科学绘图。我想不可能为那个用例应用 nw.js,但我会看看。
    猜你喜欢
    • 1970-01-01
    • 2012-07-12
    • 1970-01-01
    • 2014-05-03
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多