The more I learn about Groovy, the less I understand why the world needs JavaFX.
Back around 2002 or 2003 I studied Java, but it seemed heavy to me, verbose, and slow to program with. My attitude has mostly been, life is short, so I’d rather program in light-weight, high level programming languages. I want to be able to go as fast possible. For the last few years I’ve mostly been doing web development, mostly with PHP, though I did one project with Ruby On Rails.
But then the iPhone came out. And then the iPhone app store. So I became intrigued with the idea of programming for cell phones. But I didn’t want to especially learn Objective C just to be able to work with the iPhone. I was relieved to hear that Google was coming out with its Android operating system for cell phones, and programming for Android would be done in Java. That opened the door to using the light-weight languages (derived from Java) for cell phone programming. Very cool.
So I began to delve into the world of Java, something I hadn’t done much in the last few years. At first I was attracted to JavaFX, which Sun was hyping. But then I began to wonder why JavaFX was suffering such a slow uptake, and why programmers seemed less thrilled about it than I.
Now that I’ve started to study Groovy, I realize why JavaFX has so little traction: it isn’t needed. Much of what I liked about JavaFX is already present in Groovy. Lexecorp expresses some of the same hesitation that I feel:
I wonder whether I will be able to like JavaFX! Have I been spoilt already by Groovy (it does, virtually, the same thing)? Maybe, but I managed to accept the long winded Java language well after Perl’s expressive power had spoilt me. I learned to love Java for its platforms and immense libraries, so what can I love about JavaFX?
Consider this tutorial, which showed how to draw a coffee cup, and which showed off the clean, declarative style of JavaFX:
def plateGroup = Group {
translateX: 250
translateY: 300
content: [
// The gray ellipse under the plate
Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},
// The thin "lip" of the plate (provides a sense of 3D)
Ellipse{centerX:0 centerY:3 radiusX:170 radiusY:50 fill:Color.LAVENDER},
// The large plate ellipse
Ellipse{centerX:0 centerY:0 radiusX:170 radiusY:50
fill:RadialGradient{
centerX:0.5 centerY:0.75
stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
Stop {offset: 0.5 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.DARKGRAY}]
}
},
// Recessed plate center
Ellipse{
centerX:0 centerY:5 radiusX:90 radiusY:22
fill:RadialGradient{
centerX:0.5 centerY:0.75
stops:[Stop {offset: 0.0 color: Color.BLACK},
Stop {offset: 0.4 color: Color.LIGHTGRAY},
Stop {offset: 1.0 color: Color.GHOSTWHITE}]
}
}
]
}
def cupGroup = Group {
translateX: 152
translateY: 20
scaleX: 3.0
scaleY: 4.0
content: [
// Cup body
Circle {centerX: 100 centerY: 100 radius: 50
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.65, proportional:true
stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
},
// Cut top of cup
Rectangle{stroke: BGCOLOR fill: BGCOLOR
x:25 y:50 width:150 height:50},
// Outer rim
Ellipse{fill: Color.WHITE centerX:100 centerY:100 radiusX:50 radiusY:8},
// Inner rim
Ellipse{centerX:100 centerY:100 radiusX:48 radiusY:7 //inner rim
fill: RadialGradient {
centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.4, proportional:true
stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
Stop {offset: 1.0 color: Color.SILVER}]
}
},
// Create “coffee in cup” by intersecting coffee ellipse with inner rim ellipse
ShapeIntersect {
fill:Color.SADDLEBROWN
//Inner Rim
a: Ellipse{centerX:100 centerY:100 radiusX:48 radiusY:7} // inner rim dimensions
//Coffee
b: Ellipse{centerX:100 centerY:102 radiusX:46 radiusY:6} // coffee dimensions
}
]
}
Stage {
title: “Coffee Cup”
width: 500
height: 500
visible: true
scene: Scene {
fill: BGCOLOR
content: [plateGroup,cupGroup]
}
}
That’s impressive! Look how clean the code is! So much simpler than Swing! But then Andres Almiray turned around and demonstrated how to draw a coffee cup with Groovy:
group( id: ‘plategroup’, bc: ‘none’ ) {
// gray ellipse under the plate
ellipse( cx: 0, cy: 10, rx: 160, ry: 50, f: color(’darkGray’).brighter() )
// thin ‘lip’ of the plate (provides a sense of 3D)
ellipse( cx: 0, cy: 3, rx: 170, ry: 50, f: ‘lavender’ )
// large plate
ellipse( cx: 0, cy: 0, rx: 170, ry: 50 ) {
radialGradient( cx: 1, cy: 1, fy: 100, r: 270 ) {
stop( c: ‘whiteSmoke’, s: 0 )
stop( c: ‘lightGray’, s: 0.5 )
stop( c: ‘darkGray’, s: 1 )
}
}
// recessed plate center
ellipse( cx: 0, cy: 5, rx: 90, ry: 22 ) {
radialGradient( cx: 1, cy: 1, fy: 20, r: 180 ) {
stop( c: ‘black’, s: 0 )
stop( c: ‘lightGray’, s: 0.4 )
stop( c: color(’white’).darker(), s: 1 )
}
}
transformations {
translate( x: 250, y: 300 )
}
}
group( id: ‘cupgroup’, bc: ‘none’ ) {
subtract( id: ‘cup’, asShape: yes ) {
circle( cx: 100, cy: 100, r: 50 )
rect( x: 25, y:50, w: 150, h: 50 )
}
draw( cup, keepTrans: yes ) {
radialGradient( cx: 0.4, cy: 0, r: 100 ) {
stop( c: ‘whiteSmoke’, s: 0 )
stop( c: color(’whiteSmoke’).darker(), s: 1 )
}
}
// outer rim
ellipse( cx: 100, cy: 100, rx: 50, ry: 8, f: ‘white’ )
// inner rim
ellipse( cx: 100, cy: 100, rx: 48, ry: 7, id: ‘innerRim’ ) {
linearGradient( y2: 1 ){
stop( c: ‘whiteSmoke’, s: 0 )
stop( c: color(’whiteSmoke’).darker(), s: 1 )
}
}
intersect( f: color(’darkOrange’).darker().darker() ) {
shape( innerRim )
ellipse( cx: 100, cy: 102, rx: 46, ry: 6 )
}
transformations {
scale( x: 3, y: 4 )
translate( x: -16, y: -70 )
}
}
transformations {
translate( x: -50, y: -50 )
}
Damn. Doesn’t that look similar? There are some syntax differences, but both use a declarative style, and both require less work than using Swing.
Groovy offers some solid MVC frameworks. For web development, there is Grails, which is an imitation of Ruby On Rails. For the desktop, there is Griffon. Consider this post on Transentia:
Although it is early days yet for the project, Griffon aims to bring the same “Configuration by Convention” goodness to desktop GUI development that Grails has brought to Web development. In fact, Griffon ‘borrows’ heavily from Grails: many of the build scripts, etc. are straight carry-overs, meaning that anybody familiar with Grails can get started easily.
This is all that is needed to get started:
griffon create-app GT
cd GT
griffon run-app
These three shell commands give a simple immediately runnable application.
As with Grails, Griffon imposes a clear MVC structure for the code and also creates a standard project filesystem heirarchy.
I haven’t yet worked with Griffon, but the setup described on Transentia looks very clean. Certainly, everything I’ve learned so far about Groovy has left me impressed. And since Groovy integrates with regular Java far more smoothly than JavaFX, why do we need JavaFX? Can anyone name one thing that JavaFX gives us that Groovy hasn’t already given us?