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
填充 vaadin 组件,例如 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();});
我有一个整数类型的组合框,我这样设置:
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
填充 vaadin 组件,例如 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();});