Tuesday, September 27, 2011

GroovyFX vs ScalaFX

Oh, it's on now.

My good friend and new alternative language nemesis, Stephen Chin, published a blog post last night introducing a project he's been working on called ScalaFX. A nice, easy way to write JavaFX 2.0 code in Scala.

I, of course, have been working with Jim Clarke on his GroovyFX project.  Stephen points out that his ScalaFX library creates code that is more concise and more readable than the Java equivalent.  That is undeniably true, but picking on poor Java because it is succinctness-challenged is too easy.  How about picking on a language that can defend itself with respect to conciseness, programmer productivity, and modern language features?

I give you the GroovyFX version of the Colorful Circles demo:
GroovyFX.start { primaryStage ->
  def circles
  def sg = new SceneGraphBuilder(primaryStage)

  sg.stage(title: 'GroovyFX ColorfulCircles', resizable: false, visible: true) {
    scene(width: 800, height: 600, fill: black) {
      group {
        circles = group {
          30.times {
            circle(radius: 200, fill: rgb(255, 255, 255, 0.05), 
                   stroke: rgb(255, 255, 255, 0.16),
                   strokeWidth: 4, strokeType: 'outside')
          }
          effect boxBlur(width: 10, height: 10, iterations: 3)
        }
      }
      rectangle(width: 800, height: 600, blendMode: 'overlay') {
        def stops = ['#f8bd55', '#c0fe56', '#5dfbc1', '#64c2f8', 
                     '#be4af7', '#ed5fc2', '#ef504c', '#f2660f']
        fill linearGradient(start: [0f, 1f], end: [1f, 0f], stops: stops)
      }
    }

    parallelTransition(cycleCount: indefinite, autoReverse: true) {
      def random = new Random()
      circles.children.each { circle ->
        translateTransition(40.s, node: circle, 
                            fromX: random.nextInt(800), fromY: random.nextInt(600),
                            toX: random.nextInt(800), toY: random.nextInt(600))
      }
    }.play()
  }
}
Update: Stephen updated his version to make it shorter!  He even stole GroovyFX's new gradient stop syntax to do it.  That was low.  :-)  I have no choice but to respond by shortening the GroovyFX version even further.  (Thanks to Jim Clarke for the idea of using the parallelTransition in place of the timeline).

Not only is the GroovyFX version even shorter than the ScalaFX version, it is, in my humble opinion, much more readable.  By my reckoning that's GroovyFX 1, ScalaFX 0.

What will the final score be?  To find out, join Stephen and I for our JavaOne session "JavaFX 2.0 with Alternative Languages" on Wednesday, October 5 at 4:30 PM in the Hotel Nikko.  It should be a great time as Stephen and I battle it out to convince you that our language and library is the best choice for JavaFX development.

Who will be the winner?  Why, developers of course.  No matter which of the two languages you choose, you will have a great JavaFX 2.0 library to go with it!

And here is the psychedelic output of the program, which of course matches Stephen's ScalaFX version and the original Java version.
Happy JavaFX-ing and stay Groovy!

Sunday, August 21, 2011

JavaFX on Griffon: Events and Binding

I have just uploaded a second screencast (embedded below) in the "JavaFX on Griffon" series. If you missed the first screencast, you can find it here. This screencast concludes the basic introduction I wanted to provide to writing JavaFX applications with Griffon.

In my previous article, I was remiss in forgetting to thank Andres Almiray, the leader of the Giffon project, for all his help in creating these plugins. I am thoroughly convinced that Andres spent about twice as much time answering all of my silly questions as it would have taken him to just write the plugins himself.

So Mr. Almiray, thank you for all the time you spent teaching me about Griffon plugins and the Griffon build system. You, sir, are a scholar and a gentleman!

Saturday, August 20, 2011

Writing JavaFX Applications with Griffon

I'm really happy to share one of the side projects I've been working on for a while now. Those of you who follow me on Twitter will have seen images of this in the past, but now I'm finally able to open up the sandbox and let others play.

I have posted a screencast on YouTube that shows how to get started with Griffon, GroovyFX, and JavaFX. I hope you will agree that it is a really fun and easy combination for writing Java desktop clients. If you are ready to try it out for yourself, the archetype I used in the video can be downloaded from my GitHub page. The screencast is embedded below, broken into two parts since it is a little on the lengthy side.

In other GroovyFX news, Jim Clarke and I will be doing an in-depth technical session on GroovyFX at JavaOne. The session will be the last session of the day on Thursday. It's titled "GroovyFX: JavaFX is my bag, baby, yeah!" This session will also touch on using GroovyFX with Griffon so I hope you can squeeze it into your busy JavaOne schedule!

Jim and I have also been busy adding more features to GroovyFX. I hope to post a new article soon describing new features like IDEA code completion and improved event declarations. There is so much Groovy JavaFX stuff to talk about!

Update: The next screencast in this series is now available. This screencast goes into more binding functionality and discusses event handling in JavaFX Griffon applications.

Monday, August 8, 2011

Introducing GroovyFX: It's About Time

It's About Time!
GroovyFX is an open source project whose goal is to combine the conciseness of Groovy with the power of JavaFX 2.0.  Jim Clarke, the originator of the project, and I have been working hard to make GroovyFX the most advanced library for writing JavaFX code with alternative JVM languages.  As you are about to see, it is more than a mere DSL that provides some syntactic sugar for JavaFX code. We have decided that it is past time to share our progress with the wider JavaFX community; this article is long overdue (right, Jonathan?).
This is the first of many articles I'll be writing about GroovyFX.  If you want to stay up to date with the GroovyFX project you can follow this blog or follow me on Twitter.

How to Play

The GroovyFX website has all the information you need to get started but I will summarize it here:
  1. Download and install the latest version of JavaFX and set a JAVAFX_HOME environment variable that points to the root directory of your JavaFX installation.
  2. Download the latest version of Gradle (1.0 milestone-4 or better), unzip it, and add it to your path.  Gradle provides the easiest and quickest way to build and run the demos.
  3. Check out the GroovyFX source from http://svn.codehaus.org/gmod/groovyfx/trunk/.
Now you are ready to build and run the demos.  You can build the project by changing to the GroovyFX root directory and typing
gradle build
Once the project builds successfully, you can start running one of the many demos included with the project by typing a command like
gradle AnalogClockDemo
That will start the application pictured at the top of this article.  You can see a complete list of available demos by typing
gradle tasks
and examining the "Demo" task group.

Setting the Table

Setting up and populating a TableView is something that is not only common but can take a surprising amount of code in Java.  So we will start with the GroovyFX TableViewDemo shown in the image below.
Any of these guys would be happy to answer your JavaFX questions.
The code for this example, in its entirety, is as follows.
@Canonical
class Person {
    @FXBindable String firstName
    @FXBindable String lastName
    @FXBindable String city
    @FXBindable String state
}

def data = [
    new Person('Jim', 'Clarke', 'Orlando', 'FL'),
    new Person('Jim', 'Connors', 'Long Island', 'NY'),
    new Person('Eric', 'Bruno', 'Long Island', 'NY'),
    new Person('Dean', 'Iverson', 'Fort Collins', 'CO'),
    new Person('Jim', 'Weaver', 'Marion', 'IN'),
    new Person('Stephen', 'Chin', 'Belmont', 'CA'),
    new Person('Weiqi', 'Gao', 'Ballwin', 'MO'),
]

GroovyFX.start {
    def sg = new SceneGraphBuilder()

    sg.stage(title: "GroovyFX TableView Demo", visible: true) {
         scene(fill: groovyblue, width: 650, height:450) {
             stackPane(padding: 20) {
                 tableView(items: data) {
                     tableColumn(text: "First Name", property: 'firstName')
                     tableColumn(text: "Last Name", property: 'lastName')
                     tableColumn(text: "City", property: 'city')
                     tableColumn(text: "State", property: 'state')
                 }
             }
         }
    }
}
Compare that with other "simple" JavaFX TableView examples, and it's easy to see that GroovyFX can save you both time and code.  There are three main sections to this code: our Person class, the declaration of the data List, and the scene graph itself.  The Person class contains the four properties that will be displayed in the TableView.  It is annotated with the standard Groovy @Canonical AST transformation that adds a tuple constructor.  This allows us to construct a Person instance using new Person('Jim', 'Clarke', 'Orlando', 'FL') in our data List.  @Canonical also adds appropriate overrides for the hashCode, equals, and toString methods.  These are all generated for us at compile time; this is the power of Groovy's AST transformations.
The @FXBindable annotation is a custom AST transform that Jim and I have added to GroovyFX.  When you use it to annotate a standard Groovy property, the property will be transformed into a JavaFX property. Its job is to generate all of the boilerplate associated with declaring JavaFX properties.  For each annotated property it will generate three methods:
public void setFirstName(String value)
public String getFirstName()
public final StringProperty getFirstNameProperty()
This setup allows you to access your JavaFX properties just as you would any standard Groovy property.
def name = person.firstName
person.firstName = 'James'
person.firstNameProperty.bind( /* some binding expression - more on that below */ )
Considering all of the boilerplate involved when creating JavaFX properties in Java, this will be a real productivity win for GroovyFX users.  One last thing to note is that you can also use @FXBindable to annotate a class.  The following code is equivalent to the class declaration above.  The FXBindable transform will iterate all of the class properties and transform each one into a JavaFX property.
@Canonical
@FXBindable
class Person {
    String firstName
    String lastName
    String city
    String state
}
We'll now turn our attention to the GroovyFX scene graph declaration.  All scene graphs in GroovyFX begin with the GroovyFX.start method, which takes a closure as its argument.  The first few lines of the closure are almost always the same: instantiate a SceneGraphBuilder and use it to declare your stage and scene.  The root of our scene graph is a StackPane layout container.  This is a nice container to use as a root node since it will be resized as the scene size changes and will also grow and shrink its child nodes if they are resizable (like TableView is).  After the stackPane we add a tableView with its data items and its four tableColumn declarations.  It is a very concise way to declare your scene graph.
You have probably noticed that the naming convention for GroovyFX scene graph nodes matches the JavaFX class names with the first letter converted to lower case.  This is a convention we follow for all of our nodes.  Another convention is that you specify properties for a node using Groovy's propertyName: value Map syntax.  There are a couple of other fun things to note about the scene graph code.
There is a new color "groovyblue" that is added to JavaFX's Color class at runtime.  We use it as the background of all of our demos, but you are free to use it in your code as well (it's the color of the star in the Groovy logo).  Any JavaFX color constant can be declared using just its lowercase name such as red, blue, or burlywood.  There are also shortcuts for specifying the padding of a node.  Above we have just used a single integer value which will be used as the padding on all sides.  You can also specify a list with 1, 2, 3, or 4 integers that will be assigned just as they are in CSS.  See the GroovyFX PaddingDemo for the options.  These are just a few of the many short cuts and productivity boosters we've incorporated into GroovyFX.

A Time for Binding

GroovyFX also has a nice surprise for those of you that miss the simple but powerful binding syntax in JavaFX Script.  When JavaFX was ported to Java, the team at Oracle came up with a nice fluent API for specifying binding.  Here is an example of this API:
        hourAngleProperty().bind(Bindings.add(hoursProperty().multiply(30.0),
                                              minutesProperty().multiply(0.5)));
        minuteAngleProperty().bind(minutesProperty().multiply(6.0));
        secondAngleProperty().bind(secondsProperty().multiply(6.0));
Not bad, but all of the method calls do tend to obfuscate the rather simple binding expression. Wouldn't it be great if you could write these kinds of binding expressions in a more natural way? Say, something like this?
        hourAngleProperty.bind((hoursProperty * 30.0) + (minutesProperty * 0.5))
        minuteAngleProperty.bind(minutesProperty * 6.0)
        secondAngleProperty.bind(secondsProperty * 6.0)
This is exactly what Jim has just added to GroovyFX. This functionality uses Groovy's operator overriding ability combined with its ability to add methods to existing classes. The result is all-natural binding goodness with only the essence of the binding and little ceremony. In fact the above expressions are part of the AnalogClockDemo pictured at the start of this article. The code for the demo's Time class is below.
@FXBindable
class Time {
    Integer hours
    Integer minutes
    Integer seconds

    Double hourAngle
    Double minuteAngle
    Double secondAngle

    public Time() {
        // bind the angle properties to the clock time
        hourAngleProperty.bind((hoursProperty * 30.0) + (minutesProperty * 0.5))
        minuteAngleProperty.bind(minutesProperty * 6.0)
        secondAngleProperty.bind(secondsProperty * 6.0)

        // Set the initial clock time
        def calendar = Calendar.instance
        hours = calendar.get(Calendar.HOUR)
        minutes = calendar.get(Calendar.MINUTE)
        seconds = calendar.get(Calendar.SECOND)
    }

    /**
     * Add a second to the time
     */
    public void addOneSecond() {
        seconds = (seconds + 1) % 60
        if (seconds == 0) {
            minutes = (minutes + 1)  % 60
            if (minutes == 0) {
                hours = (hours + 1) % 12
            }
        }
    }
}
Note the use of @FXBindable for easy property declarations, the simple expressive binding, and the natural way of accessing the properties. You use the property name by itself for getting and setting values. You use the property name followed by "Property" to access the underlying JavaFX property class when you need to add listeners or bindings. For completeness, the scene graph code used to draw the clock face is shown below.
time = new Time()

GroovyFX.start {
    def width = 240.0
    def height = 240.0
    def radius = width / 3.0
    def centerX = width / 2.0
    def centerY = height / 2.0

    def sg = new SceneGraphBuilder()

    sg.stage(title: "GroovyFX Clock Demo", width: 245, height: 265, visible: true, resizable: false) {
       def hourDots = []
        for (i in 0..11) {
            def y = -Math.cos(Math.PI / 6.0 * i) * radius
            def x = ((i > 5) ? -1 : 1) * Math.sqrt(radius * radius - y * y)
            def r = i % 3 ? 2.0 : 4.0

            hourDots << circle(fill: black, layoutX: x, layoutY: y, radius: r)
        }

        scene(fill: groovyblue) {
            group(layoutX: centerX, layoutY: centerY) {
                // outer rim
                circle(radius: radius + 20) {
                    fill(radialGradient(radius: 1.0, center: [0.0, 0.0], focusDistance: 0.5, focusAngle: 0,
                                        stops: [[0.9, silver], [1.0, black]]))
                }
                // clock face
                circle(radius: radius + 10, stroke: black) {
                    fill(radialGradient(radius: 1.0, center: [0.0, 0.0], focusDistance: 4.0, focusAngle: 90,
                                        stops: [[0.0, white], [1.0, cadetblue]]))
                }
                // dots around the clock for the hours
                nodes(hourDots)
                // center
                circle(radius: 5, fill: black)
                // hour hand
                path(fill: black) {
                    rotate(angle: bind(time.hourAngleProperty))
                    moveTo(x: 4, y: -4)
                    arcTo(radiusX: -1, radiusY: -1, x: -4, y: -4)
                    lineTo(x: 0, y: -radius / 4 * 3)
                }
                // minute hand
                path(fill: black) {
                    rotate(angle: bind(time.minuteAngleProperty))
                    moveTo(x: 4, y: -4)
                    arcTo(radiusX: -1, radiusY: -1, x: -4, y: -4)
                    lineTo(x: 0, y: -radius)
                }
                // second hand
                line(endY: -radius - 3, strokeWidth: 2, stroke: red) {
                    rotate(angle: bind(time.secondAngleProperty))
                }
            }
        }
    }

    sequentialTransition(cycleCount: "indefinite") {
        pauseTransition(1.s, onFinished: {time.addOneSecond()})
    }.playFromStart()
}
Once again, this is the AnalogClockDemo located in src/demo in the GroovyFX project. These binding expressions should still be considered experimental, but you can see them in action If you run the demo with Gradle.  It should appear as shown here.
A Groovy Clock
The GroovyFX AnalogClockDemo was inspired by one of the JRuby examples on javafx.com

Conclusion

GroovyFX is a young project and it is advancing rapidly.  We are only just now getting close to releasing our first version, but it already has a lot of very useful functionality.  It has support for virtually every JavaFX shape, control, and chart.  It even provides great integration with the brand new FXML functionality (see the FXMLDemo).
There is quite a lot of documentation and many examples on the project's web site.  We invite you to get involved: download and play with the code then let us know what you think.  You can file JIRA issues for things that don't work or features you would like to see.  Our goal with GroovyFX is to make it fun and easy to write client Java applications.  So join in!

Thursday, February 24, 2011

Xoom, Xoom, Xoom

Android really shines on a tablet. After playing with my new Xoom tablet and Android Honeycomb for a few hours now, I get the sense that Android was really meant for the larger screen. The notifications, the multitasking, the widgets; they all combine to make an incredibly powerful and rich tablet OS. Having a home screen with your calendar and email at your finger tips is incredibly more useful than page after page of icon matrixes.

X1

And switching between applications is much nicer on Honeycomb.

X3

To think that all this time Android has really been a tablet OS crammed into a smart phone just bursting to get free. By the same token, I can see now just how lame iOS is as a nice, but limited phone OS when running scaled up to a larger screen on the iPad.

And the Xoom hardware is very impressive. It is slightly taller but significantly narrower than the iPad and has much smaller bevels around the screen as well. Although this does make it harder to carry the Xoom without leaving finger tip smudges. The dual core Tegra2 processor makes everything feel pretty snappy as well.

The Xoom has a higher resolution packed into a slightly smaller screen which makes for higher DPI. Games like Angry Birds and eBooks look incredible on the Xoom's higher density screen.

X2

X4

Notice how the status bar at the bottom of the screen goes into a minimal mode when reading a book? The same thing happens when viewing a movie in order to minimize the distraction of that bottom strip. These are really nice touches that I would usually expect from Apple rather than Google.

Of course, I'm talking here in terms of environment only. With a few exceptions, as far as applications go, iPad wins hands down. No question. No contest.

As we have seen in the past, a superior OS usually doesn't win against an OS with more apps so this should be an interesting fight.

Saturday, February 12, 2011

A Sweet Combination: JavaFX 2.0 EA, Griffon, and Groovy

Working with the recent early access release of JavaFX 2.0 has been interesting. On one hand, the scene graph API you know and love translates surprisingly well to Java. The team at Oracle has done a nice job of keeping the new API simple to use. The animation support still makes it easy to do the simple things, and possible to do the sophisticated. The memory overhead is down while performance is up. All good.

Screen shot 2011 02 12 at 6 30 30 PM

There are definitely places where JavaFX Script (now Visage) is missed. Binding, object literals, functional programming, and easy internationalization were all particularly useful language features. To make up for this loss, you can now use all of the old, familiar Java tools to write JavaFX including all of the awesome testing libraries and IDEs that Java is known for. In my opinion, this more than makes up for the loss of the awesomeness that was the JavaFX Script syntactic sugar.

You can always add some of that sweetness back in by using one of the many great JVM languages at our disposal. My weapon of choice happens to be Groovy and I can tell you that Groovy and JavaFX are a potent combination. Apparently Groovy is a terrific language for expressing application frameworks as it boasts two of the best in the Java world: Grails for web applications and Griffon for desktop applications.

Yesterday I decided to take a quick look at what would be involved in creating a JavaFX application plugin for Griffon. I was pleasantly surprised at how easy it was. Griffon's architecture is clean and the documentation was great. It took me a lot longer than it should have just because I was enjoying looking around under Griffon's hood.

A video showing the results of my little experiment is embedded below.

I plan to continue developing this plugin with the ultimate goal being first-class Griffon support for JavaFX applications when JavaFX 2.0 ships later this fall.

The JavaFX team at Oracle has a lot of work ahead of them. There are some missing features and some rough edges, but this Early Access release is a great start. I can't wait to see the finished product.