Binding to a POJO
Good afternoon!
So, I have a program I'm writing whose primary window is a JFrame. Many
of the JFrame's children are bound to fields within a Java bean.
I was using JGoodies Binding to accomplish this, but then I started
using WindowBuilder Pro, which has very nice support for JSR 295
(BeansBinding).
The often-cited problem with either JGoodies or BeansBinding is this: it
introduces code bloat. Instead of
public void setFoo(Object newFoo) {
this.foo=newFoo;
}
you have to do this:
public void setFoo(Object newFoo) {
String oldFoo = this.foo;
this.foo=newFoo;
// support is a previously-initialized
// instance of java.beans.PropertyChangeSupport
support.firePropertyChange(propertyName, oldValue, newValue);
}
I came up with a solution that will allow you to do this instead:
public void setFoo(Object newFoo {
changeProperty("foo",this.foo,newFoo);
}
How do I do this? I make my bean inherit from PCLBean:
package com.lobosstudios.binding;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class PCLBean {
private transient PropertyChangeSupport support = new
PropertyChangeSupport(this);
protected boolean changeProperty(String propertyName, Object
oldValue,
Object newValue) {
System.out.println(propertyName + ": old=" + oldValue + ",
new="
+ newValue);
try {
setNewValue(propertyName, newValue);
} catch (NoSuchFieldException exc) {
exc.printStackTrace();
return false;
} catch (IllegalAccessException exc) {
exc.printStackTrace();
return false;
} catch (InvocationTargetException exc) {
exc.printStackTrace();
return false;
}
support.firePropertyChange(propertyName, oldValue,
newValue);
return true;
}
private void setNewValue(String propertyName, Object newValue)
throws IllegalAccessException,
InvocationTargetException,
NoSuchFieldException {
Class<? extends PCLBean> c = this.getClass();
Field f = c.getDeclaredField(propertyName);
// this next step allows us to set the value of a property
// even if it wouldn't normally be visible; e.g. if it is
private
f.setAccessible(true);
f.set(this, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener
listener ) {
support.addPropertyChangeListener( listener );
}
public void removePropertyChangeListener(PropertyChangeListener
listener ) {
support.removePropertyChangeListener( listener );
}
}
Am I over-thinking this? Is it necessary to do this? (It does keep my
code a little cleaner than it would otherwise. I like that. But it also
uses reflection, which may impact performance.)
What do y'all think? (Please note: this code is still rough, and
improvements can probably be made to it)
--
Steve Sobol - Programming/Web Dev/IT Support
Apple Valley, CA
sjsobol@JustThe.net