If you have already had a deal with Java/Swing programming you must know that any visual component of the toolkit has a data model. Usually developers use data models to store data whereas components display this data in specific way.
The main conceptual difference between GWT and Swing is that GWT widgets don't use models at all. Authors of GWT tried to simplify the framework as much as possible and merged data and its representation in one entity - a widget. Note that GWT generally copies features of JavaScript and allows wrapping typical JavaScript functions in Java code. So, this decision might be justified.
Anyway this idea makes GWT simpler. However it has several disadvantages:
To cover all the lacks in standard approach Advanced GWT Components offer easy and reliable solution - data models. Most of library widgets have a least one model and can display the data stored in the model. Current there are several basic interfaces for diffrent kinds of widgets. All the models have the same package org.gwt.advanced.client.datamodel.*.
Interface | Description | Used in Widgets |
---|---|---|
GridDataModel | This is a data model for all library tables and grids. It has many extending interfaces and implementations. Learn API documentation of a particular grid to choose a correct data model for it. | EditableGrid, HierarchicalGrid, TreeGrid |
Editable | This is a data model for all editable (updatable) grids. If the GridDataModel doesn't allow changing data dynamically (immutable model), this extension does. Note that this interface extends the previous one. | EditableGrid, HierarchicalGrid, TreeGrid |
Hierarchical | This data model is usually used to store complex objects, i.e. objects of different types and related to each other like a tree. Interface implementations provide several additional methods to add and remove subobjects. | HierarchicalGrid |
Composite | This data model stores a hierarchy of the same type objects. In comparison with the previous model it doesn't allow adding objects into subtrees if they have different structure in comparison to the parent node. | TreeGrid |
LazyLoadable | Data models implementing this interface allow lazy data loading. It doesn't matter where data is stored at the moment when a widget apply the model. Anyway it will be loaded dynamically when it's requested. Each non-lazy model has a least one lazy prototype. Widgets which can support the first type can also support its lazy "brother" | EditableGrid, HierarchicalGrid, TreeGrid |
Pageable | Pageable data models often required if the large volume of data must be splitted to separate pages. GridDataModel extends this interface and therefore all library grids support paging. Lazily loadable models use paging to load data on page-by-page basis. | EditableGrid, HierarchicalGrid, TreeGrid |
ListDataModel | This is a set of pairs model. It consists of items and each of them is identified by string ID (key) and contains payload (value). It's usually used for complex lists. | ComboBox, SuggestionBox |
Note that there is one important exception: SimpleGrid. This widget is a grid but don't use data models at all. We made it for those developers who are happy with GWT common approch and wants to use advanced view functionality and believes they don't need modeling.
Sometimes it may be reasonable but it's strongly recommended to use libary models and / or develop your own ones because of problems listed above.
The next code listing shows how to create a model and use it:
Object[][] data = new Object[][] { "Text 1", new ListBox(), Boolean.TRUE }; Editable model = new EditableGridDataModel(data); model.addRow(1, new Object[]{"Text 2", new ListBox(), Boolean.FALSE}); model.addColumn(2, new Object[]{Integer.MAX_VALUE});
As a result the model will contain 2 rows and 4 columns. Note that adding column we put only one value in the array. The model detects that a new column array dimension is less than number of rows and puts null values automatically.
Model flexibility might be restricted by a widget that displays the data. In the sample above you can notice that the model takes abstract array of objects, i.e. a matrix. But being used in the EditableGrid and it's extentions it must contain value of the same types in the same columns. Also this widget doesn't allow dynamic columns adding and therefore you may broke the view if add it after the grid was initialized.
Interesting that the model may contain not only plain data but also GWT widgets. It was done to make it copatible with old GWT applications where you might integrate the library and where you probably use simple flex tables.
Lazy data loading sample is shown below:
DataModelCallbackHandler handler = new DataModelCallbackHandler() { public void synchronize(GridDataModel model) { //fill the model with data here } }; LazyLoadable model = new LazyGridDataModel(handler); model.setTotalRowCount(1000); //set a total row count to make lazy paging
The listing creates a new lazily loadable model and defines a callback handler that will be used to put data into this model dynamically. It also sets a total row count to cheat widgets that use this model. Widget renderers will "think" that the model contains more rows than it's really does.
To load the next portion of data or simply refresh it you can use the statement: model.getHandler().synchronize(model).
The next sample illustrates how to create and use ListDataModel:
ListDataModel model = new ComboBoxdataModel(); model.add("Item 1", new IconItem("my-image1.jpg", "Image 1")); model.add("Item 2", new IconItem("my-image2.jpg", "Image 2")); model.add("Item 3", new IconItem("my-image3.jpg", "Image 3"));
The sample creates a new model for the ComboBox and fills it with the keyed items. Each of the items is a labeled image. Note that it doesn't mean that it contains an image itself. It just points to an image URI.