Home » Ext-GWT (GXT), Featured, GWT, Home

Using the Ext-GWT (GXT) MVC Framework

7 October 2009 1,529 views One Comment

In this article I try to give a brief tutorial of how to use the
GXT (Ext-GWT) MVC. Using GWT 1.7 and GXT 2.0.1.

Having worked out what was going on in GXT MVC I was able to put
together a simple sample app of my own. The example I choose was an app
to to retrieve and display the current stock price of Google. To keep things simple the backend is based on an example from the GreatWebGuy website.

The diagram below shows the key components used in the GXT MVC
framework and how they talk to each other:

gxtmvcEvents

First I defined the events the application will use. These are defined
in a class as static fields which are instances of the EventType class.

1
2
3
4
5
6
7
8
public class StockAppEvents
{
public static final EventType Init = new EventType();
public static final EventType Error = new EventType();
public static final EventType StockPriceUpdated = new EventType();
public static final EventType UIReady = new EventType();
public static final EventType StockPriceUpdateRequested = new EventType();
}

The Controller

A controller is responsible for handling events. It registers to receive a notification from the dispatcher each time an event of a specified type occurs. It can then make changes to the model and/or forward the event on to the view it is responsible for in order to update the display for example.

Controllers register the events they are interested in their constructors. This is achieved by using the registerEventTypes method which takes an AppEvent as an argument.

For example if a controller was required to handle to perform an action when the StockPriceUpdated event occurred it would look like this:

1
2
3
4
5
6
7
8
9
public class StockPriceController extends Controller
{
...
public StockPriceController()
{
registerEventTypes(StockAppEvents.StockPriceUpdated);
}
...
}

In order to be able to handle events a controller is required to implement the handleEvent method. This method defines how the controller processes an event notification received from the dispatcher.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class StockPriceController extends Controller
{
...
@Override
public void handleEvent(AppEvent event)
{
EventType eventType = event.getType();
if (eventType.equals(StockAppEvents.StockPriceUpdated))
{
onStockDataUpdated(event);
}
}
...
}

You also need to specify the view that the controller is responsible for in order to be able to forward events to it. This is done in the initialise method.

1
2
3
4
5
6
7
8
9
10
11
public class StockPriceController extends Controller
{
...
@Override
public void initialize()
{
super.initialize();
stockPriceView = new StockPriceView(this);
}
...
}

If a controller need to forward event onto the view for processing you can use the forwardToView method.

1
2
3
4
5
6
7
8
9
public class StockPriceController extends Controller
{
...
private void onStockDataUpdated(AppEvent event)
{
forwardToView(stockPriceView, event);
}
...
}

The View

The view provides the interface with the user. It is responsible for displaying data and responding to user actions by creating events. When creating a view the view’s controller must be defined in its constructor.

1
2
3
4
5
6
7
8
public class StockPriceView extends View
{
public StockPriceView(Controller controller)
{
super(controller);
}
...
}

It also is required to implement the handleEvents method in the same way as the controller.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class StockPriceView extends View
{
...
@Override
protected void handleEvent(AppEvent event)
{
EventType eventType = event.getType();
if (eventType.equals(StockAppEvents.StockPriceUpdated))
{
onStockPriceUpdated(event);
}
}
...
}

The view does not communicate directly with its controller; instead it forwards events to the dispatcher by calling the static Dispatcher.forwardEvent method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class StockPricePortlet extends Portlet
{
...
public StockPricePortlet()
{
btnUpdate.addSelectionListener(new SelectionListener()
{
public void componentSelected(ButtonEvent ce)
{
Dispatcher.forwardEvent(StockAppEvents.StockPriceUpdateRequested);
}
});
...
}
...
}

The Dispatcher

The dispatcher is used to notify controllers that an event has occurred.

In order to receive any events a controller needs to first be registered with the dispatcher. This is achieved by adding a controller to the dispatcher using the addController method and would typically be done on module load.

1
2
3
4
5
6
7
8
9
10
public class StockApp implements EntryPoint
{
  public void onModuleLoad()
  {
  ...
    Dispatcher dispatcher = Dispatcher.get();
    dispatcher.addController(new StockPriceController());
  ...
  }
}

Similarly controllers can stop receiving events using the removeContoller method. A list of controllers currently registered with the dispatcher can be retrieved using the getControllers method.

In GXT the dispatcher is a singleton, that is only one instance of it exists in the application. In order to fire an event there are two options: The first is to retrieve the dispatcher instance using the static Dispatcher.get() static and then call the resultant dispatchers dispatch method. The alternative is to call the static Dispatcher.forwardEvent. Both methods do the same thing.

1
2
3
4
5
6
7
8
9
public class StockApp implements EntryPoint
{
  public void onModuleLoad()
  {
  ...
    dispatcher.dispatch(StockAppEvents.Init);
  ...
  }
}

The only difference I can see is that forwardEvent has a version that allows you to specify that an event is a history event. I personally favour using the static Dispatcher.forwardEvent version from views as it is more convenient.

When calling either the dispatch or forwardEvent methods the code makes sure that the controllers are properly initialized. It then notifies only the controllers that have specifically registered to receive events of that type (using the registerEventTypes in their constructor) that the event has occurred using the fireEvent method.

It is possible to call the fireEvent method directly however I cannot see any reason to use this over the forwardEvent or dispatch method. In this case all controllers would receive the event whether or not they had registered to receive events of that type.

The Application

I hope this gives you some idea of how to get started with a GXT MVC application.

The source code for my test application is available here:

StockApp.zip (10Kb)

1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 4.50 out of 5)
Loading ... Loading ...

One Comment »

  • Mark Beaty said:

    Nice intro to GXT MVC. One important detail you omitted is that the order in which controllers are added to the Dispatcher, in your EntryPoint class, is significant. The dispatcher will always interrogate controllers in the order you have added them. This might seem obvious if you have a clear understanding of GXT MVC, but not so obvious otherwise. Depending on your app structure, order may matter or it may not. Just a good little detail to keep in mind.

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.