Using Widgets

All the library components extend one class - Widget. This class is a standard basic parent for all GWT widgets, not only for classes of this library. Some widgets may override basic methods containing in this class. Advanced GWT Components is not an exception. For internal purposes it offten provides renamed methods that perform original logic. You can use them in cases when you have to do something that is not overriden by a library class.

Note that you can extend wny widget in the library and override any method since there are no private and final class members excepting internal fields. But it's not recommended because of possible incompatibility troubles that may occur in future versions of the library.

In fact Advanced GWT Components API ensures backward compatibility only for classes, public methods and constants. Even if it is planned to replace a class member with a new solution, old API will be kept "as is" and supported with limitations explained above.

The next sample illustrates how you can invoke one of renamed orginal methods using custom extension of the widget:

new EditableGrid() {
    public Widget getOriginalWidget(int row, int column) {
        return super.getOriginalWidget(row, column);
    }
}.getOriginalWidget(0, 0);
            

This simple sample gives three ideas:

  • the idea on how to use overriden method
  • the idea on how to make it public
  • the idea on how to invoke it

It doesn't mean that you always need to write code like shown above, but probably helps to understand how the library works.

Another question that is reasonable to talk about in this topic is the basic inteface org.gwt.advanced.client.ui.AdvancedWidget. It contains only one method display() and was added to the library because of perfomance improvements.

It's not a secret that GWT renders content dynamically using JavaScript. And actually this solution makes GWT application be slower than alternative server side solutions. Taking into account this fact imagine what could happen if the widgets redrew their content on each widget property change!

To avoid this problem all the widgets implement this interface and redraw their content only if the display() method is invoked. Look at the next sample to understand how it works:

GridPanel panel = new GridPanel()
panel.set... //set something here...
panel.set... //...and here
panel.display();
            

The lines 2 and 3 set panel properties but NOT make it be displayed or redrawn. If you're familiar with Swing you can note that it is similar to JFrame.pack() method.

There are some exceptions from this rule. For instance grid columns resizing works without this method invocation because in fact this opertation changes column styles and doesn't renew content inside cells.

Note that to make your application work faster follow the next simple restrictions:

  • Avoid invoking the display() method more times than it's required, for example, in loops
  • Do NOT call the method after each property setting
  • Do NOT invoke it manually if you have a deal with lazily loadable data models, use locking instead (see below)

Locking is another build-in feature of the library that solves the problem of asynchronous requests. GWT doesn't allow using synchronous RPC calls, this feature is not supported by default API. But in most cases synchronous invocations of remove services is much preferable than asynchronous ones.

Widgets that require synchronous requests (actually any widget that support lazily loadable models) provide methods lock() and unlock(). The idea of these methods is simple. The first one creates an invisible popup panel that prevents all mouse and kayboard events on the page where it's displayed. As soon as a callback response was received the second method must be invoked to hide the panel and unlock all page controls.

You can also find a good sample of locking in the FAQ section.

Additionally to invisible panel displying the unlock() method redraws widget content or parts of content (it depends on what was changed in the data model during request).

It's strongly recommended to use lock / unlock methods instead of direct display() call because the team of the Advanced GWT Components all the time works on rendering perfomance inmrovents and tries to do it in most optimal way.

Modern browsers like FireFox 3.x significantly improved JavaScript machine perfomance but there are cases when even all the solutions described above and super modern browsers don't provide expected speed of rendering. Advanced GWT Components offers mechanism alternative to GWT standard approch - the server side rendering. It means that you can build widget content on server side and it will be displayed allegedly it was dynamically rendered on client side.

Look at the sample that shows how it could be made for grids:

editableGrid.setGridRenderer() {
    new DefaultGridRenderer() {
        public void drawContent(GridDataModel model) {
            myService.getContent(
                new AsyncCallback() {
                    public void onSuccess(Object content) {
                       //put content into the grid cells here using FlexTable.setText() method
              
                       ((Editable)model).update((Object[][])content); //synchronize data model
                    }
                    public void onFailure(Throwable error) {
                       Window.alert("Unexpected error: " + error.getMessage());
                    }
                }
            )
        }
    }
}

editableGrid.display();
            

This sample invokes the myService remotely and draws grid content on success. Sometimes it allows to achive very good results.

Note that it doesn't matter how you render widgets. All advanced features like cells editing and validation are supported by both approaches. Everything you should always keep in mind is that the data model MUST be synchronized with the view. In case of client rendering it happens automatically. In other cases you should do it manually as shown in the sample.

There is one important exception to the thoughts explaned in this topic. It's the SimpleGrid widget. Being developed in 1.4.5 it was designed especially for those individuals who don't need advanced features and preferes standard GWT approaches.

SimpleGrid is a basic class for all the grids of the library and doesn't provide features like:

  • data models
  • editable (updatable) cells
  • rows selection
  • perfomance improvements (server side rendering, lazy loading, display(), etc)

On the other hand the SimpleGrid supports <thead> element, columns resizing and body scrolling. This widget replaces the AdvancedFlexTable and overrides some methods to fix some look & feel issues that occur in the parent class. The grid displays content as soon as it's created and data added into the cells.

If you are a supporter of classic approach you can you this widget to achive greater flexibility and implement necessary operations manually as you want.