BeanItemContainer unique property values

Viewed 49

I am using BeanItemContainer for my Grid. I want to get a unique list of one of the properties. For instance, let's say my beans are as follows:

class Fun {
     String game;
     String rules;
     String winner;
}

This would display as 3 columns in my Grid. I want to get a list of all the unique values for the game property. How would I do this? I have the same property id in multiple different bean classes, so it would be nice to get the values directly from the BeanItemContainer. I am trying to avoid building this unique list before loading the data into the Grid, since doing it that way would require me to handle it on a case by case basis.

My ultimate goal is to create a dropdown in a filter based on those unique values.

2 Answers

There isn't any helper for directly doing what you ask for. Instead, you'd have to do it "manually" by iterating through all items and collecting the property values to a Set which would then at the end contain all unique values.

Alternatively, if the data originates from a database, then you could maybe retrieve the unique values from there by using e.g. the DISTINCT keyword in SQL.

In case anyone is curious, this is how I applied Leif's suggestion. When they enter the dropdown, I cycle through all the item ids for the property id of the column I care about, and then fill values based on that property id. Since the same Grid can be loaded with new data, I also have to "clear" this list of item ids.

        filterField.addFocusListener(focus->{
            if(!(filterField.getItemIds() instanceof Collection) ||
                    filterField.getItemIds().isEmpty())
            {
                BeanItemContainer<T> container = getGridContainer();

                if( container instanceof BeanItemContainer && getFilterPropertyId() instanceof Object )
                {
                    List<T> itemIds = container.getItemIds();
                    Set<String> distinctValues = new HashSet<String>();
                    
                    for(T itemId : itemIds)
                    {
                        Property<?> prop = container.getContainerProperty(itemId, getFilterPropertyId());
                        String value = null;

                        if( prop.getValue() instanceof String )
                        {
                            value = (String) prop.getValue();
                        }
                        
                        if(value instanceof String && !value.trim().isEmpty())
                            distinctValues.add(value);
                    }
                    
                    filterField.addItems(distinctValues);
                }
            }
        });

Minor point: the filterField variable is using the ComboBoxMultiselect add-on for Vaadin 7. Hopefully, when I finally have time to convert to Vaadin 14+, I can do something similar there.

Related