CellTree, adding data to a child node and refresh

729 views
Skip to first unread message

Ümit

unread,
Nov 3, 2010, 1:13:06 PM11/3/10
to Google Web Toolkit
Hi all,

I have an issue with the CellTree and adding new items to a child
node. I am not exactly sure if my approach is flawed or maybe there is
an issue with the CellTree but maybe somebody can help with that
problem.
So basically I followed the CellTree example from the showace.

I have a CellTree which consists of 3 nodes which correspond to three
different DTO's (let's say: ObjectA, ObjectB and ObjectC)
Each ObjectA instance contains a list of ObjectBs and each ObjectB has
a list of ObjectCs.

ObjectA should be displayed in the root node, ObejctB in the second
node and ObjectC in the third node (= leaf node).

I created a CustomTreeModel with a custom constructor which takes a
List of ObjectA instances as a parameter. In the constructor I create
a ListDataProvider which is stored as a member variable in the
CustomTreeModel.

Then I define the necessary Cells for each node level and implement
the public <T> NodeInfo<?> getNodeInfo(T value) function.

This looks something like this:
public <T> NodeInfo<?> getNodeInfo(T value) {
if (value == null)
{
return new DefaultNodeInfo<ObjectA>
(listDataProvider,new TextCell());
}
else if (value instanceof ObjectA)
{
ObjectA object = (ObjectA)value;
return new DefaultNodeInfo<ObjectB>(new
ListDataProvider<ObjectB>(object.getObjectBList()),new TextCell());
}
else if (value instanceof ObjectB)
{
ObjectB object = (ObjectB)value;
return new DefaultNodeInfo<ObjectC>(new
ListDataProvider<ObjectC>(object.getObjectCList()),new TextCell());
}
String type = value.getClass().getName();
throw new IllegalArgumentException("Unsupported object type: "+
type);
}


getObjectBList(),getObjectCList() return the List of the child
Objects.

I pass this model to the CellTree and the CellTree is displayed
correctly.

Now I try to add a new ObjectB instance to the list of ObjectBs in the
one of the ObjectA instances. In order to update the CellTree I have
to update the DataProvider. I define a updateData function in the
CustomTreeModel:

public void updateData(List<ObjectA> objects){
listDataProvider.setList(objects); //listDataProvider of the root
node level is stored in the CustomTreeModel
listDataProvider.refresh(); //probably not necessary as setList
already takes care of refreshing the Tree.
}


Now when I call this method and pass the List of ObjectA instances
(one of them has modified List of ObjectB instances). the CellTree
doesn't get updated/refreshed.

My assumption is that listDataProvider.setList() only checks the List
of ObjectAs and as I haven't changed anything in the root list but in
one of its client lists, the CellTree doesn't get updated. One
workaround is that I call listDataProvider.setList(new
ArrayList<ObjectA>()) (empty list) before calling setList with the
actual list. However this causes the CellTree Nodes to get collapsed,
which I want to avoid.

Another approach would be to store the DataProviders for the ObjectB
and ObjectC instances (which I now only create as a local variable and
pass it to new DefaultNodeInfo) in the CustomTreeModel and also call
setList() on them. But IMHO that's not a really nice way of solving
it.


So basically there are two questions:

1.) When does setList() on the DataAdapter cause the Display to
refresh it contents? ( I assume that setList() will only call refresh
if the amount of elements is changed -> that's the reason why using
the workaround with a new empty ArrayList worked). What happens, if I
only change one of the properties? How can I force the DataAdapter to
update the Display if the amount of elements doesn't change ?

2.) How can I map an object graph (parent -> client objects) to a
CellTree or CellBrowser, so that any change to one of the client
objects causes a refresh of the Display (CellTree).

John LaBanca

unread,
Nov 3, 2010, 2:38:24 PM11/3/10
to google-we...@googlegroups.com
You are correct that refreshing the ListDataProvider<ObjectA> will only update that level of the tree.  You need to keep a reference to ListDataProvider<ObjectB> in order to refresh that section of the tree.  That probably means creating a parallel tree structure of ListDataProviders, or at least having a map for ObjectA to the ListDataProvider<ObjectB> that represents its children.

One workaround is to close/reopen the TreeNode, which will cause it to request a new DefaultNodeInfo from the TreeViewModel.

Thanks,
John LaBanca
jlab...@google.com



--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.


Ümit

unread,
Nov 4, 2010, 4:39:27 AM11/4/10
to Google Web Toolkit
Thanks John,
I was thinking in the same thing.
One last question. If I update the ListDataProvier of the Child
Objects will the nodes that were open stay open or will they be
automatically be closed?

cheers
Uemit


On Nov 3, 7:38 pm, John LaBanca <jlaba...@google.com> wrote:
> You are correct that refreshing the ListDataProvider<ObjectA> will only
> update that level of the tree.  You need to keep a reference to
> ListDataProvider<ObjectB> in order to refresh that section of the tree.
>  That probably means creating a parallel tree structure of
> ListDataProviders, or at least having a map for ObjectA to the
> ListDataProvider<ObjectB> that represents its children.
>
> One workaround is to close/reopen the TreeNode, which will cause it to
> request a new DefaultNodeInfo from the TreeViewModel.
>
> Thanks,
> John LaBanca
> jlaba...@google.com
> > google-web-tool...@googlegroups.com<google-web-toolkit%2Bunsubs cr...@googlegroups.com>
> > .

John LaBanca

unread,
Nov 4, 2010, 10:21:01 AM11/4/10
to google-we...@googlegroups.com
Open child nodes will stay open.  As an implementation detail, the children are physically detached from the DOM, the current level is refreshed, then the children are reattached to the DOM.

FYI - there is a bug in CellTree where it does not update a single value correctly.  You need to refresh all children (as you are doing by calling ListDataProvider.refresh()) for the CellTree to render correctly).  The bug will be fixed in GWT 2.1.1.

Thanks,
John LaBanca
jlab...@google.com


To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.

Matej

unread,
Nov 11, 2011, 9:39:27 AM11/11/11
to Google-We...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages