Blog Archives

Events

There are a lot of events within GXT. I have created a class-overview.

Sometimes I ask myself, which event I will get from a widget and which listener I have to use.

Follow these steps:

  1. Go to the documentation of the class, which is the event source (i.e. Grid)
  2. Look for the right event (like CellClick)
  3. You will see, that CellClick generates a GridEvent. GridEvents can have a generic type, which is related to the ModelData displayed within the grid.

  4. Go to enumeration Events. Choose the right EventType (Events.CellClick)
  5. There are also events like On***. These events are DOM events (browser events). You can also listen to OnClick, but you won’t get high level information like ModelData.

  6. Implement a listener class, which implements the interface Listener
  7. Because the CellClick event type generates a GridEvent, our listener should implement Listener<GridEvent>. There are some special listener like DNDListener which provide additional empty methods for some event types related to special field (like drag&drop). But it is always possible to implement the Listener interface and split the events on their types without any helper classes.

TreeStore<ModelData> store = new TreeStore<ModelData>();
// listen to all events
store.addStoreListener(new SpecialStoreListener());
// or 
store.add(Events.Store.Add, new BaseStoreListener());
store.add(Events.Store.BeforeClear, new BaseStoreListener());
store.add(Events.Store.Sort, new BaseStoreListener());
public class SpecialStoreListener extends StoreListener<ModelData> {
   // override the provided methods as needed
}
public class BaseStoreListener implements Listener<StoreEvent<ModelData>> {
   public void handleEvent(StoreEvent<ModelData> evt) {
      if (e.getType() == Store.Add) {

      } else if (e.getType() == Store.BeforeClear) {

      } else if (e.getType() == Store.Sort) {

      }
   }
}

As you can see, you will have always methods to register a special listener (i.e. store.addStoreListener() instead of store.addListener()). But it is not documented, which class can use such a listener. You have to look into the outline of each class. I have created a listener overview, so you can check the supported EventTypes for each listener.

Filter selection within a TreeGrid

Every node within a TreeGrid can be selected. But sometimes you only need the leafs or only a few of them. It is possible to filter the selection later, just before you execute an action on the selected nodes. But the better way is to prevent a selection on obsolete nodes. Use a custom SelectionModel for that.

public class CustomSelectionModel extends GridSelectionModel<ModelData> {

	public CustomSelectionModel() {
		addListener(Events.BeforeSelect, new NoSelectionListener());
	}

	private class NoSelectionListener
		implements Listener<SelectionEvent<ModelData>> {

		@Override
		public void handleEvent(SelectionEvent<ModelData> se) {
			ModelData model = se.getModel();
			if (model instanceof Something) {
				se.setCancelled(true);
			}
		}

	}
}

You can also use properties of the model to make a decision, but sometimes you can simply ask for the instance type (i.e. folders and files).

Bold font on TreeGrid

You can have a bold font on a TreeGrid. Create your own renderer and enhance the HTML returning by the renderer.

private class BoldGridCellRenderer extends TreeGridCellRenderer<ModelData> {
	protected String getText(TreeGrid<ModelData> grid, ModelData model, String property, int rowIndex, int colIndex) {
		return "<span style=\"font-weight:bold\">" + super.getText(grid, model, property, rowIndex, colIndex) + "</span>";
	}
}

Add the renderer to your tree column (use always TreeGridCellRenderer for that column!).

ColumnConfig name = new ColumnConfig("name", "Name", 300);
name.setRenderer(new BoldGridCellRenderer());

DateFormat

You can not use java.text.DateFormat within GWT/GXT applications. The class is not supported by the Google runtime environment. But there is a similar class com.google.gwt.i18n.client.DateTimeFormat which is useable:

DateTimeFormat dFormat = DateTimeFormat.getFormat("dd.MM.yyyy");
String date = dFormat.format(new Date());

DateTimeFormat tFormat = DateTimeFormat.getFormat("HH:mm:ss");
String time = tFormat.format(new Date());

This can be used within GridCellRenderer or ColumnConfig within a ColumnModel.

ColumnConfig config = new ColumnConfig("column", "Column", 100);
config.setDateTimeFormat(dFormat);

Icons

To create an icon you can use

AbstractImagePrototype icon = IconHelper.create("path/to/png");

Within a TreeGrid it is possible to use a ModelIconProvider

TreeGrid<ModelData> grid = new TreeGrid<ModelData>(store, columnModel);
grid.setIconProvider(new MyIconProvider());

The provider can return an icon for different situations (like expanded or collapsed nodes, some special node types).

public class MyIconProvider implements ModelIconProvider<ModelData> {

   private final TreeGrid<ModelData> grid;

   public MyIconProvider(TreeGrid<ModelData> grid) {
      this.grid = grid;
   }

   public AbstractImagePrototype getIcon(ModelData model) {
      if (model instanceof Something) {
         return IconHelper.create("img/something.png");
      }
      
      if (grid.isExpanded(model)) {
         return IconHelper.create("img/folder-open.png");
      } else {
         return IconHelper.create("img/folder-close.png");
      }
   }
}

Resize your application within the browser

You can resize your application automatically within your browser window. Use a Viewport:

Viewport vp = new Viewport();
vp.setLayout(new FitLayout());
FitData layoutData = new FitData(5,5,5,5);
vp.add(new ContentPanel(), layoutData);
RootPanel.get().add(vp);

You should also set FitLayout to fit the ContentPanel of your application within the browser window.

Tooltips within Grid

If you need tooltips within a grid you should create your own GridCellRenderer.

public class MyData extends BaseModelData {
   public MyData(String name, Date date) {
      set("name", name);
      set("date", date);
   }
}

public class MyPanel extends ContentPanel {
   public MyPanel() {
      // ...
      ListStore store = new ListStore();
      Grid grid = new Grid(store, new MyColumnModel());
      // ...
      add(grid);
      new QuickTip(grid);  // don't forget it!
   }
}

public class MyColumnModel extends ColumnModel {
   public MyColumnModel() {
      super(new ArrayList());

      // our ModelData has two properties: name and date
      ColumnConfig aCol = new ColumnConfig("name", "Name", 300);
      aCol.setRenderer(new NameRenderer());
      configs.add(aCol);

      ColumnConfig bCol = new ColumnConfig("date", "Date", 100);
      bCol.setRenderer(new DateRenderer());
      configs.add(bCol);
   }

   private class NameRenderer implements GridCellRenderer {
      public Object render(MyData model, String property, ColumnData config, int rowIndex, int colIndex, ListStore store, Grid grid) {
         return "<div>" + model.get(property) + "</div>";
      }
   }

   private class DateRenderer implements GridCellRenderer {
      public Object render(MyData model, String property, ColumnData config, int rowIndex, int colIndex, ListStore store, Grid grid) {
         String date = DateTimeFormat.getFormat("dd.MM.yyyy").format(model.get("date"));
         return "<div qtitle=\"Date\" qtip=\"a date with format dd.MM.yyyy\">" + date + "</div>";
      }
   }
}

We can return HTML code from the renderer, which has “qtitle” and “qtip” attributes, which are used by the QuickTip instance.