-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Dear all,
when I use dynamic tree with model and renderer, there is problem with combobox inside treeitem. When comobox has many comboitems (roughly about 100), then when I open parent treenode, I get on client small window with (probably javascript) exception: "addAft". After I click "redraw", the data are displayed correctly.
Here is a simple example:
<?page id="kukatkoPage2" title="Test Tree item"?> <zk xmlns="http://www.zkoss.org/2005/zul" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml"> <window title="Test" height="100%" apply="TestController"> <tree id="tree" width="100%" height="100%" > <treecols sizable="true"> <treecol label="Name" /> <treecol label="Description" /> </treecols> </tree> </window> </zk>
And the controller class (only relevant part is the with DLTreeItemRenderer inner class, there is the construction of combobox with 500 items)
import java.util.ArrayList; import java.util.List; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.util.GenericForwardComposer; import org.zkoss.zul.AbstractTreeModel; import org.zkoss.zul.Combobox; import org.zkoss.zul.Comboitem; import org.zkoss.zul.Tree; import org.zkoss.zul.Treecell; import org.zkoss.zul.Treeitem; import org.zkoss.zul.TreeitemRenderer; import org.zkoss.zul.Treerow; public class TestController extends GenericForwardComposer { Tree tree; public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); comp.setVariable("ctl", this, true); String[] name2 = {"Paul","Eric","Gray"}; String[] accountId2 = {"p002","e009","g019"}; ArrayList alc2 = new ArrayList(); for(int i =0; i < name2.length; i++){ DataItem person = new DataItem(name2<i >,accountId2<i >); SimpleTreeNode stn = new SimpleTreeNode(person,new ArrayList()); alc2.add(stn); } SimpleTreeNode salesDep = new SimpleTreeNode(new DataItem("Sales",""),alc2); ArrayList al = new ArrayList(); al.add(salesDep); SimpleTreeNode root = new SimpleTreeNode("ROOT",al); tree.setTreeitemRenderer(new DLTreeItemRenderer()); tree.setModel(new DLTreeModel(root)); } class DataItem{ private String polozka; private String hodnota; public DataItem(String polozka, String hodnota) { this.polozka = polozka; this.hodnota = hodnota; } public String getHodnota() {return hodnota;} public void setHodnota(String hodnota) {this.hodnota = hodnota;} public String getPolozka() {return polozka;} public void setPolozka(String polozka) {this.polozka = polozka;} } class DLTreeItemRenderer implements TreeitemRenderer { public void render(Treeitem item, Object data) throws Exception { SimpleTreeNode t = (SimpleTreeNode) data; DataItem person = (DataItem) t.getData(); Treecell tcName = new Treecell(person.getPolozka()); Treecell tcEmail = new Treecell(); Combobox l = new Combobox(); for (int i = 0; i < 500; i++) { Comboitem ci = new Comboitem(); ci.setValue(i); ci.setLabel("Label: " + i); ci.setParent(l); } l.setParent(tcEmail); Treerow tr = null; if (item.getTreerow() == null) { tr = new Treerow(); tr.setParent(item); } else { tr = item.getTreerow(); tr.getChildren().clear(); } tcName.setParent(tr); tcEmail.setParent(tr); item.setOpen(false); } } class DLTreeModel extends AbstractTreeModel { public DLTreeModel(SimpleTreeNode root) {super(root);} public Object getChild(Object parent, int index) { SimpleTreeNode node = (SimpleTreeNode)parent; return node.getChildAt(index); } public int getChildCount(Object parent) { SimpleTreeNode node = (SimpleTreeNode)parent; return node.getChildCount(); } public boolean isLeaf(Object node) { if(node instanceof SimpleTreeNode){ SimpleTreeNode node_ = (SimpleTreeNode)node; return node_.isLeaf(); }else{ return true; } } } public class SimpleTreeNode { private Object _data; private List _children; public SimpleTreeNode(Object data, List children){ _data = data; _children = children; } public Object getData(){return _data;} public List getChildren(){return _children;} public String toString(){return (_data == null)?"Data is null":_data.toString();} public boolean isLeaf(){return (_children.size() == 0);} public Object getChildAt(int childIndex){return _children.get(childIndex);} public int getChildCount(){return _children.size();} } }
It looks like a ZK bug to me. Does anyone experience similar problems?
Best Regards,
Jiri Bubnik
can you reduce your code and repost it ?
This is as reduced as possible :-)
<?xml version="1.0" encoding="UTF-8"?> <zk xmlns="http://www.zkoss.org/2005/zul" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml"> <zscript><![CDATA[ // initialize the model List rList = new ArrayList(); rList.add("Level 2 - A"); rList.add("Level 2 - B"); SimpleTreeNode r = new SimpleTreeNode("Root", rList); List rootList = new ArrayList(); rootList.add(r); SimpleTreeNode root = new SimpleTreeNode("Root", rootList); SimpleTreeModel model = new SimpleTreeModel(root); // create renderer TreeitemRenderer renderer = new TreeitemRenderer() { public void render(Treeitem item, Object data) throws Exception { // combobox with many items - usually 100 is enaugh to reproduce this problem Combobox combo = new Combobox(); for (int i = 0; i < 500; i++) { Comboitem ci = new Comboitem(); ci.setLabel("Label: " + i); ci.setParent(combo); } // attach the combo as only item in tree row Treerow row = new Treerow(); Treecell cell = new Treecell(); combo.setParent(cell); cell.setParent(row); row.setParent(item); } } ]]></zscript> <tree model="${model}" treeitemRenderer="${renderer}"> <treecols sizable="true"> <treecol label="Col" /> </treecols> </tree> </zk>
It loads correctly, but after you try to expand first row, it throws javascript error:
addAft
a is undefined
Regards,
JB
Hi JB,
After trying you code, i found that's a bug of ZK, and it only happens when the i is > 141 or more (maybe racing problem)
i post a bug here, you can follow it :)
imho, render 500 combo items is very slow(because it will add add add many times)
you can create it all in server side and invalidate() the tree.
it can also avoid the bug above.
/Ryan Wu
Hi thanks for your response.
I don't understand what you mean by multiple adding. I thought that it will be transfered to the client in one shot...
Regards,
JB
yes, you got the answer !!
if you transfer the "tree" which contains lots of comboitem to client in one shot,
it's much faster than "render" it.
Asked: 2009-03-19 18:08:04 +0800
Seen: 997 times
Last updated: Apr 01 '09