Let's start with some screenshots, both jsilhouette-geom and jsilhouette-scene use the default Swing settings (which means ugly Metal L&F), from an outsider's point of view there is no difference whatsoever on the finished app so the following screenshot is the same for both demo apps

The real difference strives in how the graphics are attached to the canvas panel. Regular Swing/Java2D applications that rely on custom painting usually create a subclass of JComponent or JPanel and plug-in the custom painting code. This is exactly what ShapesDemoJava.java does, it defines a CanvasPanel that requires and instance of PaintOperation to actually draw anything as its contents. Each button wires up a listener that creates an anonymous inner implementation of PaintOperation upon activation. In other words quite the regular plumbing we are used to in Swing/Java2D.
Now on the SceneGraph version (ShapesDemoSG.java) things look a bit brighter. SceneGraph relies on SGNode to do its work, happily for us it also includes a handy JSGPanel that knows how to render SGNodes, in other words, you do not need to create a CanvasPanel nor a PaintOperation, just make sure to build a proper graph of SGNodes and set it as the scene property of a JSGPanel instance. Notice that in both demo apps the main frame and the whole ui are built in the EDT (thanks to wrapping the building code with SwingUtilities.invokeLater), this is important to remark as the next demo relieves you of that burden: ShapesDemoFX.fx. The JavaFx Script libraries also provide a canvas, aptly named Canvas, where you can set a sequence of Node instances as its content, which will be used to draw anything into it. Declarative programming helps a bit in reducing the visual clutter (no setter/getters) but in no way reduces the amount of lines of code (more on that later). So how does it look?

If you run the demos with j6u10 installed you'll get a nicer L&F (Nimbus), the frame will be centered on the screen by default too. Notice that the green color differs form one screenshot to the other, I don't know why but java.awt.Color.GREEN is lighter that javafx.scene.paint.Color.GREEN.
Time for some stats. I have no recorded data on the time spent in each demo app, what it is true is that I started with the geom demo and finished with the jfx one. Once the first layout and behavior was set, the other two demo apps were quicker to implement (already had the recipe), it was just a matter of using the native facilities of each version. Lines of Code is also another metric people like to use, along with the size of the packaged product, here goes
geom | scene | jfx | |
---|---|---|---|
LoC | 337 | 463 | 546 |
Tokens | 1395 | 1713 | 2347 |
Size (compiled) | 17854 (jdk4) | 8659 (jdk5) | 128553 (jdk5) |
# source classes | 10 | 9 | 9 |
# compiled classes | 10 | 9 | 87 |
Looks like the geom version is the winner in terms of LoC & Tokens and the jfx is a considerable percentage behind, but there is some explaining involved. Even though the geom version creates its own 'rendering setup' it also relies on specialized constructors available in each shape, so creating a shape with a mix of default values and new ones is just a matter of invoking a one-liner. The scene version requires less plumbing on the 'rendering setup' (as explained before) but its shapes do not provide specialized constructors, which means that if those constructors were available this version should be the shortest one in terms of LoC), thus requiring helper methods to build each shape. Lastly the jfx version does not require any specialized 'rendering setup' (it is already there), so it is the declarative way of instantiating an object the one responsible for the amount of LoC and Tokens. Notice that many properties are clumped in the same line (contrary to many jfx demos out there) effectively rendering the LoC argument quite pointless, that is why I decided to also show the token count.
So is declarative programming bad for your productivity? certainly not. What we 'lost' in source file size we gained in comprehensibility and readability. The jfx version explicitly states which property has what value, in the geom/scene versions you will have to search the code to know the correct order and types of the parameters (this is where tool support kicks in, right?).
Regarding file size, the geom shapes provide accessors for each property and the actual implementation of each shape, the scene shapes provide only accessors for each property and rely on their correspondent shape (of the geom package) making them smaller. The jfx version is bigger given that
- Each jfx class is compiled to a class and and interface
- Each trigger is compiled to its own class
What about the Groovy version? I'm a bit embarrassed as it is not finished yet but here is a glimpse of how it may look
Other than requiring an explicit GraphicsBuilder instance (that will probably change in the future *wink*) this version as a bit shorter on the build code as the native Map syntax is really helpful here, but I believe the token count may be a bit bigger than the jfx version given that commas are required to separate each property when declaring the shapes.