package org.drools.guvnor.client.table; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import com.google.gwt.user.cellview.client.CellTable; /** * @author Geoffrey De Smet */ public class SortableHeaderGroup<T extends Comparable> { private final CellTable<T> cellTable; // TODO change List into Deque after upgrade to java 6 private List<SortableHeader<T, ?>> sortOrderList = new LinkedList<SortableHeader<T, ?>>(); public SortableHeaderGroup(CellTable<T> cellTable) { this.cellTable = cellTable; } public void headerClicked(SortableHeader<T, ?> header) { updateSortOrder(header); cellTable.redrawHeaders(); updateData(); } private void updateSortOrder(SortableHeader<T, ?> header) { int index = sortOrderList.indexOf(header); if (index == 0) { if (header.getSortDirection() != SortDirection.ASCENDING) { header.setSortDirection(SortDirection.ASCENDING); } else { header.setSortDirection(SortDirection.DESCENDING); } } else { // Remove it if it's already sorted on this header later if (index > 0) { sortOrderList.remove(index); } header.setSortDirection(SortDirection.ASCENDING); // Bring this header to front // Deque.addFirst(sortableHeader) sortOrderList.add(0, header); // Update sortIndexes int sortIndex = 0; for (SortableHeader<T, ?> sortableHeader : sortOrderList) { sortableHeader.setSortIndex(sortIndex); sortIndex++; } } } private void updateData() { // TODO If paging is used, this should be a back-end call with a sorting meta data parameter List<T> displayedItems = new ArrayList<T>(cellTable.getDisplayedItems()); Collections.sort(displayedItems, new Comparator<T>() { public int compare(T leftRow, T rightRow) { for (SortableHeader<T, ?> sortableHeader : sortOrderList) { Comparable leftColumnValue = sortableHeader.getColumn().getValue(leftRow); Comparable rightColumnValue = sortableHeader.getColumn().getValue(rightRow); int comparison = (leftColumnValue == rightColumnValue) ? 0 : (leftColumnValue == null) ? -1 : (rightColumnValue == null) ? 1 : leftColumnValue.compareTo(rightColumnValue); if (comparison != 0) { switch (sortableHeader.getSortDirection()) { case ASCENDING: break; case DESCENDING: comparison = -comparison; break; default: throw new IllegalStateException("Sorting can only be enabled for ASCENDING or" + " DESCENDING, not sortDirection (" + sortableHeader.getSortDirection() + ") ."); } return comparison; } } return leftRow.compareTo(rightRow); } }); cellTable.setRowData(0, displayedItems); cellTable.redraw(); } }