如何订购选择行的网格始终作为网格的第一行/最顶行?

时间:2017-11-22 08:42:58

标签: java sorting grid vaadin comparator

我想在Vaadin Grid组件上设置所选行(在Multiselect模式下)作为第一个显示的行,即按所选行的顺序。

有人知道这是否可能?

1 个答案:

答案 0 :(得分:0)

有可能。我在这里提出一个有四点需要注意的解决方案。可能会有更优雅的解决方案。

  1. 需要一个可以检查项目
  2. 的选择状态的比较器
  3. 比较者需要考虑排序顺序
  4. 排序是基于列的
  5. 无论如何都需要使用默认的排序方法/比较器对未选择的行进行排序,也可能选择其他所选行。
  6. 积分1&通过创建同时实现Comparator

    SortEvent.SortListener来满足2
    @RequiredArgsConstructor
    // above is a lombok annotation to generate constructor
    // SelectedFirstComparator(grid, defaultComparator);
    public class SelectedFirstComparator<T>
            implements SerializableComparator<T>, SortListener<GridSortOrder<T>> {
        private final Grid<T> grid; // used to dig selected rows
        // defaultComparator is used when selection status is not taken 
        // account to handle rest of sorting, related to point 4   
        private final SerializableComparator<T> defaultComparator; 
        // sortOrder is used to inverse the sorting order between
        // selected & not selected items
        // if not used selected items will change between first & last rows 
        // and we need them always first 
        private int sortOrder = 1; 
        @Override
        public int compare(T o1, T o2) {
            boolean o1Selected = grid.getSelectedItems().contains(o1);
            boolean o2Selected = grid.getSelectedItems().contains(o2);
            // if one is selected and one is not the selected one "wins"
            if(o1Selected && !o2Selected) return 1 * sortOrder;
            if(!o1Selected && o2Selected) return -1 * sortOrder;
            // if both are selected arrange amongst first rows
            // with default comparator
            // if both are not-selected arrange them to natural order
            // with default comparator
            return defaultComparator.compare(o1, o2);
        }
    
        // This method is listening the sort order change
        // and updating the sortOrder to keep selected rows as firts 
        @Override
        public void sort(SortEvent<GridSortOrder<T>> event) {
            switch(event.getSortOrder().get(0).getDirection()) {
            case ASCENDING:
                sortOrder = -1;
                break;
            case DESCENDING:
                sortOrder = 1;
                break;
            }
        }
    }
    

    第3点

    您需要为每个可排序列添加SelectedFirstComparator的实例作为比较器,例如

    col1.setComparator(col1Comparator);
    col2.setComparator(col2Comparator);
    ...
    

    对于每个colXcomparator,您需要在构造时提供相应的默认比较器处理列默认排序。如果col1的类型为String,则类似于

    SelectedFirstComparator<GridEntity> col1Comparator = 
        new SelectedFirstComparator<GridEntity>( grid, (e11, e12) -> {
            return e11.getName().compareTo(e12.getName());
        }
    );
    

    第4点

    要使比较器或监视器排序顺序和sort()方法更新sortOrder,您需要将所有比较器注册为网格SortListener

    grid.addSortListener(col1Comparator);
    grid.addSortListener(col2Comparator);
    ...