以编程方式刷新Gwt CellTree

时间:2011-08-30 07:29:55

标签: gwt tree refresh cell gwt-rpc

我想在我当前正在运行的CellTree上触发“开放根节点”事件,该事件现在具有以下行为:

@Override
    public <T> NodeInfo<?> getNodeInfo(final T value) {
        return new DefaultNodeInfo<Categoria>(
                (value instanceof Categoria) ? 
                        createBranchDataProvider((Categoria)value) :
                        rootDataProvider, 
                new CategoriaCell()
        );
    }

private AsyncDataProvider<Categoria> createRootDataProvider() {
        AsyncDataProvider<Categoria> dataProvider = new AsyncDataProvider<Categoria>() {
            @Override
            protected void onRangeChanged(HasData<Categoria> display) {
                AsyncCallback<Categoria[]> cb = new AsyncCallback<Categoria[]>() {
                    @Override
                    public void onSuccess(Categoria[] result) {
                        updateRowCount(result.length, true);
                        updateRowData(0, Arrays.asList(result));
                    }
                    @Override
                    public void onFailure(Throwable caught) {
                        Window.alert(caught.toString());
                    }
                };  
                rpcService.getCategorie(cb);
            }
        };
        return dataProvider;
    }

如何触发“onRangeChanged”事件,刷新我的1级节点?

我的便利方法缺失了什么?

private void updateTree() {     
        TreeNode rootTreeNode = cellTree.getRootTreeNode();
        for (int i = 0; i < rootTreeNode.getChildCount(); i++) {
            rootTreeNode.setChildOpen(i, false);
        }
        // HOW TO REFRESH LEVEL-1 NODES?
    }

2 个答案:

答案 0 :(得分:4)

工作示例。添加对DataProvider(和父节点)的引用(MyMenuItem和MyCell with DataProvider在我的代码中)。添加元素刷新后的父级。

public class MyMenuItem {
    private String name;
    private String action; //some data
    private int level; //if needed
    private ArrayList<MyMenuItem> list; //nodes childrens
    private MyMenuItem parent; //track internal parent
    private MyCell cell; //for refresh - reference to visual component

    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 String getAction() {
        return action;
    }
    public void setAction(String action) {
        this.action = action;
    }
    public MyMenuItem(String name, String action) {
        super();
        parent = null;
        level = 0;
        this.name = name;
        this.action = action;
        list = new ArrayList<MyMenuItem>();
    }
    public MyMenuItem(String name) {
        this(name, "");
    }
    public void addSubMenu(MyMenuItem m) {
        m.level = this.level+1;
        m.parent = this;
        list.add(m);
    }

    public boolean hasChildrens() {
        return list.size()>0;
    }
    public int getLevel() {
        return level;
    }
    public void setLevel(int level) {
        this.level = level;
    }
    public ArrayList<MyMenuItem> getList() {
        return list;
    }
    public MyMenuItem getParent() {
        return parent;
    }
}

public class MyTreeModel implements TreeViewModel {
    private MyMenuItem officialRoot; //default not dynamic
    private MyMenuItem studentRoot; //default not dynamic
    private MyMenuItem testRoot; //default not dynamic
    private MyMenuItem root;

    public MyMenuItem getRoot() { // to set CellTree root
        return root;
    }

    public MyTreeModel() {
        root = new MyMenuItem("root");
        // Default items
        officialRoot = new MyMenuItem("Official"); //some basic static data
        studentRoot = new MyMenuItem("Student");
        testRoot = new MyMenuItem("Test");
        root.addSubMenu(officialRoot);
        root.addSubMenu(studentRoot);
        root.addSubMenu(testRoot);
    }

    //example of add add logic
    private void addNew(MyMenuItem myparent, String name, String uid) {
        myparent.addSubMenu(new MyMenuItem(name, uid)); 
        myparent.refresh(); //HERE refresh tree
    }   

    @Override
    public <T> NodeInfo<?> getNodeInfo(T value) {
        ListDataProvider<MyMenuItem> dataProvider;
        MyMenuItem myValue = null;
        if (value == null) { // root is not set
            dataProvider = new ListDataProvider<MyMenuItem>(root.getList());
        } else {
            myValue = (MyMenuItem) value;
            dataProvider = new ListDataProvider<MyMenuItem>(myValue.getList());
        }
        MyCell cell = new MyCell(dataProvider); //HERE Add reference
        if (myValue != null)
            myValue.setCell(cell);
        return new DefaultNodeInfo<MyMenuItem>(dataProvider, cell);
    }

    @Override
    public boolean isLeaf(Object value) {
        if (value instanceof MyMenuItem) {
            MyMenuItem t = (MyMenuItem) value;
            if (!t.hasChildrens())
                return true;
            return false;
        }
        return false; 
    }

}

public class MyCell extends AbstractCell<MyMenuItem> {
        ListDataProvider<MyMenuItem> dataProvider; //for refresh
        public MyCell(ListDataProvider<MyMenuItem> dataProvider) {
          super("keydown","dblclick");
          this.dataProvider = dataProvider;
        }
        public void refresh() {
            dataProvider.refresh(); 
        }
        @Override
        public void onBrowserEvent(Context context, Element parent, MyMenuItem value,
            NativeEvent event, ValueUpdater<MyMenuItem> valueUpdater) {
          if (value == null) {
            return;
          }
          super.onBrowserEvent(context, parent, value, event, valueUpdater);
          if ("click".equals(event.getType())) {
            this.onEnterKeyDown(context, parent, value, event, valueUpdater);
          }
          if ("dblclick".equals(event.getType())) {
              this.onEnterKeyDown(context, parent, value, event, valueUpdater);
            }
        }

        @Override
        public void render(Context context, MyMenuItem value, SafeHtmlBuilder sb) {
          if (value == null) {
            return;
          }
          sb.appendEscaped(value.getName());
          //add HERE for better formating
        }


        @Override
        protected void onEnterKeyDown(Context context, Element parent,
                MyMenuItem value, NativeEvent event, ValueUpdater<MyMenuItem> valueUpdater) {
          Window.alert("You clicked "+event.getType()+" " + value.getName());
        }


}

在模块中添加

 treeModel = new MyTreeModel();
 tree = new CellTree(treeModel,treeModel.getRoot());

答案 1 :(得分:2)

Level-1节点(我想你是根节点下面的平均值)无法按照你的方式刷新。

您必须为某个级别的1级节点存储dataProvider的实例。 稍后当您刷新列表时,您必须为级别1节点更新存储的dataProvider level-1下面的节点可以按照您的方式刷新。因为只要你关闭1级节点(这是你在updateTree方法中所做的),并且下次打开它时,将调用getNodeInfo并且将检索更新的子类别并在CellTree中显示。

<强>更新

为了刷新附加到AsyncDataProvider的CellWidgets,您可能需要扩展AsyncDataProvider,并将RPC调用解压缩到onRangeChanged()方法中调用的getData()方法,或者创建{{3}并在自定义的AsyncDataProvider中实现它,它调用受保护的onRangeChanged()方法。