Sencha Inc. | HTML5 Apps

Blog

Ext GWT 3.0 State API

April 05, 2012 | Darrell Meyer

The Ext GWT 3.0 State API provides the ability to persist state information. The API supports saving state data to different persistence providers. These include providers based on cookies and HTML5 local storage.

The data is saved and retrieved as a map from string keys to string values. State data is serialized to strings and deserialized to objects via the bean-like interfaces of GWT AutoBeans. This data is retrieved asynchronously, and this allows for asynchronous providers such as those that communicate via RPC.

Differences with Ext GWT 2.0

With 2.0, Components work directly with the StateManager, restoring and saving state directly as part of the Component lifecycle. With 3.0, this functionality was moved out of Component and is now managed via state handlers (AbstractStateHandler). 3.0 Component has two state related methods:

StateManager & Providers

State API

The StateManager is a singleton that delegates the action of saving and retrieving data to its Provider. Ext GWT ships with two concrete Provider implementations and an abstract base on which to build your own:

Window State Example

Example URL: http://staging.sencha.com:8080/examples-dev/#ExamplePlace:windowstate

This article demonstrates how to use the State API. We’ll create a new example that uses the State API to maintain state. In this example, Window components will remember their last size and position when closed. If a user returns to the example and opens a window, that window will be initialized to its previous size and position.

You can test the code by opening a window. Close the window after moving and resizing it. Then, refresh the browser and open the same window again. The size and position should match the window when it was last closed.

Define Data Structure & AutoBeanFactory

First, we’ll define the data we want to persist using these interfaces:

public interface ExampleAutoBeanFactory extends DefaultStateAutoBeanFactory {

  AutoBean<WindowsState> windowsState();

  AutoBean<WindowState> windowState();

}
public static interface WindowState {

  int getHeight();

  int getWidth();

  int getX();

  int getY();

  void setHeight(int height);

  void setWidth(int width);

  void setX(int x);

  void setY(int y);

}

The data will be a list of WindowState instances stored in a map. This map will be keyed by state ID. The state ID is a unique key given to each window in the example using the setStateId method defined in Component.

Next, we define our AutoBean factory. Note that we subclass DefaultStateAutoBeanFactory. This is necessary to take advantage of the Ext GWT State code.

public interface ExampleAutoBeanFactory extends DefaultStateAutoBeanFactory {

  AutoBean<WindowsState> windowsState();

  AutoBean<WindowState> windowState();

}

Now that we’ve defined our data and factory, we need to tell the StateManger code to use our AutoBean factory and not the Ext GWT default. We do this by setting the appropriate configuration property in our module XML file:

<set-configuration-property name="GXT.state.autoBeanFactory" value="com.sencha.gxt.explorer.client.misc.WindowStateExample.ExampleAutoBeanFactory" />

State Handler

Next, we create the class that will load and save our state information. This is done by subclassing AbstractStateHandler.

public class StateExampleHandler extends AbstractStateHandler<WindowsState, WindowStateExample> {

  public StateExampleHandler(WindowStateExample example, String key) {
    super(WindowsState.class, example, key);
  }

  @Override
  public void applyState() {
    Map<String, WindowState> windows = getState().getWindowState();
    if (windows == null) {
      windows = new HashMap<String, WindowState>();
      getState().setWindowState(windows);
    }
  }

}

AbstractStateHandler has two type parameters. The first represents the AutoBean state type (WindowState). The second represents the target object that will use this state information (WindowStateExample).

When we instantiate the handler, we pass the target object and a key to identify the saved and retrieved state.

In the applyState method, we simply ensure that we have our state map instantiated. We will retrieve the actual state and use it in other code.

State handlers supports 4 event types: BeforeRestoreState, RestoreState, BeforeSaveState and SaveState.

Opening a Window

Before a window is opened, we check to see if that window has any state information. If it does, we initialize the window before it is shown.

private void onBeforeShowWindow(Window window) {
  if (stateHandler.getState() != null && stateHandler.getState().getWindowState() != null) {
    String stateId = window.getStateId();
    WindowState state = stateHandler.getState().getWindowState().get(stateId);
    if (state != null) {
      window.setPixelSize(state.getWidth(), state.getHeight());
      window.setPagePosition(state.getX(), state.getY());
    }
  }
}

Hiding a Window

private void onBeforeHideWindow(Window window) {
  String stateId = window.getStateId();

  WindowsState state = stateHandler.getState();
  Map<String, WindowState> windows = state.getWindowState();
  WindowState windowState = windows.get(stateId);
  if (windowState == null) {
    windowState = factory.windowState().as();
    windows.put(stateId, windowState);
  }

  Rectangle rect = window.getElement().getBounds();

  windowState.setHeight(rect.getHeight());
  windowState.setWidth(rect.getWidth());
  windowState.setX(rect.getX());
  windowState.setY(rect.getY());

  stateHandler.saveState();
}

Summary

In this article, we introduced the Ext GWT 3.0 State API by working through an example. The example is running here, and you can view the source code of the example by clicking the Source tab below the example. One note, the example and event support was recently added to the state handlers and is not in the last public release (beta 2).

This particular example uses a cookie provider to persist the state data. You use use a developer tool such as Firebug to inspect the request to see the cookies that are being set by the example. The provider can be easily changed to use a different persistence strategy such as a server side RPC provider or an HTML5 local storage provider.

There are 6 responses. Add yours.

Piotr Kosmowski

2 years ago

Very nice, thank you smile

Ronan Quillevere

2 years ago

I have been watching the HTML5, CSS3 ... video from SC2011 recently. Nice to see that the HTML5 state functionnality is now supported in EXT GWT with cookie/html5 implementations.

Loiane Groner

2 years ago

Nice article!
Hope to see more articles about GXT 3 here!

Travis Webb

2 years ago

Very well done. Keep articles on new features coming. We are eager to find out what else GXT 3 has in store and, most importantly, how to make use of it. Thanks.

ipad to mac transfer

2 years ago

thanks for your post, would you post more article about GXT 3 here for sharing with more people.

Arul

2 years ago

Very nice article

Comments are Gravatar enabled. Your email address will not be shown.

Commenting is not available in this channel entry.