I can't understand that part, neither trying the showcase examples.
I'm using an extension of AsyncDataProvider to bind my tree to RPC service. Here's my method:
public <T> NodeInfo<?> getNodeInfo(T value) {
/*
if (value instanceof Categoria) {
dataProvider.setCurrentParent((Categoria)value);
}
*/
return new DefaultNodeInfo<Categoria>(dataProvider, new CategoriaCell());
}
"currentParent" is my stuff: except for (null => root) values, I set the parent to pass via RPC to my service. Actually, in my widget code:
dataProvider = new CategorieTreeDataProvider() {
@Override
protected void onRangeChanged(HasData<Categoria> display) {
updateTree(getCurrentParent());
}
};
private void updateTree(Categoria categoria) {
rpcService.getCategorie(categoria, new AsyncCallback<Categoria[]>() {
@Override
public void onSuccess(Categoria[] result) {
dataProvider.updateRowCount(result.length, true);
dataProvider.updateRowData(0, Arrays.asList(result));
}
@Override
public void onFailure(Throwable caught) {
Window.alert(caught.toString());
}
});
}
My rpc-server code, however, is working as expected:
@Override
public Categoria[] getCategorie(Categoria parent) {
List<Categoria> categoryList = categorieDao.listByProperty("parent", parent);
for (Categoria c : categoryList) {
if (categorieDao.listByProperty("parent", c).size() == 0) {
c.setLeaf(true);
}
}
return categoryList.toArray(new Categoria[0]);
}
**Then I add some data to my Categories: 'GrandFather', 'Father' and 'Son'.
Unfortunately, after loading my widget, I see:
The grandfather correctly, with his "+" how expected;
Then I click it and...
The grandfather disappear and I see 'Father' with his '+'
same for father -> son
I suspect the bug is in updateRowCount / updateRowData usage.**
Any ideas?
The getNodeInfo is called whenever you open a node so you have to create distinct DataProvider for each of the nodes's childs.
public <T> NodeInfo<?> getNodeInfo(T value) {
if (value == null) {
return new DefaultNodeInfo<Category>(dataProvider, new CategoriaCell());
}
else if (value instanceof Categoria) {
Category category = (Category)value;
return new DefaultNodeInfo<Grandfather>(new ListDataProvider<Grandfather>(category.getGrandFathers()),new GrandFatherCell());
}
else if (value instanceof Grandfather) {
Grandfather grandfather = (Grandfather)value;
return new DefaultNodeInfo<Father>(new ListDataProvider<Father>(granfather.getFathers()),new FatherCell());
}
else if (value instanceof Father) {
//same as above but with fathers.
}
}
The category.getGrandFathers() function can for example do a RPC request to the server or just return the list if you retrieve everything in one RPC request.
UPDATE based on comment:
So in case you have only one class and want to achieve a dynamic CellTree (number of levels are not pre-determined) you could take following approach.
public <T> NodeInfo<?> getNodeInfo(T value) {
if (value == null) {
return new DefaultNodeInfo<Category>(dataProvider, new CategoriaCell());
}
else {
Category category = (Category)value;
return new DefaultNodeInfo<Category>(new ListDataProvider<Category>(category.getSubCategories()),new CategoryCell());
}
}
category.getSubCategories() is either an RPC call which retrieves the subcategories for the current category or if the Category class is a linked list type datastructure it could just return the list of subcategories.