FX Experience Has Gone Read-Only

I've been maintaining FX Experience for a really long time now, and I love hearing from people who enjoy my weekly links roundup. One thing I've noticed recently is that maintaining two sites (FX Experience and JonathanGiles.net) takes more time than ideal, and splits the audience up. Therefore, FX Experience will become read-only for new blog posts, but weekly posts will continue to be published on JonathanGiles.net. If you follow @FXExperience on Twitter, I suggest you also follow @JonathanGiles. This is not the end - just a consolidation of my online presence to make my life a little easier!

tl;dr: Follow me on Twitter and check for the latest news on JonathanGiles.net.

It was my pleasure to recently come across the GroovyFX project, which works to make building JavaFX 2.0 user interfaces easier and more powerful from the Groovy language. I decided to reach out to the two main developers to see if they would kindly answer some questions relating to this project. Fortunately they agreed, and so here today we have the first interview on FX Experience. Enjoy!

Please introduce yourselves
Jim Clarke: I have been working with JavaFX for several years and am co-author of JavaFX-Developing Rich Internet Applications.
Dean Iverson: I work at the Virginia Tech Transportation Institute where I work with various rich client technologies.  I was an early adopter of JavaFX and a co-author of Pro JavaFX Platform.

My understanding is that GroovyFX is an API that makes working with JavaFX in Groovy much simpler (and more natural to those well-versed in Groovy). Before we get on to what exactly GroovyFX is, I’d love to hear your opinion on Groovy itself: is it a good language for people writing user interfaces? Why would someone prefer to write a user interface in Groovy compared to other JVM languages?
What’s nice about Groovy is that it is a language built from the ground up around Java and maintains a close affinity to the Java platform. It supports closures, dynamic typing, and easily supports Domain Specific Languages, commonly called DSL’s.  Groovy has a lot of nice developer productivity features; you will find yourself writing more concise, expressive code.  And with awesome tools like Spock, Groovy is a great language for unit testing.

JavaFX 2.0 is already in Java, which means it can be used already by Groovy. Why is there a need for GroovyFX? What benefits are there to using GroovyFX over just writing JavaFX 2.0 user interfaces in Groovy?
Groovy has supported Tree Structured Languages via the Builder pattern. There are already implementations to support XML, ANT and Swing. The SwingBuilder is commonly used to create Swing-based UI applications in Groovy.

GroovyFX is focused on leveraging the Builder pattern for JavaFX applications, but more than that, we want to take some of the DSL capabilities that Groovy provides and make the Groovy based JavaFX code easier to write and, just as important, easier to read. For example, JavaFX colors can be set using pseudo variables, like red or blue. SwingBuilder has a binding feature that binds a Groovy variable to a Swing JavaBean property. We have taken this concept and also included a binding feature in GroovyFX so you can do things like:

tf = textBox(text: 'Change Me!')
label(text: bind{ tf.text })

So, if the user changes the value in the JavaFX TextBox, it automatically updates the JavaFX Label’s text.

We have also provided a DSL for JavaFX Timelines to make timeline development easier.

You’re both working on GroovyFX – what exactly is it?
The primary goal of GroovyFX is to make JavaFX development simpler and more concise than what it takes in Java. This is done via numerous built-in features that Groovy provides, including the Tree Structured Language supported through Groovy’s Builder framework that makes declaring a JavaFX SceneGraph more closely resemble the actual SceneGraph itself. This is done through GroovyFX’s SceneGraphBuilder object, that supports all the Controls, Shapes, Effects, and other JavaFX objects, as well as support for using Groovy closures for event handling.

For example, Groovy Closures can be used to process mouse and key events. Attributes for each JavaFX object can be set using Groovy’s builtin mechanism. The following simple example demonstrates the Tree Structure of JavaFX Stage=>Scene=>Group=>rectangle. The rectangle has a mouse pressed event handler and a blend effect.

GroovyFX.start { primaryStage ->
    def sg = new SceneGraphBuilder(primaryStage);
    
    sg.stage(title: "Blend Effect Demo", width: 420, height: 420, visible: true ) {
        scene(fill: hsb(128, 1.0, 1.0, 0.5) ) {
            rectangle(width: 400, height: 400) {
                onMousePressed (onEvent: {e -> println "mouse press @" + e.x + "," + e.y })
                blend(mode: "multiply") {
                    topInput() {
                        colorInput(paint: blue, x: 50, y: 50, width: 200, height: 200)
                    }
                    bottomInput() {
                        colorInput(paint: red, x: 150, y: 150, width: 200, height: 200)
                    }
                }
            }
        }
    }
}

Blend effects

We have also created a Timeline DSL to support the JavaFX Timeline class for animations. The following code demonstrates the DSL where the keyword “at” represents a JavaFX KeyFrame, and the keyword “change” represents a KeyValue.

x = 0;
y = 0;
def tlb = new TimelineBuilder();
def tl = tlb.timeline(cycleCount: 2, onFinished: { Platform.exit()}) {
    at (1.m, onFinished: { println "x = ${this.x}, y = ${this.y}"} ) {
        change (this,"x") {
            to 2.0
            tween  "ease_both"
        }
        change (this,"y") {
             to 125
        }
    }
}
tl.playFromStart();

The DSL also understands that the entry “1.m” equates to a JavaFX Duration of one minute. Other examples of this DSL  include: “200.ms” is 200  milliseconds, “10.s” is 10 seconds, “1.h” is one hour.

How much of the JavaFX 2.0 API does GroovyFX cover?
Our goal is to cover the most used parts of the JavaFX 2.0 API. This includes all Controls, Shapes, Charts, Media and Image objects. Support is also provided for all effects, paints, transitions, and the new Web Engine feature to display browser pages.

So, GroovyFX is targeted at people writing user interfaces in Groovy, and we’ve learnt already that GroovyFX makes building JavaFX 2.0 interfaces far more succinct than writing the same functionality in plain Java. Does this mean you think people should consider using GroovyFX for their entire application stack, or is it possible for GroovyFX to play nicely with backend code that may already exist in Java (and may already have a user interface written in other UI toolkits such as Swing)? What would you recommend?
You can write your entire application in Groovy, and use GroovyFX for the UI coding. If you were going to do that, I would recommend checking out a framework like Griffon.  There is currently a set of Griffon plugins and an archetype in the works that will let you create JavaFX apps in Griffon. The plugins make use of GroovyFX when writing the view code.

As far as Swing integration is concerned, it works well!  Here is an example from the GroovyFX project that shows a Swing application that is a simple web browser with an embedded JavaFX WebView that displays the web content.

import groovyx.javafx.SceneGraphBuilder
import groovyx.javafx.GroovyFX;
import javafx.embed.swing.JFXPanel
import groovy.swing.SwingBuilder
import java.awt.BorderLayout as BL
import javax.swing.WindowConstants as WC
import java.awt.Dimension
import javafx.application.Platform;

def DEFAULT_URL = "http://www.yahoo.com"
def swing = new SwingBuilder();
def fxPanel = new JFXPanel(preferredSize: new Dimension(800,400));

def setUrl = { url ->
    Platform.runLater {
        webEngine.load(url)
    }
}

swing.edt {
    frame = frame(title:'Swing Embedded Browser', show: true,
          defaultCloseOperation: WC.EXIT_ON_CLOSE) {
        borderLayout()
        panel(constraints: BL.NORTH) {
            textField(id: "urlField", actionPerformed: {setUrl(urlField.text)}, columns: 40)
            button(text: "Go", actionPerformed: {setUrl(urlField.text)})
        }
        widget(fxPanel, constraints: BL.CENTER)
    }
    frame.pack()
}

GroovyFX.start {
     def sg = new SceneGraphBuilder(it);
     fxPanel.scene = sg.scene(width: 800, height: 400) {
         webEngine = webEngine(location: DEFAULT_URL)
         webView(engine: webEngine)
     }
}

A Swing application with a JavaFX WebView embedded inside it using GroovyFX

GroovyFX is a relatively new project. What plans do you have for GroovyFX in the future?
We have written the basic support for JavaFX 2.0, now we want to use it for real projects and find ways to make it easier and more intuitive to develop with. Of course, as JavaFX evolves, we will evolve GroovyFX.

How can people get involved with this project? What kind of help are you looking for?
For now we want people to download it and use it, then provide us feedback. What is good? What features should we add? What is broken?

Guys – thanks so much for your time. Do you have anything else you’d like to add?
Obviously, we are excited about JavaFX 2.0, with both the re-write of JavaFX in Java and the new features added to the platform. GroovyFX builds on this momentum and provides a robust platform for Groovy developers to make really cool looking applications.