Vaadin 8 - 在 ComboBox<Integer> 中对项目进行排序

Vaadin 8 - Sorting items in ComboBox<Integer>

我有一个整数类型的组合框,我这样设置:

Collection<Integer> cbItems = new HashSet<>();
for(Integer i = 100; i < 360; i+=5){
    cbItems.add(i);
}
ComboBox<Integer> cb = new ComboBox<>();
cb.setItems(cbItems);

我创建了一个整数集合并用特定的整数值(100、105、110 等)填充它。代码编译,组合框显示在视图中。

我的问题是 ComboBox 中的项目没有排序(或者更好:没有按照我认为的方式排序)。

为什么它会重新排序我的整数集合,我该如何防止它?

好的,我明白了:
我将集合更改为列表 (ArrayList),这样我就可以使用 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);

现在项目按升序排列。

我建议您使用 DataProvider 填充 组件,例如 ComboBox。这会让以后的事情变得更容易。

如果以后没有向 ComboBox 其他地方添加项目,您自己的解决方案就可以正常工作。如果添加项目,可能需要再次执行 Collections.sort()

稍作更改即可使用 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);

现在,如果您稍后将项目添加到组合(通过原始 Collection):

// add some items to see where they are sorted
cbItems.add(102);
cbItems.add(113);

这些项目应排序到 ComboBox 中的正确位置。

然后考虑一个更复杂的例子。如果你有一个 class 像:

@RequiredArgsConstructor
public class Wrapper {
   @Getter 
   private final Integer id;
   @Getter
   private final String name;
}

并且您想按名称降序对它进行排序,就像(带有测试数据):

// 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();});