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

时间:2018-01-24 16:50:39

标签: java vaadin vaadin8

我有一个类型为Integer的ComboBox,我设置如下:

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显示在视图中。

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

Screenshot of the actual Combobox

为什么要重新整理我的整数集合,我该如何预防呢?

2 个答案:

答案 0 :(得分:4)

我建议您使用ComboBox填充DataProviderComboBox组件。它会让事情变得更容易。

如果之后没有其他项目添加到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

这些项目应排在@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();});

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

const fs = require("fs");
const files = ["a.txt","b.txt","c.txt","d.txt"];

function forEachOf (array, asynchFunction, callbackWhenFinished) {
    let nbCalls = 0;
    array.forEach(item => asynchFunction(item, () => {
        // Wrapper function responsible of calling callback function
        // only once asynchronous job is done on all items of array
        if (++nbCalls === array.length)
            callbackWhenFinished();
    }));
}

var nbLinesTotal = 0;

forEachOf(
    files,
    (name, callback) => {
        // Write your asynchronous function here
        fs.readFile(name, 'utf-8', (error, data) => {
            if (!error)
                nbLinesTotal += data.toString().split("\n").length;
            // Wrapper function is called here: it seamlessly decides if it's time to call the real callback
            callback();
        });
    },
    () => {
        // Write your callback function here.
        // It will be called only once
        console.log(nbLinesTotal);
    }
);

答案 1 :(得分:0)

好吧我明白了:
我将Collection更改为List(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);

现在物品按升序排序。