Search code examples
javavaadindropdown

Vaadin DropDown/Select/Spinner best practice?


I am looking at the Vaadin components and it seems like the "favoured" Select-component in Vaadin does not run on indexing.

Using this code:

List<String> list = new ArrayList<>();
    list.add("A");
    list.add("B");
    list.add("A");
    
    Select<String> select = new Select<>();
    select.setItems(list);

So when I have the following list:

  1. A
  2. B
  3. A

And I choose the third option, A, it would appear as the first option, also A, in the list. Is there a Vaadin component or library with java implementation which runs on indexed values? or has there been a workaround.


Solution

  • How would the end user distinguish those identical options?

    The Select component relies on the equals and hashCode methods to distinguish items. In your case, the two strings are equal to each other, and as such they are the same from the component's point of view.

    So if you have a valid use case for this, you will have to pass items where equals is properly implemented for the use case.

    There are several ways to do this: making a custom class, passing in a map of values, passing in an enum etc. In all cases you will probably want to use a custom item label generator.

    With a map, it would look something like this:

    Map<Integer, String> values = new HashMap<>();
    values.put(1, "A");
    values.put(2, "B");
    values.put(3, "A");
    
    Select<Integer> select = new Select<>();
    select.setItems(values.keySet());
    select.setItemLabelGenerator(values::get);
    
    add(select);
    

    Or with an enum, as cfrick suggested:

    enum Option {
        FIRST_A("A"), B("B"), SECOND_A("A");
    
        private final String name;
    
        Option(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }
    
    ...
    
    Select<Option> select = new Select<>();
    select.setItems(Option.values());
    select.setItemLabelGenerator(Option::getName);
    
    add(select);