ExtGWT: NullPointerException in case of adding items into TreePanel

We’re using ExtGWT(GXT) of version 2.0.1 as an addition to the standard GWT capabilities.

So we have a tree panel(com.extjs.gxt.ui.client.widget.treepanel.TreePanel) which is used to display hierarchy. Everything worked fine until the recent changes. The interesting things began happening once we’ve moved sorting of data to the UI layer. Once we were trying to add more than one node – internal ExtGWT exception occurred:

java.lang.NullPointerException: null
at com.extjs.gxt.ui.client.widget.treepanel.TreePanel.getChildModel(TreePanel.java:963)

at com.extjs.gxt.ui.client.widget.treepanel.TreePanel.update(TreePanel.java:1406)
at com.extjs.gxt.ui.client.widget.treepanel.TreePanel.onAdd(TreePanel.java:1031)
at com.extjs.gxt.ui.client.widget.treepanel.TreePanel$1.storeAdd(TreePanel.java:280)

at com.extjs.gxt.ui.client.store.TreeStore.doInsert(TreeStore.java:792)
at com.extjs.gxt.ui.client.store.TreeStore.insert(TreeStore.java:493)
at com.extjs.gxt.ui.client.store.TreeStore.add(TreeStore.java:163)

After trying to understand why this happens – I have detected the source of the problem. Once you’re trying to call com.extjs.gxt.ui.client.store.TreeStore.add(List, boolean) method to add items to the tree panel – com.extjs.gxt.ui.client.store.TreeStore.doInsert(TreeModel, List, int, boolean, boolean) method is called. If we’ll look into this method we’ll see:

if (storeSorter != null) {
for (TreeModel child : children) {

fireEvent(Add, evt);
}
} else {

fireEvent(Add, evt);
}

So in case if you have specified sorter – the event is sent for every root node added. If you don’t specify sorter – single event for the whole bunch of root nodes.
Firing Add event causes TreePanel to register item as a node in hashmap and redraw itself. And it appears that dis-synchronization between TreePanel cache and TreeModel occurs and this causes NullPointerException on the second node.

In our case the following workaround allowed us to eliminate the problem:

// Getting actual sorter and storing it.
final StoreSorter sorter = getStoreSorter();
// Disabling sort.
setStoreSorter(null);
// Adding items
add(children, true);
// Restoring tree panel sorter
setStoreSorter(sorter);