The demo application from the Groovy SwingBuilder Tech Session at JavaOne 2008 is now runnable via WebStart. (note to self, link to SDN site when the presentaiton goes live). The source code may also be browsed via FishEye. There are a couple of points I wish to call out that were touched on in the tech session:
Model View Controller Separation
The GUI has a firm model view controller separation. All of the Twitter API functionality is sequestered into the TwitterAPI.groovy class. No other class does network functionality. The GUI code is also handled separate from the controller. View.groovy is the main class, whereas a couple other classes (ScrollablePanel.groovy, RoundedPanel.groovy) are there to support the view portion. One other view class, TweetLine.groovy, handles the rendering of the individual tweet line (because I was not satisfied with JList). Finally there is the controller class, Greet.groovy. In addition to the main method all Swing events are dispatched to the various controller methods. State variables are also kept here.
A lot of the glue code to manage visual state with the controller has been automated because of the new
@Bindable annotation in Groovy 1.6. This allows me to send notices that the view shouldn't be accepting updates and also notify the view that the backing data model has changed. Adding these hooks by hand would add at least 100-200 lines to the application and would also introduce repetitive code that is prone to cut and paste errors. The view code uses the
bind() node to easily bind the values of the actions to relevant attributes.
Actions are your friends
Less of a Groovy call out and more of a Swing call out. Use actions, actions are your friends. All of the buttons, text lines, and list boxes are not hooked directly to the controller, but to the action. This causes all of the relevant controls to turn off when the action becomes unavailable, and is why the bind to enable occurs in the actions definition and not the control definitions.
Builder scripts are still Groovy Code
In line 142 to 147 of View.groovy I do a loop inside of a panel to add the tweet lines individually, calling out to the TweetLine.groovy script. This is perfectly legal in Groovy, since a builder is actually just executing closures and using meta-programming to intercept the method calls. It may look like a static declarative XML type file in most cases, but it doesn't have to. Especially with repeating elements, it's a great way to DRY out code.
The 'Dynamic Language' part is what makes it possible
The dynamic language aspect of Groovy code (and in particular the Scripts) is what allows for most of the magic to happen. It is essential to the builder pattern. You will also notice that both of the principal view scripts (View and TweetLine) don't create a SwingBuilder, or even imply that one exists. They also use variables that are not defined in the scope of their script (like the controller object and the tweet). This provides for a very subtle form of resource injection that requires no ceremony to access. If this were statically typed I would have to state somehow the methods and fields the controller and tweet have, even if by simple type decleration. All of that formality is unneeded in this context.
So what is the future of Greet? I intend it to be one of a few marquee examples for a project I am attempting to get off of the ground with a few others, so the WebStart version may see some changes every once in a while. But that is also why I am a fan of the promise of WebStart (if not particular shipped versions), new versions can be distributed without the same ceremony as an installer.