1

The existing HTML elements are given here under H:

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

The available JAVA API classes are shown here:

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

Unfortunately the org.w3c.dom package misses some more specific elements like HTMLCanvasElement.

I am looking for some more advanced Java API that at least supports the HTMLCanvasElements (full WEP API support would be great).


What I found so far:

A. For the Project javafx-d3 I use the JavaFx WebView to control some JavaScript in Java. The communication between Java and JavaScript is based on netscape.javascript.JSObject and works fine in principle:

I am able to cast a JSObject that I got from the JavaScript world to an org.w3c.dom.Element ... and use its Java methods to manipulate the DOM.

If I want to "go deeper", e.g. control a HTMLCanvasElement, I have to write my own wrappers based on JSObject. That is possible but feels like reinventing the wheel.


B. Google GWT seems to provide some wrapper Classes, e.g.

com.google.gwt.dom.client.CanvasElement for HTMLCanvasElement

However I did not manage to convert netscape.javascript.JSObject to the GWT wrapper classes (starting from com.google.gwt.core.client.JavaScriptObject) .

If this is possible at all, could someone provide an example?

Anybody knows how to get that dummy example below running?

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();

    }   

}

maven dependency for GWT elemental:

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

Or do you know an alternative/advanced JAVA API for DOM manipulation (that is build on the JSObject hierarchy)?

Stefan
  • 10,010
  • 7
  • 61
  • 117

2 Answers2

2

I'm the guy who tried to port Elemental to JavaFx that you mentioned in the comments. I made a small application called Animation Companion with it, and it just isn't that great. The WebKit engine provided with JavaFx is missing a lot of features, and it's very slow to move a lot of data from Java to JavaScript and back. The JavaFx people rewrote WebKit to depend on JavaFx for its rendering, and sometimes there's a bit of a mismatch, which will cause things to crash or run out of resources if you push the UI too hard. Also, Elemental itself is a bit out-dated with a lot of WebKit-specific functionality, missing features, and other bugs.

The test JavaFx code from my github requires you to build elemental first. I don't entirely remember how to do that. I think you just go into the elemental directory and run ant there, and then you get a gwt-elemental.jar file output somewhere that you can link the tests against. I have temporarily put a pre-built version at http://www.user00.com/gwt-elemental.jar . You also need a few files from gwt-user.jar from GWT 2.7. I've temporarily made those files available at http://www.user00.com/gwt-user-pruned.jar . From there, you can start a web page with something like this:

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);
}

I really wouldn't advise going down this route. There just isn't enough support for it, and you have to know your JavaScript and your Java really well to debug the problems that you'll face. I think it makes more sense to invert things. Run nw.js to run JavaScript as the main VM driving your application and then call into Java as necessary if you need to do Java things. You can even use GWT to generate your JavaScript from Java code.

Ming-Yee Iu
  • 844
  • 6
  • 5
  • Thanks for the detailed answer. Using your jars I got a JavaFx application running that is able to control the DOM with the gwt elemental api. win.alert("Hello World"); is working and I am able to retrieve the height of the document. window.newAudioContext() does not work... which might be due to the restrictions that you mentioned. – Stefan Jan 17 '17 at 07:04
  • I also found some performance issues of the WebView for my project java-fx and further information on that topic can be found here: http://stackoverflow.com/questions/10762979/performance-of-webview-in-javafx – Stefan Jan 17 '17 at 07:07
  • Using the commercial JxBrowser instead of WebView might be an option. Maybe there are also other alternatives out there. – Stefan Jan 17 '17 at 07:14
  • https://nwjs.io looks interesting! I currently use the WebView inside some Eclipse plugins as a bridge from Java to JavaScript .... to be able to use the JavaScript library d3.js for scientific plotting in Eclipse ( https://github.com/stefaneidelloth/treez ). I guess that it won't be possible to apply nw.js for that use case but I'll have a look. – Stefan Jan 17 '17 at 07:27
0

Yes there is one, very close to what you already found. It is called GWT elemental. Although it's GWT, it's really directly on the DOM, incredibly complete and really really like thin ice directly on the DOM. I'm using it to write a 100% java 100% asynchronous framework VertxUI at https://github.com/nielsbaloe/vertxui .

Niels
  • 145
  • 1
  • 8
  • You seem to have a lot of experience with GWT elemental. Do you see a way how to complete the JavaFx application example that I added above to show some GWT elemental content on the JavaFx scene? Is there any browser constructor I could use? – Stefan Jan 16 '17 at 19:47
  • I just found a project that ported GWT elemental to JavaFx. Did not try it yet: https://github.com/my2iu/gwt – Stefan Jan 16 '17 at 20:11
  • I'm not really experienced in GWT elemental, it just works really great right out of the box. I only use document, console and window, in other words: the primitives that are available on javascript in the browser. I don't know about the rest. I don't have any experience in JavaFX (which looks kinda dead to me). Good luck with looking at the link above! – Niels Jan 18 '17 at 12:40
  • PS. Your original question is really answered by using GWT elemental. I don't really understand why you are looking at JavaFX, it is not an API for manipulating HTML, as your original question. It is a seperate paradigm which rests on HTMl etc. Elemental gives you really the full web API, including CanvasElement (and about 200 more classes). – Niels Jan 18 '17 at 23:32
  • I did not give you the down vote. Maybe the formulation of my question was not clear enough. Just for clarification: I dont want to create a web application but a classical **desktop application** with java, utilizing some java script in an embedded browser component. Most of my code will still run in Java on the JVM directly. The aim of GWT (elemental) is different (if I get it right) .... compile mostly everything to JavaScript to create a web application. If my main target would be to create a web application I would write my code directly in JavaScript, I guess. – Stefan Jan 19 '17 at 13:25
  • Ah no worry about the downvote, at least I don't ;) Ah a desktop application. I guess then you need to look at java webstart, using swing. That's about the only way I know to write a 100% normal desktop application with Java, with access to everything on the computer like you normally have. You don't need the browser, it is only the startpoint. – Niels Jan 21 '17 at 20:17