The Source for Java Technology Collaboration
User: Password:
Register | Login help    

Search

Online Books:
java.net on MarkMail:


Evan Summers

Evan Summers studied mechanical engineering for 8 years, but still didn't know which way to turn a screw driver. So he tinkered with Java, and eventually found "that Swing." Now he lives in a shelter for Swing code junkies, and works on aptframework.dev.java.net.

 

Evan Summers's blog

Automatic Binding

Posted by evanx on September 1, 2008 at 10:55 AM PDT

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.

Related Topics >> Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)
Syndicate content