GWT library to its full potential. It provides a thorough, no-nonsense explanation of the
Ext GWT library, what it offers, and how to use it through practical examples. This book
provides clear, step-by-step instructions for getting the most out of Ext GWT and offers
practical examples and techniques that can be used for building your own applications in
Ext GWT.
This book gets you up and running instantly to build powerful Rich Internet Applications
(RIA) with Ext GWT. It then takes you through all the interface-building widgets and
components of Ext GWT using practical examples to demonstrate when, where, and how
to use each of them. Layouts, forms, panels, grids, trees, toolbars, menus, and many other
components are covered in the many examples packed in this book. You will also learn to
present your data in a better way with templates and use some of the most sought-after
features of Ext GWT in your web applications such as drag-and-drop and charts.
Throughout the book, a real application is built step-by-step using Ext GWT and
deployed to Google App Engine.
Imagine how great you’ll feel when you’re able to create great-looking desktop-style user
interfaces for your web applications with Ext GWT!
GWT Articles
- Buy GWT in Action from GWT Books Store
- Comparison of AJAX Frameworks
- Google Web ToolKit(GWT)
What This Book Covers
Chapter 1, Getting Started with Ext GWT, introduces Ext GWT and explains where it fits
into GWT. It then moves on to show how to get up and running with Ext GWT by
creating your first project.
Chapter 2, The Building Blocks, starts by looking at the explorer demo application. It
then introduces the world of GXT components, beginning with some key concepts, and
quickly moves on to practically working with an example application.
Chapter 3, Forms and Windows, explores GXT’s form features. It looks at the form
components that GXT provides and demonstrates how to put them to use. It also
introduces the GXT Registry and shows how it can be used across the application.
Chapter 4, Data-backed Components, explains how GXT facilitates working with data. It
looks at the components available for retrieving, manipulating, and processing data and
then moves on to work with the built-in data-backed display components.
Chapter 5, More Components, introduces more advanced data-backed components
and the extensions that build on the components covered in the previous chapter. It
then moves on to cover additional advanced components—specifically menus, toolbars,
and tabs.
Chapter 6, Templates, looks at templates and how they can be used to easily format and
display data in a highly customizable way. It also introduces the more powerful features
of XTemplates.
Chapter 7, Model View Controller, explains GXT’s Model View Controller framework
and demonstrates how it can allow components to communicate in larger applications.
Chapter 8, Portal and Drag-and-Drop, covers the portal and drag-and-drop features
of GXT. It starts by showing how to turn out existing components into portlets and
then moves on to practically make use of GXT’s drag-and-drop features to move data
between them.
Chapter 9, Charts, covers GXT’s charting plugin. It explores the wide range of charts
available, shows how to avoid the pitfalls of the plugin, and demonstrates how charts can
be used with existing data.
Chapter 10, Putting it all together, shows how to publish the example application to the
world using the Google App Engine. It then moves on to look at how to take
development with GXT further and other resources that can be turned to after this book.
In this chapter, we introduce how GXT allows us to work with data. We look at
the components available for retrieving, manipulating, and processing data,
and then move on to work with the built-in data-backed display components.
We shall cover the following components:
Data
- ModelData
- BeanModel
- BeanModelTag
- BeanModelMarker
- BeanModelFactory
- Stores
Remote Data
- DataProxies
- DataReaders
- ListLoadResults
- ModelType
- Loaders
- LoadConfigs
Data-backed components
- ListField
- ComboBox
- Grid
- ColumnModel
- ColumnConfig
- GridCellRenderer
Working with data
One of the advantages of AJAX applications, including those built with GXT, is the ability to
manipulate data in the browser. GXT provides useful data-backed visual components that
allow us to work with local data such as lists, combos, and grids. With them we can perform
sorting, filtering, and editing operations on data quickly and efficiently.
There is also another set of components that work in the background allowing us to retrieve
remote data, cache it on the client, and deliver it to the visual components. It is these two
sets of components that we are going to focus on in this chapter.
First of all, we are going to look at how to produce the data that we need for display in the
visual components.
ModelData interface
GXT provides us an interface named ModelData. Any data objects we wish to use with GXT
data-backed components must implement this interface. The ModelData interface provides
the ability for property names and values to be retrieved at runtime. As GWT does not
support refl ection, GXT does this using a form of introspection.
In our example application, at present we are using a JavaBean named Feed to store feed
data. However, at the moment, it does not implement the ModelData interface, so we
cannot use it with GXT’s data-backed components.
We have three methods that will allow us to achieve this:
- Modify the Feed JavaBean so that it extends BaseModel.
- Modify the Feed JavaBean so that it implements BeanModelTag.
- Create a BeanModelMarker interface to accompany the Feed JavaBean.
This method allows us to avoid having to modify the Feed JavaBean.
Method 1: Extending BaseModel
BaseModel is the default implementation of the ModelData interface. Classes that extend
BaseModel make use of a HashMap to store data rather than local fields. Data is added and
retrieved using the set and get methods of the BaseModel respectively. The downside
of this method is that we need to use strings as attribute names and as such it is easier for
errors to creep in.
The Feed object implemented as a subclass of BaseModel would look like this:
public class Feed extends BaseModel {
public Feed () {
}
public Feed (String uuid) {
set("uuid", uuid);
}
public String getDescription() {
return get("description");
}
public String getLink() {
return get("link");
}
public String getTitle() {
return get("title");
}
public String getUuid() {
return get("uuid");
}
public void setDescription(String description) {
set("description", description);
}
public void setLink(String link) {
set("link", link);
}
public void setTitle(String title) {
set("title", title);
}
}
BeanModel class
If we already have a JavaBean we wish to use instead of creating a new BaseModel, GXT
provides the BeanModel, a class which acts as a wrapper for JavaBeans. BeanModel objects
cannot be created directly; instead they are generated by a BeanModelFactory.
BeanModelFactory class
BeanModelFactory is a useful class that allows us to take a JavaBean with a
corresponding BeanModelMarker interface such as a Feed object, and get back
a BeanModel representation.
The remaining two methods of providing a ModelData object involve wrapping a JavaBean
as a BeanModel.
Method 2: Implementing BeanModelTag
BeanModelTag is an interface that allows us to tag existing Java objects that meet the
JavaBean specification. This allows BeanModel instances to be generated from the JavaBean
using a BeanModelFactory.
In order to make our existing Feed JavaBean usable as a GXT BeanModel, we simply need to
implement the BeanModelTag interface like this:
public class Feed implements Serializable, BeanModelTag {
private String description;
private String link;
private String title;
private String uuid;
public Feed() {
}
public Feed(String uuid) {
this.uuid = uuid;
}
public String getDescription() {
return description;
}
public String getLink() {
return link;
}
public String getTitle() {
return title;
}
public String getUuid() {
return uuid;
}
public void setDescription(String description) {
this.description = description;
}
public void setLink(String link) {
this.link = link;
}
public void setTitle(String title) {
this.title = title;
}
}
This still requires a change to the JavaBean, however. There are situations where making
any change to a JavaBean would be unacceptable or at least undesirable. In this case, GXT
provides the BeanModelMarker.
Method 3: Creating a BeanModelMarker
BeanModelMarker is an interface, which, as its name suggests, allows us to mark an
existing JavaBean as a BeanModel. This is achieved by creating an interface that extends
BeanModelMarker. It makes use of annotations to define the JavaBean to wrap.
In our example application, we already have a Feed JavaBean, and we will now create a
BeanModelMarker for it so that we can use it with the GXT data-backed controls.
Notice the use of the @BEAN annotation to make a reference to the Feed class. We do not
need to make any changes to the Feed JavaBean itself.
Time for action – creating a BeanModelMarker for Feed objects
- Create a new class named FeedBeanModel that implements the
BeanModelMarker interface in a new package named client.model:public class FeedBeanModel implements BeanModelMarker {}
- Add an @BEAN annotation to tell GXT to use the Feed JavaBean class as follows:
@BEAN(com.danielvaughan.rssreader.shared.model.Feed.class)
public class FeedBeanModel implements BeanModelMarker {}
What just happened?
We created a BeanModelMarker for our existing Feed JavaBean. We can now use our Feed
JavaBean with GXT’s data-backed controls without having to modify the Feed JavaBean class
in any way.
Stores
In GXT, a Store is an abstract class used to provide a client-side cache of ModelData objects
of a specified class. Stores are where the data-backed GXT components keep data. There are
two concrete Store classes. The first is TreeStore, which is used with Tree components,
and we will look at these in the next chapter. The second is ListStore, which is used for
storing the lists of data. These are typically used with ListField, ComboBox, and
Grid components.
To create a ListStore to contain Feed objects, we would define it like this:
ListStore<BeanModel> feedStore = new ListStore<BeanModel>();
Note that the ListStore is set to contain BeanModel instances. This is because a Store
can only contain objects that inherit from the ModelData class. If we wanted to add a Feed
JavaBean object, we cannot do it directly. We need to use a BeanModelFactory to convert
the Feed JavaBean object into a BeanModel representation.
We will now modify the example application so that when creating a new Feed
JavaBean object, a BeanModel representation of the Feed object is added into
a client-side ListStore.
Time for action – creating and populating a ListStore
- In the RSSReaderConstants class, add a new constant named FEED_STORE for
the feed store:
public static final String FEED_STORE = "feedStore";
- In the onModuleLoad method of the RSSReader class, create a new ListStore
and add it to the Registry using the FEED_STORE constant as the key:
public void onModuleLoad() {
Registry.register(RSSReaderConstants.FEED_SERVICE,
GWT.create(FeedService.class));
Registry.register(RSSReaderConstants.FEED_STORE, new
ListStore<BeanModel>());
…
}
- In the save method of the FeedForm, modify the onSuccess method of the
callback function to retrieve the feed store from the Registry:
public void save(final Feed feed) {
@Override
public void onSuccess(Void result) {
Info.display("RSS Reader", "Feed " + feed.getTitle()
+ " saved successfully");
final ListStore<BeanModel> feedStore = Registry
.get(RSSReaderConstants.FEED_STORE);
}
…
}
- Retrieve a BeanModelFactory for the Feed class:
public void onSuccess(Void result) {
Info.display("RSS Reader", "Feed " + feed.getTitle() + " saved
successfully");
final ListStore<BeanModel> feedStore =
Registry.get(RSSReaderConstants.FEED_STORE);
BeanModelFactory beanModelFactory =
BeanModelLookup.get().getFactory(feed.getClass());
}
- Finally, use the BeanModelFactory to create a BeanModel representation of the
Feed object and then add it to the feed store:
public void onSuccess(Void result) {
Info.display("RSS Reader", "Feed " + feed.getTitle() + " saved
successfully");
final ListStore<BeanModel> feedStore =
Registry.get(RSSReaderConstants.FEED_STORE);
BeanModelFactory beanModelFactory =
BeanModelLookup.get().getFactory(feed.getClass());
feedStore.add(beanModelFactory.createModel(feed));
}
What just happened?
Feed objects are now stored in a GXT ListStore. The advantage of this is that we can now
simply link the data-backed components to the Store, and the values in the components
will refresh automatically.
Data-backed ComboBox
Once we have a ListStore populated with data, we can use it to provide the options in a
ComboBox by binding the ComboBox to the Store. We would take the feed store and create
a ComboBox that uses the title field of each Feed to populate the values of the ComboBox
like this:
ComboBox<Feed>combo = new ComboBox<Feed>();
combo.setDisplayField("title");
combo.setStore(feeds);
Here we use the setDisplayField of the ComboBox to set the title field as the field to use
as the display value.
Once a data-backed component is linked with a Store, it then observes the Store for
changes. If a change to the data in the Store occurs, such as an object being added to the
Store, the content of the data-backed control will be updated automatically. The specific
Store events that can be observed are listed as follows:
- Add
- Clear
- Data Changed
- Filter
- Remove
- Sort
- Update
Data-backed ListField
Associating a ListField with a Store is very similar to associating a ComboBox with a
Store. In our example application, we will now add a ListField containing all current
feeds to the left navigation panel.
Time for action – creating a ListField for feeds
- Create a new package named client.lists, and in it create a new class named
FeedList that extends LayoutContainer:
public class FeedList extends LayoutContainer {}
- In the constructor of the FeedList class, set the layout of the LayoutContainer
to FitLayout:
public FeedList() {
setLayout(new FitLayout());
}
- Override the onRender method, and in it create a new ListField:
@Override
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
final ListField<BeanModel> feedList = new
ListField<BeanModel>();
}
- Again in the onRender method, retrieve the feed store from the Registry:
final ListStore<BeanModel> feedStore =
Registry.get(RSSReaderConstants.FEED_STORE);
- Set the feed store as the Store for the feed list ListField:
feedList.setStore(feedStore);
- Tell the ListField to use the title field of the Feed object as the value to display in
the ListField:
feedList.setDisplayField("title");
- Add the ListField to the underlying container:
add(feedList);
- At the end of the constructor of the RssNavigationPanel, set the layout to a new
instance of FitLayout and add a new instance of the FeedList component to
the underlying ContentPanel:
setLayout(new FitLayout());
add(new FeedList());
- Start the application, click on the Create feed button, and complete the form as
shown in the screenshot below:

- On clicking the Save button, the new feed’s title, Test Feed, will appear in the list
of feeds on the left:

What just happened?
We added a list of feeds to the RSS Reader application. When we created a new feed, it
automatically appeared in the feed list on the left.
GWT Articles
- Buy GWT in Action from GWT Books Store
- Comparison of AJAX Frameworks
- Google Web ToolKit(GWT)