Groovy 1.5 has been released. Yes, this is the former 1.1-rc line, and a late decision was made to brand it Groovy 1.5. It's more than the typical incremental improvements, but not quite a major release (by a hair), so at the prompting of Alexandru Popescu we went for a release number that shows compatibility with Java 1.5 features.
In addition to the basic language level changes, there are a lot of changes that went into Groovy's Swing support.
- Almost every line in the SwingBuilder was adjusted in some way. And the whole thing was ported over to Groovy from Java. Dogfood baby!
- FactoryBuilderSupport is a juiced up refactoring of SwingBuilders building pattern. SwingBuidler is now a subclass of FactoryBuidlerSupport fully using Factories for all of it's classes, and node specific handling has similarly been moved to the factories out of the SwingBuidler core.
- At the FactoryBuilderSupport level a new
build()method was added, so external Groovy Scripts can be called and executed as though they are builder content directly.
- Also at the FBS level nodes that create object that should be disposed are tracked via addDisposalClosure(), which are all called in FILO order from the dispose() method.
- Most nodes now accept an object of their own type, providing another point of extension.
button(new MyCustomButton())works as expected if MyCustomButton extends JButton
actions(), a simple collection node that is meant to describe actions
imageIcon()provides support for ImageIcons
- Borders are now supported via buidler nodes.
model(), adding binding support for observable properties.
- The passthrough
widget()now has two use specific cousins,
container()for widgets that can have children (
widget()now throws an error when children are added) and
bean(), which will not add the resulting object to the parent container. (Note that the expanded argument support for the basic nodes should reduce the necessity of these nodes. Just add the new widget as an argument to it's javax.swing type.)
edt(Closure), executes the Closure in the Event dispatch Thread (EDT) and wait for completion (via SwingUtilities.invokeAndWait). Optimizations are performed for when the method is called in the EDT.
doLater(Closure), executes the Closure in the EDT asynchronously via SwingUtilities.invokeLater()
doOutside(Closere), insures that the closure is executed outside of the EDT. If the context is not in the EDT it is executed immediately, otherwise a new thread is created
shortcut(key [, modifiers]), given a keystroke it adds a platform specific modifier for it (ctrl on Windows and GTK, option on MacOS).
dispose()invokes all disposal closures. Generally these are things such as dialogs, frames, and windows created by the SwingBuilder and unbinds all bindings created by
lookAndFeel()is an easy way to set the look and feel. Defaults exist for system, metal, nimbus, etc. and a few third party LAFs.
New static method
build(Closure), creates and returns a SwingBuilder and executes the closure in context of the Event Dispatch Thread.