TreeTable - sorting by column, filtering by menuBar

Hi,

my code (I created correctly treetable and filled this table with data)

  private HierarchicalContainerOrderedWrapper createContaineForData() {
        BeanItemContainer<A> beanItemContainer = new BeanItemContainer<A>(A.class);
       
        ContainerHierarchicalWrapper containerHierarchicalWrapper = new ContainerHierarchicalWrapper(beanItemContainer);
        return new HierarchicalContainerOrderedWrapper(containerHierarchicalWrapper);
    }
     
    private Table createTable()
    {    
        HierarchicalContainerOrderedWrapper hierarchicalContainerOrderedWrapper = createContaineForData();
        
        generateDataFromDBToContainer(hierarchicalContainerOrderedWrapper);
        
        ttable= new TreeTable();
        ttable.setContainerDataSource(hierarchicalContainerOrderedWrapper);

How to add sorting by table column ?
How to add filtering by menuBar ?
(Yesterday I created ordinary Table and sorting works automatically…)

I try add sorting functionality to treetable:

[code]
ttable.addHeaderClickListener(new Table.HeaderClickListener() {

        private static final long serialVersionUID = 1L;

        public void headerClick(HeaderClickEvent event) {
            String column = (String) event.getPropertyId();
            Notification.show("Clicked " + column +
                    "with " + event.getButtonName());
            
            ttable.sort(new String{column}, new boolean {true});
        }
    });

[/code]I have error:
Caused by: java.lang.UnsupportedOperationException: Underlying Data does not allow sorting
at com.vaadin.ui.Table.sort(Table.java:4712)

Exist any Sortable and Hierarchical container ?

thanks
Areq

Hi,

the HierarchicalContainerOrderedWrapper class does not implement Container.Sortable interface which is required for the sorting to work. So you need to either make a customized container implementation that implements Sortable, or use HierarchicalContainer. There’s currently no “HierarchicalBeanItemContainer” available as far as I know. You could look at some pointers at
https://dev.vaadin.com/svn/doc/book-examples/trunk/src/com/vaadin/book/examples/datamodel/HierarchicalExample.java
where such a thing is implemented.

As for the filtering, you can just create your own Filter objects from actions on your menubar and then set them to the container. This will ofcourse require that your container implements the Container.Filterable interface.

-tepi

thank you.

I try write my container:

private CustomHierarchicalContainerOrderedWrapper createContaineForData() {
        BeanItemContainer<A> beanItemContainer = new BeanItemContainer<A>(A.class);
       
        ContainerHierarchicalWrapper containerHierarchicalWrapper = new ContainerHierarchicalWrapper(beanItemContainer);
        return new CustomHierarchicalContainerOrderedWrapper(containerHierarchicalWrapper);
    }


....

public class CustomHierarchicalContainerOrderedWrapper extends HierarchicalContainerOrderedWrapper implements Container.Sortable, Container.Filterable
{

    public CustomHierarchicalContainerOrderedWrapper(Hierarchical toBeWrapped)
    {
        super(toBeWrapped);
        // TODO Auto-generated constructor stub
    }

    private static final long serialVersionUID = -6455061814860969258L;

    @Override
    public void sort(Object[] propertyId, boolean[]
 ascending)
    {
        // TODO Auto-generated method stub
        
    }

    @Override
    public Collection<?> getSortableContainerPropertyIds()
    {
       
        return Collections.EMPTY_LIST;
    }

    @Override
    public void addContainerFilter(Filter filter)
            throws UnsupportedFilterException
    {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void removeContainerFilter(Filter filter)
    {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void removeAllContainerFilters()
    {
        // TODO Auto-generated method stub
        
    }

    @Override
    public Collection<Filter> getContainerFilters()
    {
        // TODO Auto-generated method stub
        System.out.println("ERROR");
        return null;

Could you provide any details/information hwo May I implements this methods in my case ?

thanks
Areq

Hi Areq,

why do you want to wrap a wrapper?
I didn’t test it out but you may want to extend ContainerHierarchicalWrapper and except an AbstractBeanContainer as constructor parameter/as delegator. So you can let the delegator do the sorting thing. That would be my first approach.

Hi,

providing pointers for all those methods is quite a task :).

Please see the code I linked earlier and especially the HierarchicalBeanItemContainer implemented within it. It implements Hierarchical and extends BeanItemContainer which is already Sortable and Filterable, so I think this should do what you need. You might even be done by just copy-pasting that exact implementation.

-tepi

thanks, but this solution:

[code]

public class CustomHierarchicalContainerOrderedWrapper
    extends HierarchicalContainerOrderedWrapper
    implements Container.Sortable, Container.Filterable
{
    public CustomHierarchicalContainerOrderedWrapper(Hierarchical toBeWrapped)
    {
        super(toBeWrapped);
        // TODO Auto-generated constructor stub
    }
    private static final long serialVersionUID = -6455061814860969258L;


    @Override
    public void sort(Object propertyId, boolean ascending)
    {
        // TODO Auto-generated method stub
    }


    @Override
    public Collection<?> getSortableContainerPropertyIds()
    {
        LinkedList<Object> sortables = new LinkedList<Object>();
        for (Object propertyId : getContainerPropertyIds()) {
            Class<?> propertyType = getType(propertyId);
            if (Comparable.class.isAssignableFrom(propertyType) || propertyType.isPrimitive()) {
                sortables.add(propertyId);
            }
        }
        return sortables;
    }


    @Override
    public void addContainerFilter(Filter filter)
            throws UnsupportedFilterException
    {
        // TODO Auto-generated method stub
    }


    @Override
    public void removeContainerFilter(Filter filter)
    {
        // TODO Auto-generated method stub
    }


    @Override
    public void removeAllContainerFilters()
    {
        // TODO Auto-generated method stub
    }


    @Override
    public Collection<Filter> getContainerFilters()
    {
        // TODO Auto-generated method stub
        System.out.println("ERROR");
        return null;
    }

[/code]will be not work correctly ?

I impleneted correctly getSortableContainerPropertyIds() method, but I have a problem with void sort(Object propertyId, boolean ascending)…

Yes, you can do it this way, I just don’t get why you want to do work that’s already been done. Basically what you need to do is just forward those method calls to the actual container. Since the underlying container is a BeanItemContainer those methods are already implemented there. If you’re going this way, you should probably change the constructor parameter type to something else than Hierarchical, since that alone does not provide access to Sortable/Filterable, even though the underlying BeanItemContainer implements those.

It is too difficulT to me…

I will try to use HierarchicalContainer, exist a big difference to use it instead of BeanItemContainer ?

The main difference is that you can’t use beans/BeanItems as the items in the container. This should not be an issue - you can just use the bean itself as the itemid. Remember that if you do that ,your bean should implement hashCode and equals methods properly.

Ok, thanks, it works !

I am feeling very tired :slight_smile:

One question yet - in these lines I have warning (Property should be parametrized)

item.getItemProperty("t").setValue(a.getT()); ... How to omit it ?

Hey Areq,

if you think you are safe, just annotate this method with

    @SuppressWarnings("unchecked")