GWT-Ext automatically resize GridPanel columns

The problem here is that GWT-Ext framework has no API or support for automatically resizing of the GridPanel columns based on the content of the grid cells.

FORTUNATELY THERE IS A SOLUTION ! see it below what we need to do:

1) The resizing function.
2) Preparing the grid.

1. The resize static function
We have to define a static resize function that will work on any GridPanel or EditorGridPanel. Here's the code:
/**
* Automatically adjust Grid column widths. It gets the total of the
* adjustable columns and exclude fixed width columns from the target width.
*/
public static void resizeColumns(final Store gridStore,
final ColumnModel gridColsModel) {
if (gridStore == null || gridColsModel == null) {
return;
}
final BaseColumnConfig[] colCfgs = gridColsModel.getColumnConfigs();
if (colCfgs == null) {
return;
}
final int nbRows = gridStore.getCount();
if (nbRows > 0) {
final Record[] records = gridStore.getRecords();
/* Resize each column according the cell values */
for (int i = 0; i < colCfgs.length; i++) {
if (colCfgs[i] instanceof ColumnConfig) {
final ColumnConfig cfg = (ColumnConfig) colCfgs[i];
int colW = cfg.getHeader().length();
for (int r = 0; r < nbRows; r++) {
final String val = records[r].getAsString(cfg
.getDataIndex());
if (val != null && val.length() > colW) {
colW = val.length();
}
}
/* here's the weak of logic (6px for each char) */
gridColsModel.setColumnWidth(i, colW * 6 + 20);
}
}
}
}

2. Prepare the grid
For having this function called automatically we need to register 2 listeners:
  • one for the grid's store
  • second for the grid's wrapper (parent) panel
NOTES:
  1. Don't set the "auto fill" for the grid's view and don't set the auto-width column.
  2. Another big condtion is to keep the reference to the grid's ColumnModel object. This is used in the resizing function, and we cannot use the "grid.getColumnModel()" function because the rezult of this is a brand new instance, which doesn't have the list of ColumnConfig objects.

2.1 Grid store
When we create the GridPanel and set up its store we can register a StoreListener for this store.

Store gridStore = new Store (...);
....
/* need to preserve this object: gridColumnsModel */
ColumnModel gridColumnsModel = new Columnmodel (...);
....
gridStore .addStoreListener(new StoreListenerAdapter(){
public void onLoad(Store store, Record[] records) {
resizeColumns(store, gridColumnsModel);
}
});


2.2. Grid parent panel
When we add the grid to its parent panel (container) we have to register a "resize listener" for the parent.

grid.getView().setAutoFill(false);
grid.setStore(gridStore);
...
gridWrapperPane.add (grid);


gridWrapperPane.addListener(new ContainerListenerAdapter(){
@Override
public void onResize(BoxComponent component, int adjWidth, int adjHeight, int rawWidth, int rawHeight) {
if (grid != null) {
resizeColumns(grid.getStore(), gridColumnsModel);
}
}
});

DONE! now you don't need to worry about the grid columns size.
Enjoy it!



2 comments:

  1. Thank you, very userful,

    i attached your static method directly to the GridPanel:

    grid.addListener(new ContainerListenerAdapter() {

    @Override
    public void onRender(Component component) {
    resizeColumns(grid.getStore(), columnModel);
    }});

    ReplyDelete