Search code examples
gwttreecelldataprovider

On Gwt TreeViewModel getNodeInfo() method


I can't understand that part, neither trying the showcase examples.

I'm using an extension of AsyncDataProvider to bind my tree to RPC service. Here's my method:

public <T> NodeInfo<?> getNodeInfo(T value) {
        /*
        if (value instanceof Categoria) {
            dataProvider.setCurrentParent((Categoria)value);
        }
        */
        return new DefaultNodeInfo<Categoria>(dataProvider, new CategoriaCell());
    }

"currentParent" is my stuff: except for (null => root) values, I set the parent to pass via RPC to my service. Actually, in my widget code:

dataProvider = new CategorieTreeDataProvider() {            
            @Override
            protected void onRangeChanged(HasData<Categoria> display) {
                updateTree(getCurrentParent());
            }
        };

private void updateTree(Categoria categoria) {
        rpcService.getCategorie(categoria, new AsyncCallback<Categoria[]>() {
            @Override
            public void onSuccess(Categoria[] result) {
                dataProvider.updateRowCount(result.length, true);
                dataProvider.updateRowData(0, Arrays.asList(result));
            }
            @Override
            public void onFailure(Throwable caught) {
                Window.alert(caught.toString());
            }
        });
    }

My rpc-server code, however, is working as expected:

@Override
    public Categoria[] getCategorie(Categoria parent) {
        List<Categoria> categoryList = categorieDao.listByProperty("parent", parent);
        for (Categoria c : categoryList) {
            if (categorieDao.listByProperty("parent", c).size() == 0) {
                c.setLeaf(true);
            }
        }
        return categoryList.toArray(new Categoria[0]);
    }

**Then I add some data to my Categories: 'GrandFather', 'Father' and 'Son'.

Unfortunately, after loading my widget, I see:

  • The grandfather correctly, with his "+" how expected;

  • Then I click it and...

  • The grandfather disappear and I see 'Father' with his '+'

  • same for father -> son

I suspect the bug is in updateRowCount / updateRowData usage.**

Any ideas?


Solution

  • The getNodeInfo is called whenever you open a node so you have to create distinct DataProvider for each of the nodes's childs.

    public <T> NodeInfo<?> getNodeInfo(T value) {
            if (value == null) {
                return new DefaultNodeInfo<Category>(dataProvider, new CategoriaCell());
            }
            else if (value instanceof Categoria) {
                     Category category  = (Category)value;
                 return new DefaultNodeInfo<Grandfather>(new ListDataProvider<Grandfather>(category.getGrandFathers()),new GrandFatherCell());
            }
            else if (value instanceof Grandfather) {
                 Grandfather grandfather = (Grandfather)value;
                 return new DefaultNodeInfo<Father>(new ListDataProvider<Father>(granfather.getFathers()),new FatherCell());
            }
            else if (value instanceof Father) {
                //same as above but with fathers.
            }
        }
    

    The category.getGrandFathers() function can for example do a RPC request to the server or just return the list if you retrieve everything in one RPC request.

    UPDATE based on comment:

    So in case you have only one class and want to achieve a dynamic CellTree (number of levels are not pre-determined) you could take following approach.

    public <T> NodeInfo<?> getNodeInfo(T value) {
        if (value == null) {
            return new DefaultNodeInfo<Category>(dataProvider, new CategoriaCell());
        }
        else {
            Category category  = (Category)value;
            return new DefaultNodeInfo<Category>(new ListDataProvider<Category>(category.getSubCategories()),new CategoryCell());
        }
    }
    

    category.getSubCategories() is either an RPC call which retrieves the subcategories for the current category or if the Category class is a linked list type datastructure it could just return the list of subcategories.