Posted in gwt, Software Engineering, Uncategorized

GWT CellTable Example (Using AsyncDataProvider)

http://www.mytechtip.com/2010/11/gwt-celltable-example-using_8168.html

GWT CellTable Example (Using AsyncDataProvider)

GWT version 2.1 has finally been released with the anticipated business level data presentation widgets and other interesting features. CellTable is one of the new widgets that supports pagination. Therefore, there no need to usePagingScrollTable in the gwt incubator or implementations in other third-party libraries.

From the Google official document on how to use data presentation widgets, you can get some examples of using these cell widgets including CellTable. It also includes a simple example of using CellTable with SimplePager to implement pagination. That example uses ListDataProvider which requires all the data that needs to be paged to be set at the client (browser) side. However, in realty, the common practice is to load only one page of data from the server (mostly pulled from a database) to the browser in order to save the bandwidth and improve the response time.

Of course the document indicates there are ways to implement the asynchronized page data loading from remote server.

To illustrate how to use AsyncDataProvider, I modified a simple example from GWT below.

Please note the example do not actually calls the server to get the data. It should be quite easy to modify the example to do so as illustrated in the next code snippet.

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import com.google.gwt.cell.client.DateCell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.AsyncDataProvider;
import com.google.gwt.view.client.HasData;

public class CellTableExample implements EntryPoint {

/**
   * A simple data type that represents a contact.
   */
private static class Contact {
private final String address;
private final Date birthday;
private final String name;

public Contact(String name, Date birthday, String address) {
this.name = name;
this.birthday = birthday;
this.address = address;
}
}

/**
   * The list of data to display.
   */
@SuppressWarnings("deprecation")
private static final List<Contact> CONTACTS = Arrays.asList(
new Contact("John", new Date(80, 4, 12), "123 Abc Avenue"),
new Contact("Joe", new Date(85, 2, 22), "22 Lance Ln"),
new Contact("Tom", new Date(85, 3, 22), "33 Lance Ln"),
new Contact("Jack", new Date(85, 4, 22), "44 Lance Ln"),
new Contact("Tim", new Date(85, 5, 22), "55 Lance Ln"),
new Contact("Mike", new Date(85, 6, 22), "66 Lance Ln"),
new Contact("George", new Date(46, 6, 6),"77 Lance Ln"));

public void onModuleLoad() {
// Create a CellTable.
final CellTable<Contact> table = new CellTable<Contact>();
// Display 3 rows in one page
table.setPageSize(3);

// Add a text column to show the name.
TextColumn<Contact> nameColumn = new TextColumn<Contact>() {
@Override
public String getValue(Contact object) {
return object.name;
}
};
table.addColumn(nameColumn, "Name");

// Add a date column to show the birthday.
DateCell dateCell = new DateCell();
Column<Contact, Date> dateColumn = new Column<Contact, Date>(dateCell) {
@Override
public Date getValue(Contact object) {
return object.birthday;
}
};
table.addColumn(dateColumn, "Birthday");

// Add a text column to show the address.
TextColumn<Contact> addressColumn = new TextColumn<Contact>() {
@Override
public String getValue(Contact object) {
return object.address;
}
};
table.addColumn(addressColumn, "Address");

// Associate an async data provider to the table
// XXX: Use AsyncCallback in the method onRangeChanged
// to actaully get the data from the server side
AsyncDataProvider<Contact> provider = new AsyncDataProvider<Contact>() {
@Override
protected void onRangeChanged(HasData<Contact> display) {
int start = display.getVisibleRange().getStart();
int end = start + display.getVisibleRange().getLength();
end = end >= CONTACTS.size() ? CONTACTS.size() : end;
List<Contact> sub = CONTACTS.subList(start, end);
updateRowData(start, sub);
}
};
provider.addDataDisplay(table);
provider.updateRowCount(CONTACTS.size(), true);

SimplePager pager = new SimplePager();
pager.setDisplay(table);

VerticalPanel vp = new VerticalPanel();
vp.add(table);
vp.add(pager);

// Add it to the root panel.
RootPanel.get().add(vp);
}
}

To make remote calls to retrieve table data from the server, The code snippet should look like the following.

// Associate an async data provider to the table
AsyncDataProvider<Contact> provider = new AsyncDataProvider<Contact>() {
@Override
protected void onRangeChanged(HasData<Contact> display) {
final int start = display.getVisibleRange().getStart();
int length = display.getVisibleRange().getLength();
AsyncCallback<List<Contact>> callback = new AsyncCallback<List<Contact>>() {
@Override
public void onFailure(Throwable caught) {
Window.alert(caught.getMessage());
}
@Override
public void onSuccess(List<Contact> result) {
updateRowData(start, result);
}
};
// The remote service that should be implemented
remoteService.fetchPage(start, length, callback);
}
};

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s