Groovy 1.6 is about to hit it's first beta here pretty soon, so I thought I'de spend some time writing about an implementation of the second big feature. in 1.6. Call site caching is the first big feature, and that is really just a technical term for 'faster.' The second big feature is AST Transformations. Right now it just triggers off of annotations, but there are already two implementations of it that are slated to ship, @Mixin (which I won't go into here) and @Bindable/@Vetoable. I'll go into the details of how you could write a transform later, but now I will focus on the most common task, simply using it.
@groovy.beans.Bindable is an annotation that can go either on a Groovy class property or a Groovy class itself. When the annotation is on a class you are telling the transform that all properties declared in the class should be treated as having @Bindable (whether or not they already have it). When a property has this annotation the AST Transformation will generate (if it doesn't exist) a java.beans.PropertyChangeSupport object, appropriate listener addition methods, and then a setter that uses the property change support. The end result is a bound JavaBeans property, with a whole lot less boilerplate code. What was once this:
import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener;
class MyBean {
private String prop;
PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener l) {
pcs.add(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
pcs.remove(l);
}
public String getProp() {
return prop;
}
public void setProp(String prop) {
pcs.firePropertyChanged("prop", this.prop, this.prop=prop);
}
}
now looks a lot more concise and to the point:
import groovy.beans.Bindable
class MyBean {
@Bindable String prop
}
This goes hand in hand with the bind() node in swingbuilder, making a model update a text field automatically when it changes is now a simple as textField(text:bind(source:myBeanInstance, sourceProperty:'prop')). This is a very sublte thing to grok, but it really goes a long way in cutting down the amount of lines it takes to link the model and the view togeather in a client application.
The same premise goes for @Vetoable, you know, for all those constrained JavaBeans properties you write. You know, just in case. I have seen some code in the wild that uses VetoableChangeListeners, but not indexed JavaBean properties. It is useful for validation, when architected properly.