View Full Version : [FNR][1.2.2] RootTreeTableItem constructor contains rendered=true causing NPE

30 Apr 2009, 6:01 AM
The code:

package com.mycompany.prototype.gwtprototype.client;

import java.util.ArrayList;

import com.extjs.gxt.ui.client.binder.TreeTableBinder;
import com.extjs.gxt.ui.client.data.BaseTreeModel;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.widget.TabItem;
import com.extjs.gxt.ui.client.widget.TabPanel;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.treetable.TreeTable;
import com.extjs.gxt.ui.client.widget.treetable.TreeTableColumn;
import com.extjs.gxt.ui.client.widget.treetable.TreeTableColumnModel;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;

public class GwtPrototype implements EntryPoint {

private TreeStore<BaseTreeModel> store;
BaseTreeModel tm;

public void onModuleLoad() {
Viewport v = new Viewport();
TabPanel tp = new TabPanel();
TabItem ti2 = new TabItem("Tab 2");
tp.add(new TabItem("Tab 1"));

final TreeTableColumn name = new TreeTableColumn("name", "Name");
final ArrayList<TreeTableColumn> columnList = new ArrayList<TreeTableColumn>();

final TreeTableColumnModel cm = new TreeTableColumnModel(columnList);
TreeTable tt = new TreeTable(cm);
store = new TreeStore<BaseTreeModel>();
TreeTableBinder<BaseTreeModel> binder = new TreeTableBinder<BaseTreeModel>(tt, store);
tm = new BaseTreeModel();
tm.set("name", "My name");
store.add(tm, false);

Button b = new Button("Update");
b.addSelectionListener(new SelectionListener<ComponentEvent>(){

public void componentSelected(ComponentEvent ce) {
tm.set("name", "my new name");
}store.update throws an NPE when you click the button.
The problem:
We are using a treetable for a chat-like function, which is initially hidden in a not-yet-rendered tab. Whenever we add items to the tree (new remote user logs on), we call expandall on the tree after adding them. TreeTable.expandall() calls root.setExpanded(), which checks if the root item is rendered, and if it is it then goes through and renders all its children. The problem is that RootTreeItem has rendered=true in its constructor, so it thinks it is rendered, therefore "renders" all its children, even though their tree is not rendered. If you subsequently call store.update on an item in the store, it thinks it is rendered, so in TreeTableItem.setValue(), the if (rendered) passes, and treeTable.getView().renderItemValue() is called, which has treeTable as null, therefore the line String s = treeTable.getRenderedValue(); in TreeTableView.renderItemValue() throws a null pointer exception.

You can see the resulting NPE in this post:

30 Apr 2009, 8:52 PM
Fixed in SVN.