GWT - 在celltree中添加和删除节点 [英] GWT - Add and remove nodes in celltree

查看:98
本文介绍了GWT - 在celltree中添加和删除节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里,我有一个完整且非常简单的例子来动态地向celltree添加/删除
节点。我的例子不太好。看来
是一个刷新问题。只有关闭/展开节点才会显示正确的
结果。我也没有在这个论坛上找到适合这个问题的答案。
也许有人可以尝试我的例子,并告诉我问题在哪里。
任何其他提示也非常感谢。



问候,马可

  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;

公共类MyCelltreeTest实现EntryPoint {
private AbsolutePanel absolutePanel;
私有CellTree cellTree;
私人按钮btnAdd;
私人按钮btnRemove;
私人MyTreeModel myTreeModel;
private SingleSelectionModel< MyNode> 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);
}
返回absolutePanel;

$ b私有CellTree getCellTree(){
if(cellTree == null){
myTreeModel = new MyTreeModel();
cellTree = new CellTree(myTreeModel,null);
cellTree.setSize(285px,401px);
}
return cellTree;

$ b 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;

$ b 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< MyNode>孩子的; //节点childrens
私人MyNode父母; //跟踪内部父母
私人MyCell小区; //用于刷新 - 引用可视组件

public MyNode(String name){
super();
parent = null;
this.name = name;
childs = new ArrayList< MyNode>();
}

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()> 0;
}

public ArrayList< MyNode> getList(){
返回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(); //刷新树
}
}

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}
}

公共类MyTreeModel实现了TreeViewModel {
private MyNode officialRoot; //默认不动态
private MyNode studentRoot; //默认不动态
private MyNode testRoot; //默认不动态
私人MyNode root;
$ b $ public MyNode getRoot(){//设置CellTree root
return root;

$ b $ public MyTreeModel(){
selectionModelCellTree = new SingleSelectionModel< MyNode>();
root = new MyNode(root);
//默认项目
officialRoot = new MyNode(Cat); //一些基本的静态数据
studentRoot = new MyNode(Dog);
testRoot = new MyNode(Fish);
root.addSubMenu(officialRoot);
root.addSubMenu(studentRoot);
root.addSubMenu(testRoot);


//添加逻辑示例
public void addNew(MyNode myparent,String name){
myparent.addSubMenu(new MyNode(name));
myparent.refresh(); //这里刷新树
}
public void remove(MyNode objToRemove){

objToRemove.removeMenu(objToRemove);
objToRemove.refresh();
}

@Override
public< T>的nodeinfo<?> getNodeInfo(T值){
ListDataProvider< MyNode>数据提供程序;
MyNode myValue = null;
if(value == null){// root未设置
dataProvider = new ListDataProvider< MyNode>(root.getList());
} else {
myValue =(MyNode)value;
dataProvider = new ListDataProvider< MyNode>(myValue.getList());
}
MyCell cell = new MyCell(dataProvider); // HERE添加引用
if(myValue!= null)
myValue.setCell(cell);
返回新的DefaultNodeInfo< MyNode>(dataProvider,cell,selectionModelCellTree,null);

$ b @Override
public boolean isLeaf(Object value){
if(value instanceof MyNode){
MyNode t =(MyNode)value;
if(!t.hasChildrens())
返回true;
返回false;
}
返回false;
}
}

公共类MyCell扩展AbstractCell< MyNode> {
ListDataProvider< MyNode>数据提供程序; //刷新

public MyCell(ListDataProvider< MyNode> dataProvider){
super();
this.dataProvider = dataProvider;
}
public void refresh(){
dataProvider.refresh();

$ b @Override
public void render(Context context,MyNode value,SafeHtmlBuilder sb){
if(value == null){
return ;
}
sb.appendEscaped(value.getName());



code
$ b $ hr

非常感谢您的解释。
我尝试了重新打开的版本。
我用下面的方法替换了我的刷新方法。
添加正在工作,但没有移除。
整个话题都很奇怪。我很惊讶这些基本的
函数并不真正被GWT支持。
有人可以给我更多帮助来运行一个真实的工作示例。

  public void refresh(){

closeReopenTreeNodes(cellTree.getRootTreeNode());
}

private void closeReopenTreeNodes(TreeNode node){
if(node == null){
return; (i).equals(this))

for(int i = 0; i< node.getChildCount(); i ++){

if(node.getChildValue {

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);






$ b这里我的第三次尝试:
这样由gwt-commiter推荐。
请参阅以下问题:
http://code.google.com/p/google-web-toolkit/issues/detail?id=7160



当前状态:
*可以添加
*如果不是最后一个孩子,可以移除!


$ b

所以,最后一个开放点,如果最后一个开放的孩子刷新树!

  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实现EntryPoint {
private AbsolutePanel absolutePanel;
私有CellTree cellTree;
私人按钮btnAdd;
私人按钮btnRemove;
私人MyTreeModel myTreeModel;
private SingleSelectionModel< MyNode> selectionModelCellTree = null;
私人地图< MyNode,ListDataProvider< MyNode>> mapDataProviders = null;
私人ListDataProvider< MyNode> 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);
}
返回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;
}


公共类MyNode {

私有字符串名称;
private ArrayList< MyNode>孩子的; //节点childrens
私人MyNode父母; //跟踪内部父元素


public MyNode(String name){
super();
parent = null;
this.name = name;
childs = new ArrayList< MyNode>();
}
public boolean hasChildrens(){
return childs.size()> 0;
}
public ArrayList< MyNode> getList(){
返回childs;
}
public MyNode getParent(){
return parent;
}

public String getName(){
return name;
}
public void setName(String name){
this.name = name;


$ b public class MyTreeModel实现了TreeViewModel {


MyTreeModel(){
selectionModelCellTree = new SingleSelectionModel< MYNODE>();
mapDataProviders = new HashMap< MyCelltreeTest2.MyNode,ListDataProvider< MyNode>>();

$ b public void add(MyNode myparent,String name){

MyNode child = new MyNode(name);

//根节点
if(myparent == null){
rootDataProvider.getList()。add(child);
mapDataProviders.put(child,rootDataProvider);
}
else {

ListDataProvider< MyNode> dataprovider = mapDataProviders.get(myparent);
myparent.childs.add(child);
child.parent = myparent;
dataprovider.refresh();
}
}
public void remove(MyNode objToRemove){

ListDataProvider< MyNode> dataprovider = mapDataProviders.get(objToRemove);
dataprovider.getList()。remove(objToRemove);
// mapDataProviders.remove(objToRemove);
dataprovider.refresh();
dataprovider.flush();

if(objToRemove.parent!= null){
ListDataProvider< MyNode> dataproviderParent = mapDataProviders.get(objToRemove.parent);
objToRemove.parent.childs.remove(objToRemove);
dataproviderParent.refresh();
dataproviderParent.flush();
}
else {
rootDataProvider.refresh();
rootDataProvider.flush();
}
}


@覆盖
public< T>的nodeinfo<?> getNodeInfo(T值){

如果(值== NULL){//根未设置
rootDataProvider =新ListDataProvider< MYNODE>(新的ArrayList< MYNODE>());
MyCell cell = new MyCell();
返回新的DefaultNodeInfo< MyNode>(rootDataProvider,cell,
selectionModelCellTree,null);
} else {
MyNode myValue =(MyNode)value;
ListDataProvider< MyNode> dataProvider =
新的ListDataProvider< MyNode>(myValue.childs);
MyCell cell = new MyCell();
for(MyNode currentNode:myValue.childs){
mapDataProviders.put(currentNode,dataProvider);
}
返回新的DefaultNodeInfo< MyNode>(dataProvider,cell,
selectionModelCellTree,null);



$覆盖
public boolean isLeaf(Object value){
if(value instanceof MyNode){
MyNode t = (MyNode)值;
if(!t.hasChildrens())
返回true;
返回false;
}
返回false;
}

}

public class MyCell extends AbstractCell< MyNode> {
public MyCell(){
super();

@Override
public void render(Context context,MyNode value,SafeHtmlBuilder sb){
if(value == null){
return;
}
sb.appendEscaped(value.getName());




解决方案

这是CellTree的一个已知问题。

刷新问题的原因是在 getNodeInfo()函数中创建了一个新 ListDataProvider 例如每个CellTree水平。结果
的CellTree只更新/刷新本身,如果你更新的项目 ListDataProvider
我相信你的removeMenu()和addSubMenu()函数会添加和删除存储在MyNode类中的原始列表中的项目,但不会更新相应ListDataProviders中的列表(可以尝试在调试模式下检查它)。
当您关闭并重新打开
时,CellTree被刷新的原因是因为当您重新打开节点时, getNodeInfo() code>被再次调用,并且整个CellTree结构将被重新构造(包括新菜单或分别没有被删除的菜单)。

有两种可能的解决方案:


  1. 保留每个参考 ListDataProviders 某处并调用remove / add在该列表上(尽管如此,我认为这些项目并未真正添加/删除)。
  2. 以编程方式关闭所有节点并重新打开它。

这两种方式都是PITA的实现方式。不幸的是,它没有简单的方法。


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.

Greetings, Marco

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<MyNode> 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<MyNode> 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<MyNode>();
    }

    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()>0;
    }

    public ArrayList<MyNode> 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<MyNode>();
      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 <T> NodeInfo<?> getNodeInfo(T value) {
      ListDataProvider<MyNode> dataProvider;
      MyNode myValue = null;
      if (value == null) { // root is not set
        dataProvider = new ListDataProvider<MyNode>(root.getList());
      } else {
        myValue = (MyNode) value;
        dataProvider = new ListDataProvider<MyNode>(myValue.getList());
      }
      MyCell cell = new MyCell(dataProvider); //HERE Add reference
      if (myValue != null)
        myValue.setCell(cell);
      return new DefaultNodeInfo<MyNode>(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<MyNode> {
    ListDataProvider<MyNode> dataProvider; //for refresh

    public MyCell(ListDataProvider<MyNode> 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());
    }
  }
}


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.

    public void refresh() {

         closeReopenTreeNodes(cellTree.getRootTreeNode());
    }

    private void closeReopenTreeNodes(TreeNode node) {
        if(node == null) {
            return;
        }
        for(int i = 0; i < 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);
        }
    }

Here my third try: This way is recommended by gwt-commiter. Please see following issue: http://code.google.com/p/google-web-toolkit/issues/detail?id=7160

Current status: * Adding is possible * Removing is possible if not last child!

So, last open point, refresh the tree if last open child!

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<MyNode> selectionModelCellTree = null;
    private Map<MyNode, ListDataProvider<MyNode>> mapDataProviders = null;
    private ListDataProvider<MyNode> 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<MyNode> childs; //nodes childrens
        private MyNode parent; //track internal parent


        public MyNode(String name) {
            super();
            parent = null;
            this.name = name;
            childs = new ArrayList<MyNode>();
        }
        public boolean hasChildrens() {
            return childs.size()>0;
        }
        public ArrayList<MyNode> 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<MyNode>();
            mapDataProviders = new HashMap<MyCelltreeTest2.MyNode, ListDataProvider<MyNode>>();
        }

        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<MyNode> dataprovider = mapDataProviders.get(myparent);
                    myparent.childs.add(child);
                    child.parent = myparent;
                    dataprovider.refresh();
            }
        }   
        public void remove(MyNode objToRemove) {

            ListDataProvider<MyNode> dataprovider = mapDataProviders.get(objToRemove);
                    dataprovider.getList().remove(objToRemove);
  //                 mapDataProviders.remove(objToRemove);
                    dataprovider.refresh();
                    dataprovider.flush();

                    if(objToRemove.parent != null){
                            ListDataProvider<MyNode> dataproviderParent = mapDataProviders.get(objToRemove.parent);
                            objToRemove.parent.childs.remove(objToRemove);
                            dataproviderParent.refresh();
                            dataproviderParent.flush();
                    }
                    else{
                            rootDataProvider.refresh();
                            rootDataProvider.flush();
                    }       
        } 


        @Override
        public <T> NodeInfo<?> getNodeInfo(T value) {

            if (value == null) { // root is not set
             rootDataProvider = new ListDataProvider<MyNode>(new ArrayList<MyNode>());
                    MyCell cell = new MyCell(); 
   return new DefaultNodeInfo<MyNode>(rootDataProvider, cell,   
  selectionModelCellTree, null);
            } else {
                    MyNode myValue = (MyNode) value;
                ListDataProvider<MyNode> dataProvider = 
                    new ListDataProvider<MyNode>(myValue.childs);
                    MyCell cell = new MyCell(); 
                    for(MyNode currentNode : myValue.childs){
                            mapDataProviders.put(currentNode, dataProvider);
                    }
                return new DefaultNodeInfo<MyNode>(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<MyNode> {
            public MyCell() {
              super();
            }
            @Override
            public void render(Context context, MyNode value, SafeHtmlBuilder sb) {
              if (value == null) {
                return;
              }
              sb.appendEscaped(value.getName());
            }
    }
}

解决方案

This is somehow a known problem with CellTree.
The reason for the refresh problem is that in the getNodeInfo() function you create a new ListDataProvider instance for each CellTree level.
The CellTree only updates/refreshes itself if you update the items in that ListDataProvider. I believe that your removeMenu() and addSubMenu() functions add and remove items from the original list stored in your MyNode class but won't update the list in the corresponding ListDataProviders (you can try to check that in debug mode).
The reason why the CellTree is refreshed when you close and re -open the nodes is because when you re-open the nodes the getNodeInfo() is called again and the whole CellTree structure will be constructed again (including the new menu or without the removed one respectively).

There are two possible solutions:

  1. Keep a reference for each of the ListDataProviders somewhere and call remove/add on that list (although you do that I assume that the items are not really added/removed there).
  2. Programatically close all nodes and re-open it.

Both are somehow a PITA to implement. Unfortunately there is no easy way around it.

这篇关于GWT - 在celltree中添加和删除节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆