GWT多列单元格表排序

GWT多列单元格表排序,gwt,gwt-celltable,Gwt,Gwt Celltable,如何使用GWT Celltable对多列执行排序。我没有找到这方面的任何示例代码?请参见下图 我需要在多个列上执行服务器端排序。如何使用GWT Celltable实现这一点,以及如何为多个列添加此箭头图标。有什么线索吗?您可以使用自定义标题生成器。您可以使用下面的一个(它也支持排序序列,但如果不需要,您可以将其删除) public类multisorheaderorfooterbuilder扩展了AbstractHeaderOrFooterBuilder{ 私有静态类ColumnSortInfo

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


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

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

public类multisorheaderorfooterbuilder扩展了AbstractHeaderOrFooterBuilder{
私有静态类ColumnSortInfoHolder{
私人专栏SORTINFO ColumnSortInfo;
私人国际分类索引;
公共列目录持有者(列目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录目录){
this.columnSortInfo=columnSortInfo;
this.sortIndex=sortIndex;
}
public int getSortIndex(){
返回排序索引;
}
public ColumnSortInfo getColumnSortInfo(){
返回列sortinfo;
}
}
私有最终整型sortAscIconWidth;
私人最终整数排序半高;
私人最终int sortDescIconWidth;
私人最终int SORTDESCICONHALFHEIGH;
私有安全HTML分类码;
私人保险公司;
私有静态最终整数图标_PADDING=6;
/**
*为页脚部分的页眉创建新的DefaultHeaderBuilder。
* 
*@param表
*正在建造的桌子
*@param isFooter
*如果生成页脚,则为true;如果生成页眉,则为false
*/
公共MultiSorthHeaderOrFooterBuilder(AbstractCellTable表,布尔isFooter){
super(表,isFooter);
ImageResource asc=table.getResources().sortAscending();
ImageResource desc=table.getResources().sortDescending();
如果(asc!=null){
sortAscIconWidth=asc.getWidth()+图标填充;
sortAscIconHalfHeight=(int)Math.round(asc.getHeight()/2.0);
}否则{
sortAscIconWidth=0;
sortAscIconHalfHeight=0;
}
如果(描述!=null){
sortDescIconWidth=desc.getWidth()+图标填充;
sortDescIconHalfHeight=(int)数学
.round(desc.getHeight()/2.0);
}否则{
sortDescIconWidth=0;
SORTDESCIONHALFHEIGHT=0;
}
}
@凌驾
受保护的布尔型buildHeaderOrFooterImpl(){
AbstractCellTable=getTable();
布尔值isFooter=isBuildingFooter();
if(isFooter)
返回false;
//如果没有任何要渲染的列,则提前退出。
int columnCount=table.getColumnCount();
如果(columnCount==0){
//没有什么可以提供的;
返回false;
}
//如果要呈现的列中没有任何标题,请提前退出。
布尔hasHeader=false;
对于(int i=0;i();
//设置多重排序的排序信息
ColumnSortList sortList=table.getColumnSortList();
如果(table.getColumnSortList().size()>0){
对于(int colIdx=0,sortPos=sortList.size();colIdxpublic 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));