Note that there are some explanatory texts on larger screens.

plurals
  1. POGWT - Add and remove nodes in celltree
    text
    copied!<p>Here I have an complete and very easy example to dynamically add/remove nodes to an celltree. My example is not working very well. It seems there is an refresh problem. Only closing/expanding the nodes will show the correct result. I also did not found any answer in this forum which fits to this problem. Maybe somebody can try my example and tell me where the problem is. Any other hint is also very appreciated.</p> <p>Greetings, Marco</p> <pre><code>import java.util.ArrayList; import com.google.gwt.cell.client.AbstractCell; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.user.cellview.client.CellTree; import com.google.gwt.user.client.ui.AbsolutePanel; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.view.client.ListDataProvider; import com.google.gwt.view.client.SingleSelectionModel; import com.google.gwt.view.client.TreeViewModel; public class MyCelltreeTest implements EntryPoint { private AbsolutePanel absolutePanel; private CellTree cellTree; private Button btnAdd; private Button btnRemove; private MyTreeModel myTreeModel; private SingleSelectionModel&lt;MyNode&gt; selectionModelCellTree = null; @Override public void onModuleLoad() { RootPanel rootPanel = RootPanel.get(); rootPanel.add(getAbsolutePanel(), 0, 0); } private AbsolutePanel getAbsolutePanel() { if (absolutePanel == null) { absolutePanel = new AbsolutePanel(); absolutePanel.setSize("612px", "482px"); absolutePanel.add(getCellTree(), 0, 0); absolutePanel.add(getBtnAdd(), 265, 428); absolutePanel.add(getBtnRemove(), 336, 428); } return absolutePanel; } private CellTree getCellTree() { if (cellTree == null) { myTreeModel = new MyTreeModel(); cellTree = new CellTree(myTreeModel, null); cellTree.setSize("285px", "401px"); } return cellTree; } private Button getBtnAdd() { if (btnAdd == null) { btnAdd = new Button("Add"); btnAdd.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { MyNode node = selectionModelCellTree.getSelectedObject(); if(node != null) myTreeModel.addNew(node, "Bla"); } }); } return btnAdd; } private Button getBtnRemove() { if (btnRemove == null) { btnRemove = new Button("Remove"); btnRemove.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { MyNode node = selectionModelCellTree.getSelectedObject(); if(node != null) myTreeModel.remove(node); } }); } return btnRemove; } public class MyNode { private String name; private ArrayList&lt;MyNode&gt; childs; //nodes childrens private MyNode parent; //track internal parent private MyCell cell; //for refresh - reference to visual component public MyNode(String name) { super(); parent = null; this.name = name; childs = new ArrayList&lt;MyNode&gt;(); } public void addSubMenu(MyNode m) { m.parent = this; childs.add(m); } public void removeMenu(MyNode m) { m.getParent().childs.remove(m); } public boolean hasChildrens() { return childs.size()&gt;0; } public ArrayList&lt;MyNode&gt; getList() { return childs; } public MyNode getParent() { return parent; } public void setCell(MyCell cell) { this.cell = cell; } public void refresh() { if(parent!=null) { parent.refresh(); } if (cell!=null) { cell.refresh(); //refresh tree } } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class MyTreeModel implements TreeViewModel { private MyNode officialRoot; //default not dynamic private MyNode studentRoot; //default not dynamic private MyNode testRoot; //default not dynamic private MyNode root; public MyNode getRoot() { // to set CellTree root return root; } public MyTreeModel() { selectionModelCellTree = new SingleSelectionModel&lt;MyNode&gt;(); root = new MyNode("root"); // Default items officialRoot = new MyNode("Cat"); //some basic static data studentRoot = new MyNode("Dog"); testRoot = new MyNode("Fish"); root.addSubMenu(officialRoot); root.addSubMenu(studentRoot); root.addSubMenu(testRoot); } //example of add add logic public void addNew(MyNode myparent, String name) { myparent.addSubMenu(new MyNode(name)); myparent.refresh(); //HERE refresh tree } public void remove(MyNode objToRemove) { objToRemove.removeMenu(objToRemove); objToRemove.refresh(); } @Override public &lt;T&gt; NodeInfo&lt;?&gt; getNodeInfo(T value) { ListDataProvider&lt;MyNode&gt; dataProvider; MyNode myValue = null; if (value == null) { // root is not set dataProvider = new ListDataProvider&lt;MyNode&gt;(root.getList()); } else { myValue = (MyNode) value; dataProvider = new ListDataProvider&lt;MyNode&gt;(myValue.getList()); } MyCell cell = new MyCell(dataProvider); //HERE Add reference if (myValue != null) myValue.setCell(cell); return new DefaultNodeInfo&lt;MyNode&gt;(dataProvider, cell, selectionModelCellTree, null); } @Override public boolean isLeaf(Object value) { if (value instanceof MyNode) { MyNode t = (MyNode) value; if (!t.hasChildrens()) return true; return false; } return false; } } public class MyCell extends AbstractCell&lt;MyNode&gt; { ListDataProvider&lt;MyNode&gt; dataProvider; //for refresh public MyCell(ListDataProvider&lt;MyNode&gt; dataProvider) { super(); this.dataProvider = dataProvider; } public void refresh() { dataProvider.refresh(); } @Override public void render(Context context, MyNode value, SafeHtmlBuilder sb) { if (value == null) { return; } sb.appendEscaped(value.getName()); } } } </code></pre> <hr> <p>Thanks Ümit for your explanation. I tried the close-reopen version. I have replaced my refresh method with the methods below. Adding is working but removing not. Very strange the whole topic. I'm very suprised that these basic functions are not really supported by GWT. Can somebody give me more help to run a real working example.</p> <pre><code> public void refresh() { closeReopenTreeNodes(cellTree.getRootTreeNode()); } private void closeReopenTreeNodes(TreeNode node) { if(node == null) { return; } for(int i = 0; i &lt; node.getChildCount(); i++) { if(node.getChildValue(i).equals(this)){ if(node.getParent() != null){ node.getParent().setChildOpen(i, false); //node.getParent().setChildOpen(i, true); } node.setChildOpen(i, false); node.setChildOpen(i, true); } TreeNode child = node.setChildOpen(i, node.isChildOpen(i)); closeReopenTreeNodes(child); } } </code></pre> <p>Here my third try: This way is recommended by gwt-commiter. Please see following issue: <a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=7160" rel="noreferrer">http://code.google.com/p/google-web-toolkit/issues/detail?id=7160</a></p> <p>Current status: * Adding is possible * Removing is possible if not last child! </p> <p>So, last open point, refresh the tree if last open child!</p> <pre><code>package com.test; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import com.google.gwt.cell.client.AbstractCell; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.user.cellview.client.CellTree; import com.google.gwt.user.client.ui.AbsolutePanel; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.view.client.ListDataProvider; import com.google.gwt.view.client.SingleSelectionModel; import com.google.gwt.view.client.TreeViewModel; public class MyCelltreeTest2 implements EntryPoint { private AbsolutePanel absolutePanel; private CellTree cellTree; private Button btnAdd; private Button btnRemove; private MyTreeModel myTreeModel; private SingleSelectionModel&lt;MyNode&gt; selectionModelCellTree = null; private Map&lt;MyNode, ListDataProvider&lt;MyNode&gt;&gt; mapDataProviders = null; private ListDataProvider&lt;MyNode&gt; rootDataProvider = null; public void onModuleLoad() { RootPanel rootPanel = RootPanel.get(); rootPanel.add(getAbsolutePanel(), 0, 0); } private AbsolutePanel getAbsolutePanel() { if (absolutePanel == null) { absolutePanel = new AbsolutePanel(); absolutePanel.setSize("612px", "482px"); absolutePanel.add(getCellTree(), 0, 0); absolutePanel.add(getBtnAdd(), 265, 428); absolutePanel.add(getBtnRemove(), 336, 428); } return absolutePanel; } private CellTree getCellTree() { if (cellTree == null) { myTreeModel = new MyTreeModel(); cellTree = new CellTree(myTreeModel, null); cellTree.setSize("285px", "401px"); } return cellTree; } private Button getBtnAdd() { if (btnAdd == null) { btnAdd = new Button("Add"); btnAdd.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { MyNode node = selectionModelCellTree.getSelectedObject(); myTreeModel.add(node, "Bla"); } }); } return btnAdd; } private Button getBtnRemove() { if (btnRemove == null) { btnRemove = new Button("Remove"); btnRemove.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { MyNode node = selectionModelCellTree.getSelectedObject(); myTreeModel.remove(node); } }); } return btnRemove; } public class MyNode { private String name; private ArrayList&lt;MyNode&gt; childs; //nodes childrens private MyNode parent; //track internal parent public MyNode(String name) { super(); parent = null; this.name = name; childs = new ArrayList&lt;MyNode&gt;(); } public boolean hasChildrens() { return childs.size()&gt;0; } public ArrayList&lt;MyNode&gt; getList() { return childs; } public MyNode getParent() { return parent; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class MyTreeModel implements TreeViewModel { public MyTreeModel() { selectionModelCellTree = new SingleSelectionModel&lt;MyNode&gt;(); mapDataProviders = new HashMap&lt;MyCelltreeTest2.MyNode, ListDataProvider&lt;MyNode&gt;&gt;(); } public void add(MyNode myparent, String name) { MyNode child = new MyNode(name); //root-node if(myparent == null){ rootDataProvider.getList().add(child); mapDataProviders.put(child, rootDataProvider); } else{ ListDataProvider&lt;MyNode&gt; dataprovider = mapDataProviders.get(myparent); myparent.childs.add(child); child.parent = myparent; dataprovider.refresh(); } } public void remove(MyNode objToRemove) { ListDataProvider&lt;MyNode&gt; dataprovider = mapDataProviders.get(objToRemove); dataprovider.getList().remove(objToRemove); // mapDataProviders.remove(objToRemove); dataprovider.refresh(); dataprovider.flush(); if(objToRemove.parent != null){ ListDataProvider&lt;MyNode&gt; dataproviderParent = mapDataProviders.get(objToRemove.parent); objToRemove.parent.childs.remove(objToRemove); dataproviderParent.refresh(); dataproviderParent.flush(); } else{ rootDataProvider.refresh(); rootDataProvider.flush(); } } @Override public &lt;T&gt; NodeInfo&lt;?&gt; getNodeInfo(T value) { if (value == null) { // root is not set rootDataProvider = new ListDataProvider&lt;MyNode&gt;(new ArrayList&lt;MyNode&gt;()); MyCell cell = new MyCell(); return new DefaultNodeInfo&lt;MyNode&gt;(rootDataProvider, cell, selectionModelCellTree, null); } else { MyNode myValue = (MyNode) value; ListDataProvider&lt;MyNode&gt; dataProvider = new ListDataProvider&lt;MyNode&gt;(myValue.childs); MyCell cell = new MyCell(); for(MyNode currentNode : myValue.childs){ mapDataProviders.put(currentNode, dataProvider); } return new DefaultNodeInfo&lt;MyNode&gt;(dataProvider, cell, selectionModelCellTree, null); } } @Override public boolean isLeaf(Object value) { if (value instanceof MyNode) { MyNode t = (MyNode) value; if (!t.hasChildrens()) return true; return false; } return false; } } public class MyCell extends AbstractCell&lt;MyNode&gt; { public MyCell() { super(); } @Override public void render(Context context, MyNode value, SafeHtmlBuilder sb) { if (value == null) { return; } sb.appendEscaped(value.getName()); } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload