繁体   English   中英

覆盖Tapestry的Grid列排序行为

[英]Overriding Tapestry's Grid column sorting behvior

我有一个页面使用Grid表,其中可以对一个或多个列进行排序。 问题是挂毯似乎按ASCII值排序,这意味着AZ在az之前。 我希望对它进行排序,以使A和a在Z和z之前,或者是真正的字母而不是ASCII字母。

我可以在setupRender阶段正确地对值进行排序,但是问题是用户可以随时单击列标题中的排序图标,并且列的排序方式将恢复为ASCII方式。

我查看了Grid,GridSortModel和ColumnSort的文档,发现没有任何有用的方法可以替代此行为。 我对挂毯非常陌生,但是到目前为止文档对您没有帮助,而且我找不到在线上回答此问题的另一个问题。

我使用的挂毯版本为5.3.6。

谢谢。

编辑:这是一些更多的上下文。 网格是在.tml文件中定义的,如下所示:

<table t:type="grid" t:id="productGrid"
model="productModel" source="products" row="product"
                class="product-grid" inPlace="true"
                pagerPosition="both" style="width: 90%"
                include="name,processors,actions" >

然后在java文件中定义产品列表,如下所示:

@Inject
private IProductConfigurationService _productService;
@Persist
private Set<IProductConfiguration> _products;
. . . .
_products = _productService.getProductConfigurations();

然后,通过修改_products,我可以修改表/网格的顺序。

好吧,我终于弄明白了。 挂毯对我来说还是个谜,但是有人用IRL帮助了我:

您必须用自己的替换默认的GridDataSource类。 注意,此代码可能可以重构,但是我现在使用的代码如下所示:

public class MyGridDataSource implements GridDataSource {
    private final List list;

    public MyGridDataSource(final Collection collection) {
        assert collection != null;
        list = CollectionFactory.newList(collection);
    }

    public int getAvailableRows() {
        return list.size();
    }

    public void prepare(int startIndex, int endIndex, List<SortConstraint> sortConstraints) {
        for (SortConstraint constraint : sortConstraints) {
            final ColumnSort sort = constraint.getColumnSort();
            if (sort == ColumnSort.UNSORTED) {
                continue;
            }

            final PropertyConduit conduit = constraint.getPropertyModel().getConduit();

            final Comparator valueComparator = new Comparator<Comparable>() {
                public int compare(Comparable o1, Comparable o2) {
                    if (o1 == null) {
                        return 1;
                    }

                    if (o2 == null) {
                        return -1;
                    }

                    String name1 = (String) o1;
                    String name2 = (String) o2;

                    for (int i = 0; i < Math.min(name1.length(), name2.length()); i++) {
                        Character c1 = name1.charAt(i);
                        Character c2 = name2.charAt(i);
                        Character C1 = Character.toUpperCase(c1);
                        Character C2 = Character.toUpperCase(c2);
                        int diff = 0;

                        // if the letters are different and different case, then....
                        // this allows "a" to come before "Z" for instance
                        if (c1.compareTo(c2) != 0 && C1.compareTo(C2) != 0 && 
                                c1.compareTo(c2) != C1.compareTo(C2)) {
                            diff = C1.compareTo(C2);
                        } else {
                            diff = c1.compareTo(c2);
                        }

                        if (diff != 0) {
                            return diff;
                        }
                    }

                    // shorter strings come first
                    return name1.length() - name2.length();
                }
            };

            final Comparator rowComparator = new Comparator() {
                public int compare(Object row1, Object row2) {
                    Comparable value1 = (Comparable) conduit.get(row1);
                    Comparable value2 = (Comparable) conduit.get(row2);

                    return valueComparator.compare(value1, value2);
                }
            };

            final Comparator reverseComparator = new Comparator() {
                public int compare(Object o1, Object o2) {
                    int modifier = sort == ColumnSort.ASCENDING ? 1 : -1;
                    return modifier * rowComparator.compare(o1, o2);
                }
            };

            Collections.sort(list, reverseComparator);
        }
    }

    public Class getRowType() {
        return list.isEmpty() ? null : list.get(0).getClass();
    }

    public Object getRowValue(int index) {
        return list.get(index);
    }

    public List getList() {
        return list;
    }
}

好的,那么您就可以使用此类作为数据类型。 (如果您未指定,tapestry显然会使用DefaultGridDataSource自动包装您的网格数据)。

这意味着上面的代码只需更改为:

@Inject
private IProductConfigurationService _productService;
@Persist
private MyGridDataSource _products;
. . . .
_products = new MyGridDataSource(productService.getProductConfigurations());

这是覆盖默认排序行为的一种方法。 大概应该比这容易。 但这有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM