以编程方式刷新Gwt单元树

以编程方式刷新Gwt单元树,gwt,tree,refresh,cell,gwt-rpc,Gwt,Tree,Refresh,Cell,Gwt Rpc,我想在当前工作的CellTree上触发“open root node”事件,该事件现在具有以下行为: @Override public <T> NodeInfo<?> getNodeInfo(final T value) { return new DefaultNodeInfo<Categoria>( (value instanceof Categoria) ?

我想在当前工作的CellTree上触发“open root node”事件,该事件现在具有以下行为:

@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;
    }
@覆盖
公共节点信息getNodeInfo(最终T值){
返回新的DefaultNodeInfo(
(类别A的值实例)?
createBranchDataProvider((分类)值):
rootDataProvider,
新类别acell()
);
}
专用AsyncDataProvider createRootDataProvider(){
AsyncDataProvider dataProvider=新的AsyncDataProvider(){
@凌驾
受保护的无效onRangeChanged(HasData显示){
AsyncCallback cb=新的AsyncCallback(){
@凌驾
成功时公开作废(类别[]结果){
updateRowCount(result.length,true);
updateRowData(0,Arrays.asList(result));
}
@凌驾
失败时的公共无效(可丢弃){
Window.alert(catch.toString());
}
};  
rpcService.getCategorie(cb);
}
};
返回数据提供者;
}
如何触发“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?
    }
private void updateTree(){
TreeNode rootTreeNode=cellTree.getRootTreeNode();
for(int i=0;i
1级节点(我想您是根节点下的平均值)无法按您的方式刷新

您必须将级别1节点的数据提供程序实例存储在某个位置。 稍后,当您刷新列表时,您必须为级别1节点更新存储的数据提供程序。
级别1以下的节点可以按您的方式刷新。因为一旦您关闭级别1节点(这就是您在updateTree方法中所做的),并且下次打开它时,将调用getNodeInfo,更新的子类别将被检索并显示在CellTree中

更新


要刷新附加到AsyncDataProvider的CellWidget,您可能必须扩展AsyncDataProvider,提取对onRangeChanged()方法中调用的方法的RPC调用,或者创建一个并在调用受保护的onRangeChanged()的自定义AsyncDataProvider中实现它方法。

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

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


}
很好但是怎么会?!?-。-'我的意思是,提供程序上唯一可用的方法是updateRowData(),我是否必须复制onRangeChanged()中的rpc代码,或者我是否可以以某种方式简单地触发“range changed”事件??谢谢
 treeModel = new MyTreeModel();
 tree = new CellTree(treeModel,treeModel.getRoot());