Passing Events instead of Widgets to Listeners in the Google Web Toolkit (GWT)

Level: Advanced
Date: Originally published 10/07
Author: Richard Bondi,

In GWT, a listener object A may attach itself to many other widgets. These widgets will call A's onChange (or similar) method, and pass themselves as onChange's only parameter. Inside onChange, A must then decide which widget called it. At this point a programmer unfamiliar with the code faces a problem: there is no easy way for her to tell which of the widget's many methods and properties are intended to be used by A. The solution given here is to create an interface, named [widget's name]Event, that has only methods to be used inside of onChange. This makes for clean and understandable code.


If a GWT Java class or Widget A is listening to a Widget named X, X will call A's onChange event with listener.onChange(this), where listener is a reference to an instance of A. On A, the onChange() method will look something like Figure 1:

[Figure 1:  the onChange method of a GWT Java class named A that is listening to Widgets X and Y]
public void onChange(Widget sender)
{
if(sender == X)
{
    // do stuff, possibly using data from X

}
if(sender == Y)
{
  // do stuff, possibly using data from Y
}
// etc
}
The problem is the "possibly using data from X". If A and X were written by two different programmers -- perhaps widget X is a third-party widget --, how on earth is the programmer for A supposed to know what to do with X (apart from reading the documentation, if it exists)? Only some of X's methods will be intended to be used by a listener, but which ones? X may have many, many methods which have nothing, absolutely nothing, to do with what A wants to do when X changes.

If only we could pass an X event of some kind to onChange(), instead of X itself, then that event could contain only the information A needs for processing a change in X.

A simple way to accomplish this is to declare a new interface XEvent in the same package as X. Then give it only the methods A (and any other listeners) need to respond to X changing, and Javadoc them.

Now A's code can look like this:

[Figure 2: the onChange event of class A that uses X's XEvent interface.
public void onChange(Widget sender)
{
if(sender == X)
{
XEvent event = (XEvent) sender:
// do stuff with event: ignore X!
}
// etc
}

For different kinds of events (ClickEvents, FocusEvents, BrowserEvents, etc etc) you can declare different event interfaces, like XClickEvent, XFocusEvent, and so on.

Problem solved!



Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License.