PDA

View Full Version : [CLOSED] Dynamically add children to TreeGrid



fdussert
24 Jun 2009, 12:34 AM
Hi,

I tried to add dynamically items to a treeGrid but it doesn't work for items that have no child at the beginning :
- On application load, I add a child to a node : it works
- I remove all children from this node : it works
- I add a new children to this empty node : it works
- But if I add a child to a leaf : it doesn't work

Thanks in advance.

private void addItem(ModelData parent, TreeGrid<ModelData> grid) {
ModelData child = ... // creation of new object
grid.getTreeStore().add(parent, child, false);
grid.setExpanded(parent, true);
grid.getView().refresh(false);
}

private void removeItem(ModelData model, TreeGrid<ModelData> grid) {
grid.getTreeStore().remove(model);
grid.getView().refresh(true);
}

darrellmeyer
24 Jun 2009, 6:22 PM
Can you please provide complete sample code?

fdussert
17 Jul 2009, 6:51 AM
Hi,

Sorry for the response time.
I reproduced the problem with the code of your example (that very much easier than provide you my code)
The problem appears in a treeGrid with data provided by a RpcProxy.
Thanks in advance.



RpcProxy<List<BaseModel>> proxy = new RpcProxy<List<BaseModel>>() {
@Override
protected void load(Object loadConfig, AsyncCallback<List<BaseModel>> callback) {
Folder model = TestData.getTreeModel();
List<BaseModel> list = new LinkedList<BaseModel>();
for (ModelData m : model.getChildren()) {
list.add((BaseModel)m);
}
callback.onSuccess(list);
}
};
final TreeLoader<BaseModel> loader = new BaseTreeLoader<BaseModel>(proxy) {
@Override
public boolean hasChildren(BaseModel parent) {
if (parent instanceof Folder) {
Folder f = (Folder)parent;
return f.getChildCount() > 0;
}
return false;
}
};

// store
TreeStore<BaseModel> store = new TreeStore<BaseModel>(loader);

loader.load();

ColumnConfig name = new ColumnConfig("name", "Name", 100);
name.setRenderer(new TreeGridCellRenderer<ModelData>());

ColumnConfig date = new ColumnConfig("author", "Author", 100);

ColumnConfig size = new ColumnConfig("genre", "Genre", 100);

ColumnModel cm = new ColumnModel(Arrays.asList(name, date, size));

ContentPanel cp = new ContentPanel();
cp.setBodyBorder(false);
cp.setHeading("TreeGrid");
cp.setButtonAlign(HorizontalAlignment.CENTER);
cp.setLayout(new FitLayout());
cp.setFrame(true);
cp.setSize(600, 300);

final TreeGrid<ModelData> tree = new TreeGrid<ModelData>(store, cm);
tree.setBorders(true);
// tree.getStyle().setLeafIcon(Examples.ICONS.music());
tree.setSize(400, 400);
tree.setAutoExpandColumn("name");
tree.setTrackMouseOver(false);


Menu contextMenu = new Menu();
contextMenu.setWidth(140);

MenuItem insert = new MenuItem();
insert.setText("Insert Item");
// insert.setIcon(Examples.ICONS.add());
insert.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
ModelData folder = tree.getSelectionModel().getSelectedItem();
if (folder != null) {
Folder child = new Folder("Add Child");
tree.getTreeStore().add(folder, child, false);
tree.setExpanded(folder, true);
}

}
});
contextMenu.add(insert);

MenuItem remove = new MenuItem();
remove.setText("Remove Selected");
// remove.setIcon(Examples.ICONS.delete());
remove.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
List<ModelData> selected = tree.getSelectionModel().getSelectedItems();
for (ModelData sel : selected) {
tree.getTreeStore().remove(sel);
}

}
});
contextMenu.add(remove);

tree.setContextMenu(contextMenu);

fdussert
17 Jul 2009, 6:55 AM
Just one thing : I come to realize that some unnecessary code remained. (TreeStore with BaseModel and not ModelData)
It's better like that :


RpcProxy<List<ModelData>> proxy = new RpcProxy<List<ModelData>>() {
@Override
protected void load(Object loadConfig, AsyncCallback<List<ModelData>> callback) {
Folder model = TestData.getTreeModel();
callback.onSuccess(model.getChildren());
}
};
final TreeLoader<ModelData> loader = new BaseTreeLoader<ModelData>(proxy) {
@Override
public boolean hasChildren(ModelData parent) {
if (parent instanceof Folder) {
Folder f = (Folder)parent;
return f.getChildCount() > 0;
}
return false;
}
};

// store
TreeStore<ModelData> store = new TreeStore<ModelData>(loader);

loader.load();

ColumnConfig name = new ColumnConfig("name", "Name", 100);
name.setRenderer(new TreeGridCellRenderer<ModelData>());

ColumnConfig date = new ColumnConfig("author", "Author", 100);

ColumnConfig size = new ColumnConfig("genre", "Genre", 100);

ColumnModel cm = new ColumnModel(Arrays.asList(name, date, size));

ContentPanel cp = new ContentPanel();
cp.setBodyBorder(false);
cp.setHeading("TreeGrid");
cp.setButtonAlign(HorizontalAlignment.CENTER);
cp.setLayout(new FitLayout());
cp.setFrame(true);
cp.setSize(600, 300);

final TreeGrid<ModelData> tree = new TreeGrid<ModelData>(store, cm);
tree.setBorders(true);
// tree.getStyle().setLeafIcon(Examples.ICONS.music());
tree.setSize(400, 400);
tree.setAutoExpandColumn("name");
tree.setTrackMouseOver(false);


Menu contextMenu = new Menu();
contextMenu.setWidth(140);

MenuItem insert = new MenuItem();
insert.setText("Insert Item");
// insert.setIcon(Examples.ICONS.add());
insert.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
ModelData folder = tree.getSelectionModel().getSelectedItem();
if (folder != null) {
Folder child = new Folder("Add Child");
tree.getTreeStore().add(folder, child, false);
tree.setExpanded(folder, true);
}

}
});
contextMenu.add(insert);

MenuItem remove = new MenuItem();
remove.setText("Remove Selected");
// remove.setIcon(Examples.ICONS.delete());
remove.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
List<ModelData> selected = tree.getSelectionModel().getSelectedItems();
for (ModelData sel : selected) {
tree.getTreeStore().remove(sel);
}

}
});
contextMenu.add(remove);

tree.setContextMenu(contextMenu);

sven
17 Jul 2009, 7:01 AM
This is not a bug. Leafs cant be expanded. You need to override hasChildren of your loader to work correctly and indicate, that there are children. I am closing this issue

fdussert
17 Jul 2009, 7:31 AM
It's not exactly what I wanted to say.
I forgot to say to you that I delete children of the last folder for my example :

instead of

new Folder("Mozart", new Folder[] {
new Folder("Concertos",
new Music[] {
new Music("Piano Concerto No. 12", "Mozart", "Concertos"),
new Music("Piano Concerto No. 17", "Mozart", "Concertos"),
new Music("Clarinet Concerto", "Mozart", "Concertos"),
new Music("Violin Concerto No. 5", "Mozart", "Concertos"),
new Music("Violin Concerto No. 4", "Mozart", "Concertos"),
}),
}),
};

I put
new Folder("Mozart")


So, when I build my tree with a store that is directly filled, I can add some child to this empty folder

Folder model = TestData.getTreeModel();
TreeStore<ModelData> store = new TreeStore<ModelData>();
store.add(model.getChildren(), true);

before insert :
file:///C:/Temp/moz-screenshot-11.jpg15077

after insert :
15078

But if store is filled with a RpcProxy, it doesn't work ...

sven
17 Jul 2009, 7:34 AM
Yes. this is because of your hasChildren override of your loader. It returns false. You need to ask your store if you have childrens or remove that override.