If you do Swing application development, especially the enterprise application type you know lots of code that looks like this:

public class Person {
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);

public void setName(String aName){
String oldValue = name;
name = aName;
pcs.firePropertyChange("name", oldValue, aName);
}

public String getName(){
return name;
}

Having properties like this you can bind them to Swing components using JGoodies Binding like this:

      MyBean bean = new MyBean();
BeanAdapter adapter = new BeanAdapter(bean, true);
ValueModel stringModel = adapter.getValueModel("name");
JTextField field = BasicComponentFactory.createTextField(stringModel);

If you don't know JGoodies Binding you should read this article about it asap.

If you do form based Swing applications this is the way to go: don't write Listeners, bind components.

Yet I have a huge problem with this code. Actually multiple problems:

If you are willing to switch to another language you actually can abstract over this quite nicely. This of course in no surprise, since it should be easy to write a language that offers support for this kind of property. But that is not what I'm talking about. I'm of course talking about a little Scala goodness. How about this for defining a class with a property:

class Person extends PropertyOwner {
val name : Property[String] = "smith"
}

Note that there is only one line defining the property (including setting it to an initial value). So how would binding it to a JTextField look like? Like this:

    val p = new Person
val nameTextField = new JTextField()
Binder.bind(p.name, nameTextField)

Note that I don't use the String "name" anywhere. Its all just normal, strongly typed values. If I use firstName instead of name by accident, the compiler will complain. The trick is obviously that I actually use objects of type Property, instead of fields, getters and setters. Yet using this thing looks (almost) perfect natural:

    val p = new Person
p.name := "Alf"
println(p.name())

The code to achieve this is rather simple and short. The key is that a Property has a apply method returning its value and an := operator as replacement for a setter.

class Property[T](var value : T) {
var listeners = List[T => Unit]()

def apply() = value

def :=(aValue : T) {
if (value != aValue) {
value = aValue
fireEvent
}
}

def registerListener(l : T => Unit) {
listeners = l :: listeners
}

private def fireEvent {
listeners.foreach(_(value))
}
}

object Property {
implicit def apply[T](t : T)(implicit owner : PropertyOwner) : Property[T] =
new Property(t : T)

implicit def toT[T](p : Property[T]) : T = p()
}

trait PropertyOwner {
implicit val THE_OWNER = this
}

object Binder {
def bind(p : Property[String], textField : JTextField) {
var locked = false

initTextField
syncFromTextFieldToProperty
syncFromPropertyToTextField

def initTextField = p() match {
case null => textField.setText("")
case _ => textField.setText(p().toString())
}

def syncFromPropertyToTextField {
p.registerListener { value : String =>
if (textField.getText != value)
textField.setText(value)
}
}

def syncFromTextFieldToProperty = textField.getDocument.addDocumentListener(new DocumentListener() {
def changedUpdate(e : DocumentEvent) = updateProperty
def insertUpdate(e : DocumentEvent) = updateProperty
def removeUpdate(e : DocumentEvent) = updateProperty
})

def updateProperty = {
p := textField.getText
}
}
}

This is currently just a little toy, call it proof of concept if you like. It only works with JTextFields, and the event notification might needs tweaking, since it provides just the new value of the property right now. There are many more ideas how to use this as a basis for building nice clean code with a Swing GUI. Watch this blog for more ideas and toys like this.