I finished porting GWT Elemental to JavaFx's WebView. I call it ElementalFx. The code is sitting in the "elementalfx" branch of my clone of the GWT git repository:
https://github.com/my2iu/gwt
With ElementalFx, you can use GWT Elemental to make desktop apps. You can use the same UI code for both the desktop and for the web. It can be helpful in use cases like
1) You need to write a web-version and a PC/Mac/Linux-version of an app, and you don't want to write the UI code twice
2) You want to write a UI widget and share it between a HTML5 web page and a desktop application
3) You have an existing Swing or SWT application, and you want to migrate it to HTML5 by gradually replacing components and dialogs with HTML5 versions
4) You need to write a desktop application, but you don't want to waste your time learning a niche desktop UI framework when you could just use HTML5 for everything
5) You have some legacy Java UI programmers, and you want to upgrade their skills to include HTML5 in a gradual manner
6) You want to debug and test a GWT Elemental application without using SuperDevMode or DevMode
In the future, I would like to port Elemental to Android and iOS too, then you could reuse your UI code across web, mobile, and desktop. I don't have the cycles to take that on in the near future though. My initial look at the Android WebView suggested that it didn't export the right interface needed to support something like Elemental, so doing the port would involve creating a custom WebView that can be embedded in apps, which is a lot of work.
Just thought some of you might be interested,
Ming
p.s. As a demonstration of it working, I took a game I wrote for a game jam in Elemental and adapted it to run in ElementalFx. Here's a screenshot of it running in Linux:
http://www.jinq.org/elementalfx-screen.png
The game uses 2 Canvas elements, several DIVs that are updated using innerHTML, JSON processing, a timer, and keyboard events.
In order to get things to work, I had to do these things:
1) Using XMLHttpRequest would cause the JVM to crash (I think it's a bug in JavaFx). Since this was now a desktop Java program, it was fairly easy just to replace that code with something that used real Java instead
2) All my sound effects using HTML5 Audio caused IllegalThreadStateException errors. I imagine JavaFx probably doesn't properly support audio in its WebView or something.
3) The original code used Browser.getWindow() and Browser.getDocument() a lot to get at the window and document objects. This doesn't make sense in ElementalFx because the Java code does not run in the context of a web page. In fact, a desktop Java application can have multiple WebViews with multiple windows and documents. I had to change my code to pass in the window/document to use when doing UI stuff
4) I had to remove the script tag that would run the compiled GWT JS code from the HTML. Instead, my Java code would just run itself after it had loaded the HTML.
5) I needed to write my own bootstrap code to start the application. Here is what it looks like:
@GwtIncompatible
public class FxMain extends Application
{
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
// Create the WebView
VBox region = new VBox();
WebView webView = new WebView();
final WebEngine engine = webView.getEngine();
region.getChildren().add(webView);
Scene scene = new Scene(region);
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) {
Module.win = (Window)GwtFxBridge.wrapJs(engine.executeScript("window"));
Module.doc = Module.win.getDocument();
new Module().onModuleLoad();
}
}
});
// Load the main Gwt application web page
engine.load(new File("index.html").toURI().toURL().toExternalForm());
}
}
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.
No comments:
Post a Comment