Reputation: 12252
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)?
Upvotes: 1
Views: 1987
Reputation: 155
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 .
Upvotes: 0
Reputation: 884
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.
Upvotes: 2