Skip to main content

Exploring GWT 2: Properties and Binding

Posted by mjeffw on September 16, 2008 at 8:05 AM PDT

Looking around the web for GWT property binding libraries did turn up several interesting candidates. Gwittr is a project (hosted on Google code) that includes property binding support. Metawidget is another project with property binding support. A kind reader also pointed me at InsiTech's GWT binding solution, which happens to be payware. At the time of my initial exploration, I was only aware of gwtx (such is the speed of change in our industry).

What gwtx does is to add other emulated classes from the Java runtime. That means you can use these classes as is from the Java standard libraries, and GWT will properly compile them to JavaScript. Among the classes supported by gwtx are java.beans.PropertyChangeSupport, java.beans.PropertyChangeListener, java.beans.PropertyChangeListenerProxy, java.beans.PropertyChangeEvent, and java.beans.IndexedPropertyChangeEvent.

These classes are used in standard Java to support properties. Using the example of a Person class from my first post, to add property change support to this class, you'd have to encapsulate the fields in getter and setter methods, and add property change support in those methods, like this:

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

public class Person
{
   private String firstName;
   private String middleName;
   private String lastName;
   private String address;
   private String city;
   private String region;
   private String postalCode;

   // an instance of the PropertyChangeSupport helper class
   private PropertyChangeSupport support;

   public Person()
   {
      support = new PropertyChangeSupport(this);
   }

   public String getFirstName()
   {
      return firstName;
   }

   public void setFirstName(String firstName)
   {
      String oldValue = this.firstName;
      this.firstName = firstName;
      support.firePropertyChange("firstName", oldValue, firstName);
   }

   // ... repeat for all fields that need property support

   // allow other objects to register interest in Property events
   public void addPropertyChangeListener(PropertyChangeListener l)
   {
      support.addPropertyChangeListener(l);
   }

   public void addPropertyChangeListener(String propertyName, PropertyChangeListener l)
   {
      support.addPropertyChangeListener(propertyName, l);
   }
  
   public void removePropertyChangeListener(PropertyChangeListener l)
   {
      support.removePropertyChangeListener(l);
   }

   public void removePropertyChangeListener(String propertyName, PropertyChangeListener l)
   {
      support.removePropertyChangeListener(propertyName, l);
   }
}

For another object to bind to the firstName property, it would do something like this:

class Client
{
   protected String fname;

   public Client()
   {
      Person p = new Person();
      p.addPropertyChangeListener("firstName", new PropertyChangeListener() {
         public void propertyChange(PropertyChangeEvent evt)
         {
            fname = (String) evt.getNewValue();
         }});
   }
}

I don't know about you, but that is a lot of boilerplate code needed to add property support. For the Java SE-side of development, there is an effort to reduce or eliminate a lot of that code with JSR 295: Beans Binding, but it will take some time before that JSR is complete and in a JRE distribution, and some time after that before it is supported by GWT, if at all. Meanwhile, what is a GWT developer to do?

I decided to see how hard it would be to add this support myself, figuring I would be able to get into some real depth in the GWT code in order to accomplish this. What I wanted was to go from a plain old data object, possibly with getters and setters, and dynamically build an adapter class that added all of the property binding support. In Java SE this could be accomplished in several ways, including dynamic proxies, byte code generation, aspect-oriented programming, and reflection ... all of which are missing in GWT at the moment.

So the challenge I posed myself is, how can I reduce the custom code for adding property events and binding from the above, to something like this:

public class Person
{
   private String firstName;

   public String getFirstName()
   {
      return firstName;
   }

   public void setFirstName(String firstName)
   {
      this.firstName = firstName;
   }
}

class Client
{
   protected String fname;

   public Client()
   {
      Person p = new Person();
     
      // create a Property adapter from the class
      PropertyAdapter adapter = PropertyFactory.create(person);

      // bind the "firstName" property to fname
      adapter.get("firstName").bind(new PropertyChangeListener(){
         public void propertyChange(PropertyChangeEvent evt)
            {
               fname = (String) evt.getNewValue();
            }});
   }
}

Next entry, I begin to explain how to accomplish this, which involves a deep dive into GWT's deferred binding mechanism to generate new code at compile time.

Related Topics >>

Comments

dirtyqwerty, sorry, I did slip up -- code generation *is* possible in GWT, as it is the implementation of the deferred binding mechanism I mention in the last line. However it is not code generation at runtime, as most Java SE and Java EE solutions do. Nor is it byte code generation, but it is actual source code generation. Hang on, I'm heading that way...

'In Java SE this could be accomplished in several ways, including dynamic proxies, code generation, aspect-oriented programming, and reflection ... all of which are missing in GWT at the moment. ' i don't believe this to be true. do a search for "deferred binding" "generators" and the GWT.create(Clazz.class). This is the basis of the GWT abstraction.

dxxvi, you may want to revisit GWT 1.5 with the added property support in Gwittr or Metawidget.

I used gwt 1.4 in the past and was tired of the lacking of property binding and generics (which is in gwt 1.5). Does anybody know (roughly) when GWT 2.0 will be released?

- http://www.ongwt.com/post/2008/09/17/GWT-ZK-and-FUD

Varan, I don't know much about ZK, but a quick look around at the website looks interesting. However, there are reasons why a team would select any of the various web application frameworks over any other one, and I don't want to do that comparison here. I'm just going to chronicle my exploration of the GWT framework.

Sorry, that should be 'does NOTdoes require the user to deal with the separation between the client side and the server side code '.

It might be easier to do this for ZK as it does require the user to deal with the separation between the client side and the server side code and most of the updates to the client can be done from the server.