Reputation: 5766
I have a ComboBox of Type Integer that I setup like this:
Collection<Integer> cbItems = new HashSet<>();
for(Integer i = 100; i < 360; i+=5){
cbItems.add(i);
}
ComboBox<Integer> cb = new ComboBox<>();
cb.setItems(cbItems);
I create a Collection of Integers and fill it with certain Integer values (100, 105, 110, etc...). The Code compiles, and the ComboBox is displayed in the view.
My Problem is that the items in the ComboBox are not sorted (or better: not sorted in the way I thought it would be).
Why does it re-sort my Integer-Collection, and how can I prevent it?
Upvotes: 2
Views: 1487
Reputation: 5766
Okay I figured it out:
I changed the Collection to a List (ArrayList) so I can use Collections.sort(cbItems);
List<Integer> cbItems= new ArrayList<>();
for(Integer i = 100; i < 360; i+=5){
cbItems.add(i);
}
Collections.sort(cbItems);
ComboBox<Integer> cb = new ComboBox<>();
cb.setItems(cbItems);
Now the items are sorted ascendingly.
Upvotes: 0
Reputation: 12215
I would recommend you to populate vaadin components like ComboBox
with DataProvider
. It will make things easier later.
Your own solution works fine if there is not added items later to the ComboBox
elsewhere. If items are added it might be needed to perform Collections.sort()
again.
With a little change to use DataProvider
:
ListDataProvider<Integer> dp = new ListDataProvider<>(cbItems);
// the first param is function that returns the value to sort
// in case of Integer it is that Integer itself.
dp.setSortOrder(i -> {return i;}, SortDirection.ASCENDING);
ComboBox<Integer> combo = new ComboBox<>();
combo.setDataProvider(dp);
Now, if you later add items to combo (through the original Collection
):
// add some items to see where they are sorted
cbItems.add(102);
cbItems.add(113);
these items should be sorted to right place in ComboBox
.
Then consider a bit more complex example. If you had a class like:
@RequiredArgsConstructor
public class Wrapper {
@Getter
private final Integer id;
@Getter
private final String name;
}
and you wanted to sort it by name descending, it would be like (with test data):
// generate some dymmy data
Collection<Wrapper> wrappers = new HashSet<>();
for(int i=1000; i<=2000; i+=150) {
wrappers.add(new Wrapper(i,
"Rand"+ThreadLocalRandom.current().nextInt(5000, 6000)) );
}
ListDataProvider<Wrapper> dpWrappers = new ListDataProvider<>(wrappers);
// now function returns the name of the wrapper to sort as sort argument
dpWrappers.setSortOrder(wrapper -> {return wrapper.getName();},
SortDirection.DESCENDING);
ComboBox<Wrapper> comboWrappers = new ComboBox<>();
comboWrappers.setDataProvider(dpWrappers);
// remember to set this to have the name of wrapper in combo vaptions
// instead of the value of Wrapper.toString();
comboWrappers.setItemCaptionGenerator( item -> {return item.getName();});
Upvotes: 4