【问题标题】:GWT Celltable-Sorting on Multiple ColumnGWT Celltable-对多列进行排序
【发布时间】:2015-07-29 04:53:52
【问题描述】:

如何使用 GWT Celltable 对多列执行排序。我没有找到任何示例代码?见下图

我需要对多列执行服务器端排序。如何使用 GWT Celltable 实现这一点以及如何为多个列添加此箭头图标。有什么线索吗?

【问题讨论】:

    标签: gwt gwt-celltable


    【解决方案1】:

    您可以使用自定义标题生成器。你可以使用下面的(它也支持排序顺序,但如果你不需要它可以删除它)

    public class MultiSortHeaderOrFooterBuilder<T> extends AbstractHeaderOrFooterBuilder<T> {
    
        private static class ColumnSortInfoHolder {
            private ColumnSortInfo columnSortInfo;
            private int sortIndex;
    
            public ColumnSortInfoHolder(ColumnSortInfo columnSortInfo, int sortIndex) {
                this.columnSortInfo = columnSortInfo;
                this.sortIndex = sortIndex;
            }
    
            public int getSortIndex() {
                return sortIndex;
            }
    
            public ColumnSortInfo getColumnSortInfo() {
                return columnSortInfo;
            }
        }
    
        private final int sortAscIconWidth;
        private final int sortAscIconHalfHeight;
    
        private final int sortDescIconWidth;
        private final int sortDescIconHalfHeight;
    
        private SafeHtml sortAscIconHtml;
        private SafeHtml sortDescIconHtml;
    
        private static final int ICON_PADDING = 6;
    
        /**
         * Create a new DefaultHeaderBuilder for the header of footer section.
         * 
         * @param table
         *            the table being built
         * @param isFooter
         *            true if building the footer, false if the header
         */
    
        public MultiSortHeaderOrFooterBuilder(AbstractCellTable<T> table, boolean isFooter) {
            super(table, isFooter);
    
            ImageResource asc = table.getResources().sortAscending();
            ImageResource desc = table.getResources().sortDescending();
            if (asc != null) {
                sortAscIconWidth = asc.getWidth() + ICON_PADDING;
                sortAscIconHalfHeight = (int) Math.round(asc.getHeight() / 2.0);
            } else {
                sortAscIconWidth = 0;
                sortAscIconHalfHeight = 0;
            }
            if (desc != null) {
                sortDescIconWidth = desc.getWidth() + ICON_PADDING;
                sortDescIconHalfHeight = (int) Math
                        .round(desc.getHeight() / 2.0);
            } else {
                sortDescIconWidth = 0;
                sortDescIconHalfHeight = 0;
            }
        }
    
        @Override
        protected boolean buildHeaderOrFooterImpl() {
    
            AbstractCellTable<T> table = getTable();
    
            boolean isFooter = isBuildingFooter();
            if (isFooter)
                return false;
    
            // Early exit if there aren't any columns to render.
            int columnCount = table.getColumnCount();
            if (columnCount == 0) {
                // Nothing to render;
                return false;
            }
    
            // Early exit if there aren't any headers in the columns to render.
            boolean hasHeader = false;
            for (int i = 0; i < columnCount; i++) {
                if (table.getHeader(i) != null) {
                    hasHeader = true;
                    break;
                }
            }
            if (hasHeader == false) {
                return false;
            }
            HashMap<Column<?, ?>, ColumnSortInfoHolder> sortInfoByColumn = new HashMap<Column<?, ?>, ColumnSortInfoHolder>();
            // Set sorting information for multisort
            ColumnSortList sortList = table.getColumnSortList();
            if (table.getColumnSortList().size() > 0) {
                for (int colIdx = 0, sortPos = sortList.size(); colIdx < sortList.size(); colIdx++, sortPos--) {
                    ColumnSortInfo columnSortInfo = sortList.get(colIdx);
                    sortInfoByColumn.put(columnSortInfo.getColumn(), new ColumnSortInfoHolder(columnSortInfo, sortPos)); 
                }
            }
    
            // Get information about the sorted column.
            ColumnSortInfo sortedInfo = null;
            boolean isSortAscending = false;
    
            // Get the common style names.
            Style style = table.getResources().style();
            String className = isBuildingFooter() ? style.footer() : style.header();
            String sortableStyle = " " + style.sortableHeader();
    
            // Setup the first column.
            Header<?> prevHeader = getHeader(0);
            Column<T, ?> column = table.getColumn(0);
            int prevColspan = 1;
            boolean isSortable = false;
            boolean isSorted = false;
            StringBuilder classesBuilder = new StringBuilder(className);
            classesBuilder.append(" ").append(isFooter ? style.firstColumnFooter() : style.firstColumnHeader());
            if (!isFooter && column.isSortable()) {
                isSortable = true;
                sortedInfo = (sortInfoByColumn.get(column) != null) ? sortInfoByColumn.get(column).getColumnSortInfo() : null;
                isSortAscending = (sortedInfo != null) ? sortedInfo.isAscending() : false;
                isSorted = (sortedInfo != null);
            }
    
            // Loop through all column headers.
            TableRowBuilder tr = startRow();
            int curColumn;
            for (curColumn = 1; curColumn < columnCount; curColumn++) {
    
                Header<?> header = getHeader(curColumn);
    
                if (header != prevHeader) {
                    // The header has changed, so append the previous one.
                    if (isSortable) {
                        classesBuilder.append(sortableStyle);
                    }
                    if (isSorted) {
                        classesBuilder.append(getSortStyle(style, isSortAscending));
                    }
                    appendExtraStyles(prevHeader, classesBuilder);
    
                    // Render the header.
                    TableCellBuilder th = tr.startTH().colSpan(prevColspan)
                            .className(classesBuilder.toString());
                    enableColumnHandlers(th, column);
                    if (prevHeader != null) {
                        // Build the header.
                        Context context = new Context(0, curColumn - prevColspan, prevHeader.getKey());
                        // Add div element with aria button role
                        if (isSortable) {
                            th.attribute("role", "button");
                            th.tabIndex(-1);
                        }
                        renderRichSortableHeader(th, context, prevHeader, isSorted, isSortAscending, sortInfoByColumn);
                    }
                    th.endTH();
    
                    // Reset the previous header.
                    prevHeader = header;
                    prevColspan = 1;
                    classesBuilder = new StringBuilder(className);
                    isSortable = false;
                    isSorted = false;
                } else {
                    // Increment the colspan if the headers == each other.
                    prevColspan++;
                }
    
                column = table.getColumn(curColumn);
                if (!isFooter && column.isSortable()) {
                    isSortable = true;
                    sortedInfo = (sortInfoByColumn.get(column) != null) ? sortInfoByColumn.get(column).getColumnSortInfo() : null;
                    isSortAscending = (sortedInfo != null) ? sortedInfo.isAscending() : false;
                    isSorted = (sortedInfo != null);
                }
            }
    
            // Append the last header.
            if (isSortable) {
                classesBuilder.append(sortableStyle);
            }
            if (isSorted) {
                classesBuilder.append(getSortStyle(style, isSortAscending));
            }
    
            classesBuilder.append(" ").append(
                    isFooter ? style.lastColumnFooter() : style.lastColumnHeader());
    
            appendExtraStyles(prevHeader, classesBuilder);
    
            // Render the last header.
            TableCellBuilder th = tr.startTH().colSpan(prevColspan).className(classesBuilder.toString());
            enableColumnHandlers(th, column);
            if (prevHeader != null) {
                Context context = new Context(0, curColumn - prevColspan, prevHeader.getKey());
                renderRichSortableHeader(th, context, prevHeader, isSorted, isSortAscending, sortInfoByColumn);
            }
            th.endTH();
    
            classesBuilder = new StringBuilder(style.header());
            classesBuilder.append(" ").append(style.lastColumnHeader());
            th = tr.startTH().className(classesBuilder.toString());
            th.endTH();
    
            // End the row.
            tr.endTR();
    
            return true;
        }
    
        /**
         * Append the extra style names for the header.
         * 
         * @param header
         *            the header that may contain extra styles, it can be null
         * @param classesBuilder
         *            the string builder for the TD classes
         */
        private <H> void appendExtraStyles(Header<H> header, StringBuilder classesBuilder) {
            if (header == null) {
                return;
            }
            String headerStyleNames = header.getHeaderStyleNames();
            if (headerStyleNames != null) {
                classesBuilder.append(" ").append(headerStyleNames);
            }
        }
    
        private String getSortStyle(Style style, boolean isSortAscending) {
            return isSortAscending ? style.sortedHeaderAscending() : style.sortedHeaderDescending();
        }
    
        /**
         * Render a header, including a sort icon if the column is sortable and
         * sorted.
         * 
         * @param out
         *            the builder to render into
         * @param header
         *            the header to render
         * @param context
         *            the context of the header
         * @param isSorted
         *            true if the column is sorted
         * @param isSortAscending
         *            indicated the sort order, if sorted
         */
        protected void renderRichSortableHeader(ElementBuilderBase<?> out,
                Context context, Header<?> header, boolean isSorted,
                boolean isSortAscending,
                HashMap<Column<?, ?>, ColumnSortInfoHolder> sortIndexByColumn) {
    
            AbstractCellTable<T> table = getTable();
    
            ElementBuilderBase<?> headerContainer = out;
            boolean posRight = LocaleInfo.getCurrentLocale().isRTL();
            int iconWidth = 0;
            int sortIndexWidth = 0;
    
            if (isSorted) {
                // Create an outer container to hold the icon and the header.
                iconWidth = isSortAscending ? sortAscIconWidth : sortDescIconWidth;
                int halfHeight = isSortAscending ? sortAscIconHalfHeight : sortDescIconHalfHeight;
                DivBuilder outerDiv = out.startDiv();
                StylesBuilder style = outerDiv.style().position(Position.RELATIVE).trustedProperty("zoom", "1");
    
                style.endStyle();
    
                // Add the icon.
                DivBuilder imageHolder = outerDiv.startDiv();
                style = outerDiv.style().position(Position.ABSOLUTE).top(50.0, Unit.PCT).lineHeight(0.0, Unit.PX).marginTop(-halfHeight, Unit.PX);
                if (posRight) {
                    style.right(0, Unit.PX);
                } else {
                    style.left(0, Unit.PX);
                }
                style.overflow(Overflow.VISIBLE).endStyle();
    
                imageHolder.html(getSortIcon(isSortAscending));
                imageHolder.endDiv();
    
                if (table.getColumnSortList().size() > 0) {
    
                    DivBuilder sortIndexHolder = outerDiv.startDiv();
                    style = sortIndexHolder.style().position(Position.ABSOLUTE).top(0.0, Unit.PCT);
                    sortIndexWidth = iconWidth - 2;
                    if (posRight) {
                        style.right(sortIndexWidth, Unit.PX);
                    } else {
                        style.left(sortIndexWidth, Unit.PX);
                    }
    
                    Column<T, ?> column = table.getColumn(context.getColumn());
                    String sortIdx = String.valueOf(sortIndexByColumn.get(column).getSortIndex());
                    sortIndexHolder.html(SafeHtmlUtils.fromTrustedString(sortIdx));
                    sortIndexHolder.endDiv();
                }
    
                // Create the header wrapper.
                headerContainer = outerDiv.startDiv();
            }
    
            StylesBuilder style = headerContainer.style().position(Position.RELATIVE);
            if (posRight) {
                style.paddingRight(iconWidth + sortIndexWidth + 7, Unit.PX);
            } else {
                style.paddingLeft(iconWidth + sortIndexWidth + 7, Unit.PX);
            }
            style.endStyle();
    
            // Build the header.
            renderHeader(headerContainer, context, header);
    
            // Close the elements used for the sort icon.
            if (isSorted) {
                headerContainer.endDiv(); // headerContainer.
                headerContainer.endDiv(); // outerDiv
            }
        }
    
        private SafeHtml getSortIcon(boolean isAscending) {
            AbstractCellTable<T> table = getTable();
            if (isAscending) {
                if (sortAscIconHtml == null) {
                    AbstractImagePrototype proto = AbstractImagePrototype.create(table.getResources().sortAscending());
                    sortAscIconHtml = SafeHtmlUtils.fromTrustedString(proto.getHTML());
                }
                return sortAscIconHtml;
            } else {
                if (sortDescIconHtml == null) {
                    AbstractImagePrototype proto = AbstractImagePrototype.create(table.getResources().sortDescending());
                    sortDescIconHtml = SafeHtmlUtils.fromTrustedString(proto.getHTML());
                }
                return sortDescIconHtml;
            }
        }
    }
    

    你是这样设置的

    CellTable<Contact> table = new CellTable<Contact>();
    table.setHeaderBuilder(new MultiSortHeaderOrFooterBuilder<TableComponent.Contact>(table, false));
    

    【讨论】:

    • 对不起 Alkis,我没有尝试过这种方法..但无论如何(+1)
    • 没问题。感谢您的支持。如果您找到时间,请发布您决定遵循的方法,以便其他人也可以受益。不一定是代码。玩得开心
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    相关资源
    最近更新 更多