PDA

View Full Version : TreePanel expanding dynamically



jeeads
3 Jan 2012, 11:40 AM
I would like to know how to programmically expand a treepanel node. I have built a treepanel that lazy loads as it should but I need to be able to pick a model from a list that is part of the hierarchy and expand the treepanel to that node. Since, when the treepanel is first initialized just the root node is in the models list it doesn't allow me to expand to the model selected out of the list? If I first load the hierarchy of models for the model I want to expand using the treepanel.getStore().getLoader().loadChildren(model) the loader runs and loads the necessary models but they are not inserted into the treepanel.getStore().getModels() therefore I can't get treepanel.setExpanded(model) to expand them? I know that the loadChildren calls an Async load and I have placed a loadlistener on the loader and I don't try to run setExpanded until the loader has loaded the model I want to expand.

Ersmarker
4 Jan 2012, 12:30 AM
I have used this trick in the past to expand nodes deep in the tree hirarchy.
Maybe it could help.



private void expandToTop(TreePanel panel,TreeModel m) {
if (m.getParent() != null) {
expandToTop(panel,m.getParent());
}
panel.setExpanded(m, true);
}

jeeads
4 Jan 2012, 8:11 AM
Tried your trick but since the models aren't loaded this does not work? I have to be able to load the hierarchy of models before I can use your trick, any other thoughts?

jeeads
5 Jan 2012, 7:14 AM
I have been able to solve this riddle. First I load the treepanel with just the root node. Next I take the object selected from the list to show in the tree and I use it as the argument to a service call, service.getHierarchyForChild(selectedObject.getId(), AsyncCallback<ArrayList<GfmObjectModel>>), which returns an array list of the hierarchy for the selectedObject from its parent to the root object. Since it is in reverse order when created I call Collections.reverse(list) on the resultant to correctly order the list.
service.getHierarchyForChild(selection.getId(), new AsyncCallback<ArrayList<GfmObjectModel>>() {

public void getHierarchy(GfmObjectModel selection){
this.selectedUnit = selection;

tree.collapseAll();

// Calls backend and returns an arraylist of GfmObjectModels
// for hierarchy of objects from child object selected
//selected parent object to root object.
service.getHierarchyForChild(selection.getId(),
new AsyncCallback<ArrayList<GfmObjectModel>>() {

@Override
public void onSuccess(ArrayList<GfmObjectModel> result) {
// Assigns call result to hierarchy arraylist
hierarchy = result;

// Uses java.util.Collections.reverse to reverse
//order the resultant list
Collections.reverse(hierarchy);

// Add the selected unit to the hierarchy list for loading.
hierarchy.add(selectedUnit);

List<GfmObjectModel> models = tree.getStore().getModels();

// Iterate through all the hierarchy and store models
// looking for a match. Since at the beginning only
// the root is in the store it will be found.
for ( GfmObjectModel gom : hierarchy ) {
for ( GfmObjectModel testObject : models ) {
if ( gom.getId().getValue() == testObject.getId().getValue() ) {
tree.setExpanded(testObject, true);
}
}
}
};

@Override
public void onFailure(Throwable caught) {
// TODO handle error
GWT.log("##################Failed to retrieve “ +
“hierarchy for child.");
}
});
}

jeeads
5 Jan 2012, 7:37 AM
Sorry about previous thread I hit something that submitted it before I was complete. I have been able to solve this riddle. First I load the treepanel with just the root node. Next I take the object selected from the list to show in the tree and I use it as the argument to a service call, service.getHierarchyForChild(selectedObject.getId(), AsyncCallback<ArrayList<GfmObjectModel>>), which returns an array list of the hierarchy for the selectedObject from its parent to the root object. Since it is in reverse order when created I call Collections.reverse(list) on the resultant to correctly order the list.

public void getHierarchy(GfmObjectModel selection){
this.selectedUnit = selection;

tree.collapseAll();

// Calls backend and returns an arraylist of GfmObjectModels
// for hierarchy of objects from child object selected
//selected parent object to root object.
service.getHierarchyForChild(selection.getId(),
new AsyncCallback<ArrayList<GfmObjectModel>>() {

@Override
public void onSuccess(ArrayList<GfmObjectModel> result) {
// Assigns call result to hierarchy arraylist
hierarchy = result;

// Uses java.util.Collections.reverse to reverse
//order the resultant list
Collections.reverse(hierarchy);

// Add the selected unit to the hierarchy list for loading.
hierarchy.add(selectedUnit);

List<GfmObjectModel> models = tree.getStore().getModels();

// Iterate through all the hierarchy and store models
// looking for a match. Since at the beginning only
// the root is in the store it will be found.
for ( GfmObjectModel gom : hierarchy ) {
for ( GfmObjectModel testObject : models ) {
if ( gom.getId().getValue() == testObject.getId().getValue() ) {
tree.setExpanded(testObject, true);
}
}
}
};

@Override
public void onFailure(Throwable caught) {
// TODO handle error
GWT.log("##################Failed to retrieve “ +
“hierarchy for child.");
}
});
}

So now we have expanded the root node but since the load is async we have to listen for when it is loaded so we can then expand the next node in the hierarchy.

private void intializeListeners(){
loader.addLoadListener(new LoadListener() {
@Override
public void loaderLoad(LoadEvent le) {
GfmObjectModel requestor = le.getConfig();
expandNextPartOfTree(requestor);
}
});
}

In this case the requestor is the object that was loaded/expanded. Now that we know that the load is complete we can call the next tree.setExpanded. This is handled by the expandNextPartOfTree method.

private void expandNextPartOfTree(GfmObjectModel lastExpanded){

GfmObjectModel nextToExpand = null;
for ( GfmObjectModel r : hierarchy ) {
if ( lastExpanded.getName().compareToIgnoreCase(r.getName()) == 0 ) {
if ( hierarchy.indexOf(r) < hierarchy.size() - 1 ){
nextToExpand = hierarchy.get(hierarchy.indexOf(r) + 1);
}
for ( GfmObjectModel testObject : tree.getStore().getModels() ) {
if ( nextToExpand.getId().getValue() == testObject.getId().getValue() ) {
tree.setExpanded(testObject, true);
}
}
}
}
}

I have tested this thoroughly and it works every time as long as your service sends back the correct hierarchy for the selected object. Hope this helps someone.