美文网首页
如何使用JavaFX构建一个具有分页和全局排序的TabbleVi

如何使用JavaFX构建一个具有分页和全局排序的TabbleVi

作者: Huangjs1994 | 来源:发表于2018-08-07 09:47 被阅读212次

    第二步:为TableView添加全局排序功能

    1. 思路

    image.png
    • 由于不能使用内置的排序功能——分页后,内置的排序变成了局部排序,所以我们需要将内置的排序功能关闭,然后使用一个Label组件伪装成表头,设置点击事件,再点击事件中响应全局排序

    2. 实现

    1. 准备三张照片——向上的箭头(表示升序排序),向下的箭头(表示降序排序),没有箭头的空白照片(表示没有排序)可以直接截取表格自带的箭头,以假乱真。
    2. 关于全局排序,我们使用Collections提供的排序方法,
    java自带的Collections类
        public static <T> void sort(List<T> list, Comparator<? super T> c) {
            list.sort(c);
        }
    

    这个排序方法需要传入一个比较器Comparator,这里也有两种方式生成Comparator——匿名函数或Lambda表达式。

    • 使用匿名函数生成升序比较器,即age的排在前面
            Comparator<People> asc = new Comparator<People>() {
    
                @Override
                public int compare(People p1, People p2) {
                    return Integer.compare(p1.getAge(), p2.getAge());
                }
            };
    

    这里没有去写if-else if-else去排序,而是使用静态方法Integer.compare()去排序,它等价于

    if(p2.getAge() > p1.getAge()){
      return 1;
    }else if(p2.getAge() = p1.getAge()){
      return 0;
    }else{
      return -1
    }
    
    Integer.compare()方法体源码
    • 使用Lambda生成降序比较器,即age的排在前面
          Comparator<People> desc = (p1, p2) -> Integer.compare(p2.getAge(), p1.getAge());
    
    1. 在之前的类TableWithPaginationAndSorting中添加全局排序
        // 使用一个HashMap记录每个Label(表头)的当前排序状态
        private HashMap<Label, String>  orderMap = new HashMap<>();
        public void addGlobalOrdering(TableColumn<T, ?> column,
                                      Comparator<? super T> ascComparator,
                                      Comparator<? super T> descComparator) {
    
            /** label setting **/
            // set  column name to label text
            Label label = new Label(column.getText());
            label.setMinWidth(column.getMinWidth());
            label.setMaxWidth(column.getMaxWidth());
            label.setPrefWidth(column.getPrefWidth());
    
            // 初始化时默认没有排序
            orderMap.put(label, "NO");
    
            /** column setting **/
            // set built-in column name to null
            column.setText(null);
    
            // turn off built-in order in TableView
            column.setSortable(false);
    
            // make label replace original table header
            column.setGraphic(label);
    
            ImageView ascImg = new ImageView("/image-app/asc.png");
            ImageView descImg = new ImageView("/image-app/desc.png");
            ImageView noImg = new ImageView("/image-app/no.png");
    
            // set event
            label.setOnMouseClicked(mouseEvent -> {
    
                // sort only one column every time, so make other columns unsorted
                orderMap.keySet().stream().forEach(lab -> lab.setGraphic(noImg));
                switch (orderMap.get(label)) {
                    case "NO":
                        orderMap.replace(label, "ASC");
                        label.setGraphic(ascImg);
                        order(ascComparator);
                        updatePagination();
                        break;
                    case "ASC":
                        orderMap.put(label, "DESC");
                        label.setGraphic(descImg);
                        order(descComparator);
                        updatePagination();
                        break;
                    case "DESC":
                        orderMap.put(label, "ASC");
                        label.setGraphic(ascImg);
                        order(ascComparator);
                        updatePagination();
                        break;
                }
            });
        }
    
        /**
         * sort a list by given comparator
         * @param comparator
         */
        private void order(Comparator<? super T> comparator) {
            Collections.sort(page.getRowDataList(), comparator);
        }
    
    1. 将我们的新功能加入到测试类中, 只需要添加下面的代码到之前的测试类就好
     // global sorting by column age
            Comparator<People> asc = new Comparator<People>() {
    
                @Override
                public int compare(People p1, People p2) {
                    return Integer.compare(p2.getAge(), p1.getAge());
                }
            };
            Comparator<People> desc = (p1, p2) -> Integer.compare(p2.getAge(), p1.getAge());
    
            // order by column age
            table.addGlobalOrdering(peopleTable.getColumns().get(1),
                    asc,
                    desc);
    

    完整示例见:https://github.com/lhuangjs/blog/tree/master/src/main/java/javafx/tableview

    相关文章

      网友评论

          本文标题:如何使用JavaFX构建一个具有分页和全局排序的TabbleVi

          本文链接:https://www.haomeiwen.com/subject/tljnvftx.html