Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Beans Binding: A Java Data-Binding Solution with a Serious Problem : Page 3

Data binding simplifies how you sync a data object's properties with their visual representations, and Beans Binding for Java (JSR 295) aims to deliver a default data-binding specification for the Java platform. Find out how to use Beans Binding and work around its onerous overhead.


advertisement
Binding to POJOs (Where Beans Binding Fails)
At this point you likely are ready to jump into Beans Binding. Alas, this library contains a major hidden flaw that makes it extremely cumbersome to use. The flaw is not the fault of Beans Binding itself, but rather the lack of required binding plumbing in the Java language. To be two-way bindable, each object on both the source and target sides must be a full JavaBean with manually-coded property change support—in other words, a simple POJO like this is not fully bindable out of the box:

public class Person { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }

The Person class is—at best—bindable one-way (as a target), but not two-way (as both a source and a target).



To be fully two-way bindable, the same POJO would need to look like this:

import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeListener; public class Person { private String firstName; private String lastName; private PropertyChangeSupport support = new PropertyChangeSupport(this); public void addPropertyChangeListener(PropertyChangeListener listener ) { this.support.addPropertyChangeListener( listener ); } public void removePropertyChangeListener(PropertyChangeListener listener ) { this.support.removePropertyChangeListener( listener ); } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { String old = this.firstName; this.firstName = firstName; support.firePropertyChange("firstName",old,firstName); } public String getLastName() { return lastName; } public void setLastName(String lastName) { String old = this.lastName; this.lastName = lastName; support.firePropertyChange("lastName",old,lastName); } }

All the additional lines of code are in bold type. As you can see, the main overhead is that on every setter you need to remember the current value and then fire a property change event with the property name in it. This overhead is already evident in this small POJO and only gets worse as the number of properties increases. Without the property change event, the Beans Binding library does not know that your object's property was updated, and accordingly, will not update any objects bound to it.

This flaw adds so many additional lines of code to each POJO that it makes Beans Binding practically useless. You would probably write about the same amount of code (or even less) by just syncing the properties manually in your UI.

This flaw has no simple workaround—other than enhancing the Java language with "real" properties that would automatically fire the events required for proper databinding. With Sun's misguided focus on JavaFX (leaving regular Java users behind), this is not likely to happen soon unfortunately.

Java ClassBuilder to the Rescue
Frustrated by this shortcoming, I created a small, open-source project called the Java ClassBuilder. It uses a custom classloader and dynamic bytecode transformation to generate the additional code automatically at run-time. All you have to do is add the predefined @Bindable annotation to your POJO, and you're done. Here's another fully-bindable version of the Person class:

@Bindable public class Person { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }

Of course, I hope that this is just a temporary solution.

Beans Binding Alternatives
As usual, no default library from Sun exists without some open source alternative attempting to improve on it. In this case, it is the JFace Databinding library from the folks at Eclipse. Despite the JFace moniker, this databinding library is actually quite generic and can be used with both Swing and SWT applications. It seems to enjoy a much more diverse and dynamic user community than Beans Binding (which hasn't seen a new release since November 2007), and it seems to be the future of data binding in Java. But that's a subject for a future article.



Jacek Furmankiewicz is a Senior Java EE and Erlang/OTP developer at Radialpoint. He has 15 years of professional IT experience and is a Sun Certified Java Programmer (SCJP).
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap