/**
  * Sort the grid according to the specified column. If the column is already sorted, reverse sort
  * it.
  *
  * @param column the column to sort
  * @throws IndexOutOfBoundsException
  */
 public void sortColumn(int column) {
   if (column == columnSortList.getPrimaryColumn()) {
     sortColumn(column, !columnSortList.isPrimaryAscending());
   } else {
     sortColumn(column, true);
   }
 }
    @Override
    public void onSortColumn(
        SortableGrid grid, ColumnSortList sortList, SortableGrid.ColumnSorterCallback callback) {
      // Get the primary column and sort order
      int column = sortList.getPrimaryColumn();
      boolean ascending = sortList.isPrimaryAscending();

      // Get all of the cell elements
      SelectionGridCellFormatter formatter = grid.getSelectionGridCellFormatter();
      int rowCount = grid.getRowCount();
      List<Element> tdElems = new ArrayList<Element>(rowCount);
      for (int i = 0; i < rowCount; i++) {
        tdElems.add(formatter.getRawElement(i, column));
      }

      // Sort the cell elements
      if (ascending) {
        Collections.sort(
            tdElems,
            new Comparator<Element>() {
              public int compare(Element o1, Element o2) {
                return o1.getInnerText().compareTo(o2.getInnerText());
              }
            });
      } else {
        Collections.sort(
            tdElems,
            new Comparator<Element>() {
              public int compare(Element o1, Element o2) {
                return o2.getInnerText().compareTo(o1.getInnerText());
              }
            });
      }

      // Convert tdElems to trElems, reversing if needed
      Element[] trElems = new Element[rowCount];
      for (int i = 0; i < rowCount; i++) {
        trElems[i] = DOM.getParent(tdElems.get(i));
      }

      // Use the callback to complete the sorting
      callback.onSortingComplete(trElems);
    }