ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Working with the Google Web Toolkit
Pages: 1, 2, 3, 4, 5

Building the Table

Our table class here just does a pretty simple thing: draw a table from a TableDataSource implementation, then toggle a stylesheet class on the selected row so we can highlight it. To do this, we are going to extend the GWT's FlexTable class. This is a class that represents an HTML table, but lets the author create table cells on the fly. To populate our table we are going to use a very simple TableDataSource that we can fetch from our RPC servlet. For now, lets just look at the code.

The first step is to build your service interface. Ours is pretty simple:

public interface DataService extends RemoteService {    
    public Person[] getData();
}

Next, we need to create an Async interface for the service. This is done entirely with naming conventions. You need to create an interface that matches the service interface and all methods. However, instead of return types, every method is void and the last argument is an AsyncCallback implementation, thusly: public void myMethod( Param p..., AsyncCallback callback). Finally, the interface class name should match the RemoteService interface name, postfixed with Async.

For our simple service, it looks like this:

public interface DataServiceAsync {
    public void getData(AsyncCallback callback);   
}

Next, you need your service implementation. This needs to extend the GWT's RemoteServiceServlet servlet and implement your service interface.

public class DataServlet 
    extends RemoteServiceServlet implements DataService {
    
    public Person[] getData(){
    //...
    }
}

Whew. Almost there. Now we want to add the servlet to both the web.xml (so it will be there when we deploy the war) and we want to add a declaration to our Table.gwt.xml file. This second entry tells the GWTShell to load the servlet and also mounts it in the testbed Tomcat and generates client stubs for you.

<servlet path="/DataService" 
    class="com.totsp.gwt.server.DataServlet"/>

Now, we are ready to deal with the call itself. GWT only supports Asynchronous calls. There are a number of technical reasons for this, notably that the most obvious path to do a synchronous call would be to spin waiting for the response. Unfortunately, many browsers will not actually fire the XmlHttpRequest event until said spinning is done. But hey, this is Ajax, not Sjax. Right?

Now we add the getData() method to our EntryPoint class. To do this, we need to get a DataServiceAsync implementation from the GWT class, then create an AsyncCallback handler. This is a simple interface that just has an onSuccess() and onFailure() method to handle the return state of the callback.

private void getData(){
    DataServiceAsync dataService = 
       (DataServiceAsync) GWT.create( DataService.class );
    ServiceDefTarget endpoint = (ServiceDefTarget) dataService;
    endpoint.setServiceEntryPoint("/DataService");
    dataService.getData(new AsyncCallback(){
        public void onSuccess(Object result) {
            table.setSource( 
                new SimpleDataSource( (Person[]) result ) );
        }

        public void onFailure(Throwable caught) {
            Window.alert("Unable to get data from server: "
                +caught.toString());
        }

    });

}

Notice the unfortunate cast to ServiceDefTarget. Why they couldn't have made a GWT.create(Class clazz, String url) method is a bit beyond me, but you gotta do it.

Now, we simply call the setSource() method on our table object and voila, the table will render itself with the new data. Also notice that our objects that move from the server to the JavaScript world have to implement IsSerializable. This also supports arrays and basic collections, although in my experience, collections are sometimes sketchy and may give you cryptic errors. It's best to avoid them where possible for the moment.

Pages: 1, 2, 3, 4, 5

Next Pagearrow