Automatic Binding
In the
>Gooey MvnC prequel, we advocate an MVC-type architecture for
programming a Swing UI panel, using convention-over-configuration
to automate event handling, thread switching and beans binding.
In the Gooey Event Proxy prequel,
we introduced a minimalistic helper class towards the above strategy,
illustrating the automatic wiring of events, for starters.
Now we present automatic binding
by convention-over-configuration, in order to bind components in the view
to properties in the presentation model, automatically,
by matching component names
to property names.
Salient Code
Our helper binds components to bean properties as follows.
public class GEventHelper {
protected Map<Field, Component> components = new HashMap();
...
public void bind(GBean bean) {
GBeanInfo beanInfo = new GBeanInfo(bean.getClass());
for (Component component : components.values()) {
GPropertyInfo propertyInfo =
beanInfo.getPropertyInfo(component.getName());
if (propertyInfo != null) {
inputComponentAdapterFactory.create(component).bind(
new GBeanProperty(bean, propertyInfo));
}
}
}
}
where GBeanInfo and GPropertyInfo are wrappers for java.beans.BeanInfo
and PropertyDescriptor, and GBeanProperty ties in a reference to
a bean instance.
For example, GTextFieldBinding below is used to establish a binding
between a JTextField and a bean property.
public class GTextFieldBinding
implements ActionListener, FocusListener, PropertyChangeListener {
JTextField component;
GBeanProperty property;
public GTextFieldBinding(JTextField component, GBeanProperty property) {
this.component = component;
this.property = property;
updateComponent();
property.addPropertyChangeListener(this);
component.addActionListener(this);
component.addFocusListener(this);
}
...
}
where the binding implements various listeners, and registers itself
as a listener on the component's events eg. FocusEvent, and
also as a PropertyChangeListener on the bean property.
In the focusLost() event handler below, we push the edited value into
the bean property.
@Override
public void focusLost(FocusEvent event) {
updateProperty();
}
public void updateProperty() {
try {
property.parse(component.getText());
} catch (GPropertyException e) {
property.handleException(e);
}
}
In propertyChange() below, we invoke updateComponent()
to pull the value from the bean into the component.
@Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals(property.getName())) {
updateComponent();
}
}
public void updateComponent() {
try {
component.setText(property.format());
} catch (GPropertyException e) {
property.handleException(e);
}
}
The full article is reposited
here.
- Login or register to post comments
- Printer-friendly version
- evanx's blog
- 960 reads





