Archive for July, 2016

Java Desktop apps to JavaScript

July 13, 2016

My ideal dev platform would be a Java environment that lets me write fully functional, rich native desktop apps that I can also build/run natively for the browser, even if in limited fashion (but without plugin).

So two years ago I started writing my own UI kit, Snapkit, that has the modern features of JavaFX, but adheres more to Java conventions like Swing. My big cheat (and epiphany) was to implement the bottom most system interaction (graphics, input events, clipboard) as an adapter. So Snapkit can easily run on top of either Swing or JavaFX, in any Swing Component or JavaFX Node. It really only relies on a Painter, supplied through the adapter (Graphics2D or JFX Canvas). All of the graphics primitives (Shape, Rect, Path, Color, Font, Transform, etc.) and all of the components (Button, Slider, TextField, List/Table/TreeView, etc.) are implemented in Snapkit.

So since this adapter model eliminates most system dependent code, I was able to reasonably embark on an adapter to run a Snapkit desktop app in the browser. This is when I found TeaVM – a remarkable system that compiles Java bytecode to JavaScript that supports a good subset of the standard Java class library. It compiles only referenced code, so the resulting JavaScript is amazingly small.

So far my two test cases are a (1) SimpleTest that has button, slider, label, images, vector graphics, text and animation and (2) Greenfoot Asteroids, an asteroids implementation written in Greenfoot (with a simple glue library I wrote to emulate Greenfoot in Snapkit).

The interesting thing about these two apps is that I can change one line of code to run them as native desktop applications, with access to full desktop features and performance (and a 40mb download). Or I can deploy in a much more accessible fashion to the browser, where there is no download step to scare potential users away (but with some missing features). Eventually, I could add a third option where the app runs client/server: still no download, and more functionality, but slower runtime performance (due to networked graphics). Those are options I can live with!

I still need time to properly integrate this into SnapCode, and SnapCode itself still needs some work. But here are the two apps:


I’d love to hear any feedback people have. I’ve been aching for a solution along these lines for years – I wish Oracle would do this with JavaFX and/or Swing. With WebAssembly I hope we’ll see more of this. Feel free to comment or send me a note at jeff at reportmill.