Exploring data binding with Gwittir

January 30th, 2008 - Written by in Using GWT

is a library for GWT that provides a lot of interesting features including data binding, animation, reflection, and more. To help me learn more about this library, I decided to take it a spin and create a small GWT application to experiment with Gwittir’s data binding capabilities. So what does data binding give you? It allows you to glue together your user-interface widgets with the properties on your domain model. Whenever a user does something to a bound widget, its associated property in the model will be updated automatically. The binding is bi-directional as well, so if you make a change to the model, the widget will also update itself to reflect the change. Neat! So some of the benefits of data binding are that it promotes good MVC design, and it saves you from writing all those event listeners to copy data back and forth between UI and model.

The sample application I created is this simple data entry form, which allows the adding of books to a table.

I first created a Book object to be my model. It is a simple JavaBean with three fields, title, year, and inStock and extends the AbstractModelBean class. AbstractModelBean implements the Bindable interface which allows an object to be bound by the Gwittir framework and gives us the necessary PropertyChangeSupport.

(com.gwtsite.gwittir.Book)

public class Book extends AbstractModelBean {
  private String title;
  private int year;
  private boolean inStock;
 
  public Book() {}
  public String getTitle() {
    return title;
  }
  public void setTitle(String title) {
    this.title = title;
  }
  // ... other getter and setters omitted

For the user interface, I created a composite BookForm widget to hold the input fields and a table which displays the added books. The Gwittir distribution includes several BoundWidgets (Button, TextBox, etc), which are just standard GWT widgets with some extra methods to make binding easier. To get this behavior in my BookForm widget, I extended AbstractBoundWidget. By doing this, I had to implement the getValue() and setValue() methods. For a composite widget like I’ve created, the value property is simply my Book model.

(com.gwtsite.gwittir.BookForm)

public BookForm() {
  this.setValue(new Book());
  // ...
}
public Object getValue() {
  return this.getModel();
}
public void setValue(Object value) {
  this.setModel(value);
}

Now that I have created my model and view, I need a controller to hook everything together. In Gwittir, this is called an action. For this, I created an AddBookAction class which implements the BindingAction interface. This interface has four methods, bind(), unbind(), set() and execute(). Lets look at the set() method first. The set() method gets called when our widget is initially attached to the browser window. It is responsible for doing all the dirty work and wiring up the Book properties to the widgets in our form.

The Gwittir Binding object represents the data binding between two bindable objects. It can also hold a list of child bindings which allow us to manage multiple bindings with one instance.

(com.gwtsite.gwittir.AddBookAction)

private Binding binding = new Binding();
 
public void set(BoundWidget widget) {
   BookForm bookForm = (BookForm)widget;
   Book book = (Book) bookForm.getModel();
   ...
   binding.getChildren().add(new Binding(book, "title", bookForm.titleText, "value"));

The above code demonstrates how we bind the title property of the Book object with the value property of the title TextBox of our BookForm UI widget.

Gwittir also provides support for adding validation to our bindings. I’ll demonstrate this by doing some validation on the year property. Lets say that we only allow books published after 1950 to be added to our list. To accomplish this, I created a custom Validator by implementing the Validator interface.

(com.gwtsite.gwittir.AddBookAction)

private class NewBooksOnlyValidator implements Validator
{
  public Object validate(Object value) throws ValidationException {
    String year = value.toString();
    if (new Integer(year).intValue() < 1950)
      throw new ValidationException("Must be after 1950.");
    return new Integer(year);
  }
}

Ok, so this is not truly correct code, but it will work for demonstration purposes. Now we need a way to show any validation errors. Gwittir provides a ValidationFeedback interface along with several implementations. I decided to use two implementations – the PopupValidationFeedback class which will display an error message next to the TextBox if the user enters an invalid year, and the StyleValidationFeedback class which will add a css class called validation-error which we can use to highlight any errors in red.

I can add these two implementations into a CompositeValidationFeedback object and pass it to the binding like this:

(com.gwtsite.gwittir.AddBookAction)

ValidationFeedback feedback =
        new PopupValidationFeedback(PopupValidationFeedback.RIGHT)
        .addMessage(NewBooksOnlyValidator.class, 
        "We only accept books published after the year 2000.");
CompositeValidationFeedback cvf = new CompositeValidationFeedback()
        .add(feedback)
        .add(new StyleValidationFeedback("validation-error"));
binding.getChildren().add(new Binding(book, "year", null, null, 
                                bookForm.publishedText, "value", 
                                new NewBooksOnlyValidator(), cvf));

The second method of our Action class is the bind() method. This gets called automatically after our BookForm is attached to the browser window. All it does is call bind() on our binding object and establishes the binding.

The last step is to call our Action’s execute() method. I call this from BookForm’s ‘Add book’ button.

(com.gwtsite.gwittir.BookForm)

addBookBtn.addClickListener(new ClickListener() {
  public void onClick(Widget sender) {
    if (getAction() != null) {
      getAction().execute(BookForm.this);
    }
  }
});

The execute implementation itself is actually quite simple. First it checks if the binding is valid. This will not be the case for example, if the user enters an invalid year. If the binding is valid, then we get the fully populated Book object from the form, and add it to our Table. Easy!

(com.gwtsite.gwittir.AddBookAction)

public void execute(BoundWidget widget) {
  BookForm bookForm = (BookForm)widget;
  Book book = (Book) bookForm.getModel();
  if (binding.isValid()) {
    bookForm.booksTable.add(book);
  }
}

Hopefully this small example will peak your interest in taking a closer look at what the Gwittir framework has to offer. It was created by Robert Cooper and Charlie Collins who have a new book coming out, called . So expect some cool stuff from this framework in the future.

References

17 Comments Stumble it!

Weekly GWT Links for 1/26/08

January 26th, 2008 - Written by in News

I spent some time this past week tweaking the layout of the site. I think it looks a bit cleaner than the old version. Anyway, onto the GWT links of this week!

Compiere - Open Source ERP built using GWT

Make sure to keep up with the latest GWT developments by .

No Comments Stumble it!

Who’s using GWT?

January 21st, 2008 - Written by in Using GWT

I read this Dan Moore blog entry a couple of weeks ago where he asked this same question and it seems to come up quite often on the GWT developer forum as well. It is an important question to answer because it is one of the first things people ask when evaluating whether or not to adopt a specific technology. The Google Web Toolkit has now been out for more than 1.5 years, so what have people done with it in that time? I took a look at this older list by Mark Volkmann and a couple on the developer forum and came up with my own set of GWT applications I would use, if I was showing off GWT to someone else. Here they are (in no particular order):

Pibb screenshot

Pibb
JanRain

Pibb is a GWT based web application that combines the best features of instant messenger, email, chat and message boards. It supports OpenID, a lightweight protocol, for single sign-on and portable identity.


GPokr screenshot

GPokr
Ryan Dewsbury

GPokr is a free, multi-player Texas Hold’em game written by Ryan Dewsbury, author of the book, Google Web Toolkit Applications. GPokr runs tournaments which are held starting on the 1st of each month and continue till the last day of the month.


KDice screenshot

KDice
Ryan Dewsbury

KDice is another free, multi-player strategy game by Ryan Dewsbury. It is based on Taro Ito’s Dice Wars. Gameplay in KDice is a simplified version of Risk with the primary goal being to defeat your opponents by conquering the entire map.


/
Google

Although I can’t tell by looking at their source, according to , Google is using GWT as part of their Google Base and Google Checkout applications. If Google themselves won’t use GWT, who else will?


QueWeb screenshot
QueWeb
Queplix

QueWeb is a commercial open source web application which provides a Customer Care solution for businesses. You can play around with their demo here.


ContactOffice screenshot

ContactOffice
ContactOffice

ContactOffice is a professional, “virtual office” which allows users to easily manage their data (emails, contacts, meetings, etc). The beta version of ContactOffice was developed using the Google Web Toolkit. Check out the demo here.


OpenKM screenshot

OpenKM
Josep Llort

OpenKM is another commercial open-source document management system which enables users to capture, publish, find and store electronic documents. Take a look at their online demo.


Dismoiou screenshot

Dismoiou.fr / Tellmewhere
BaDTech SAS

Dismoiou.fr is a web application built with GWT that allows users to collaborate and create a common database of points of interest in the world. Users can share their favorite places, see them on the map, give recommendations and even provide pictures and videos.

Are there any other really nice GWT applications out there I missed? Feel free to leave a comment and plug any GWT based application you’ve seen or have been working on.

62 Comments Stumble it!

« Previous Entries