Wednesday, April 28, 2010

Extending widgets for use with UIBinder

UIBinder, as released with GWT 2, is convenient because it allows us to specify our UI structure through XML.

However, the maturity of UIBinder is left in question because many useful GWT widgets are quite unusable in UIBinder, placing in question the deployment capability of UIBinder in any practical project. Not that they are unusable, but UIBinder allows them to function only as child widgets, and hence, incapable of having children within the UIBinder framework.

This article tells you how to write wrappers around GWT widgets to make them available for use as parent widgets with UIBinder. In fact, you can even place such wrappers around SmargGWT widgets.

Rule: Must implement HasWidgets Interface.
Any GWT widget to be used with UIBinder must implement the interface
com.google.gwt.user.client.ui.HasWidgets.

HasWidgets interface requires your wrapper to make the following methods available.

void add(Widget w);
void clear();
Iterator<Widget> iterator();
boolean remove(Widget w);

This is especially true with widgets that inherit the restriction of the SimplePanel abstract widget. SimplePanel widgets can only have one child and a child is acquired through the setWidget method, without implementing the HasWidgets interface.

Exception to Rule: Otherwise, patch-extend an insider-traded widget.
There are existent UIBinder widgets which do not implement HasWidgets. This is due to GWT insider-trading with some of the repertoire of UIBinder widgets - the GWT compiler recognises the type of those widgets and has insider-coded their UIBinder child and attribute specification and constraints. The only way to overcome the unfair advantage these widgets have is by patch-extending them. We fool the GWT compiler into believing it is compiling one of its own insider-traded widgets by extending such widgets.

You might be asking, if a widget is already capable as a parent widget with UIBinder, what is the point of wrapping them? The reason is to expand the repertoire of widgets allowed to be its children. Since the GWT compiler has already insider-coded what such widgets are allowed to have as children.

What I mean by patch-extending is, placing the extension class within the same package namespace - by stealing into the namespace com.google.gwt.user.client.ui. Primarily, due to needing access to default and protected objects of the original widget.

And, what I mean by insider-trading of UIBinder widgets is the existence of parsers specialised for a bunch of widgets, where we (end-user-programmers) have scantly any way of inserting our own parser:
http://code.google.com/p/google-web-toolkit/source/browse/#svn/trunk/user/src/com/google/gwt/uibinder/elementparsers. Unless we built our own gwt-user.jar.

4 comments: