org.afcs.warts.gui
Class TableSorter

java.lang.Object
  extended byjavax.swing.table.AbstractTableModel
      extended byorg.afcs.warts.gui.TableMap
          extended byorg.afcs.warts.gui.TableSorter
All Implemented Interfaces:
java.util.EventListener, java.io.Serializable, javax.swing.table.TableModel, javax.swing.event.TableModelListener

public final class TableSorter
extends TableMap

The TableSorter class adds sorting functionality to a TableModel instance, and can be integrated with a JTable to update the sort order whenever the user clicks on a column in the table header.

TableSorter does not store or copy the data in the TableModel, instead it maintains an array of integers which it keeps the same size as the number of rows in its model. When the model changes it notifies the sorter that something has changed eg. "rowsAdded" so that its internal array of integers can be reallocated. As requests are made of the sorter (like getValueAt(row, col) it redirects them to its model via the mapping array. That way the TableSorter appears to hold another copy of the table with the rows in a different order. The sorting algorthm used is stable which means that it does not move around rows when its comparison function returns 0 to denote that they are equivalent.

A TableSorter instance can be added as a mouse listener to a JTable using the listenTo(JTable) method. The TableSorter can then handle all events on behalf of the client, re-sorting data every time the user clicks on a column in the table header, and updating the icons in the header to reflect the current sort order.

This implementation is based on version 1.5 of Philip Milne's classic TableSorter code (I can't find the original implementation, but google finds lots of other people using it), but has been streamlined substantially with numerous major API changes.

LICENSE: This code is released to the public domain and may be used for any purpose whatsoever without permission or acknowledgment.

Version:
Last Modified 2 September 2003
Author:
Philip Milne & Warren Hedley ( whedley at sdsc dot edu )
See Also:
Serialized Form

Field Summary
 
Fields inherited from class javax.swing.table.AbstractTableModel
listenerList
 
Constructor Summary
TableSorter(javax.swing.table.TableModel model)
          Constructs a new instance with the underlying model providing the unsorted data.
 
Method Summary
 int getOriginalRowIndex(int rowIndex)
          Given the index of a row in the sorted model, this method returns the index of the same row in the unsorted model that was passed to this instance at initialisation.
 int getSortColumn()
          Returns the index of the last column sorted on, or -1 if the model received at initialisation has no columns.
 java.lang.Object getValueAt(int rowIndex, int columnIndex)
          This method returns the object at the specified row and column in the sorted table model.
 boolean isSortAscending()
          Returns true if the current sort column was last sorted in ascending direction.
 void listenTo(javax.swing.JTable table)
          This method adds the current instance as a mouse listener to the header of the specified table.
 void setValueAt(java.lang.Object value, int rowIndex, int columnIndex)
          This method sets the object at the specified row and column in the sorted table model.
 void sort(int columnIndex, boolean sortAscending)
          This method can be used to trigger a sort on the specified column in the specified direction.
 void tableChanged(javax.swing.event.TableModelEvent tableModelEvent)
          This will be called by the underlying table model whenever the contents of the table are changed.
 
Methods inherited from class org.afcs.warts.gui.TableMap
getColumnClass, getColumnCount, getColumnName, getModel, getRowCount, isCellEditable
 
Methods inherited from class javax.swing.table.AbstractTableModel
addTableModelListener, findColumn, fireTableCellUpdated, fireTableChanged, fireTableDataChanged, fireTableRowsDeleted, fireTableRowsInserted, fireTableRowsUpdated, fireTableStructureChanged, getListeners, getTableModelListeners, removeTableModelListener
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

TableSorter

public TableSorter(javax.swing.table.TableModel model)
Constructs a new instance with the underlying model providing the unsorted data. The initial configuration of this instance is immediately set to a sort on the values of the first column.

Parameters:
model - The model providing the unsorted data.
Method Detail

getOriginalRowIndex

public int getOriginalRowIndex(int rowIndex)
Given the index of a row in the sorted model, this method returns the index of the same row in the unsorted model that was passed to this instance at initialisation.

Parameters:
rowIndex - The row index in the sorted model to look up.
Returns:
The index of the specified row in the sorted model in the unsorted model
Throws:
java.lang.IllegalArgumentException - If rowIndex is out of bounds.

getSortColumn

public int getSortColumn()
Returns the index of the last column sorted on, or -1 if the model received at initialisation has no columns.

Returns:
The index of the last column sorted on, or -1 if the model received at initialisation has no columns.

getValueAt

public java.lang.Object getValueAt(int rowIndex,
                                   int columnIndex)
This method returns the object at the specified row and column in the sorted table model.

Specified by:
getValueAt in interface javax.swing.table.TableModel
Overrides:
getValueAt in class TableMap
Parameters:
rowIndex - The row to return data from.
columnIndex - The column to return data from.
Returns:
The object at the specified row and column in the sorted data model.

isSortAscending

public boolean isSortAscending()
Returns true if the current sort column was last sorted in ascending direction. False is returned if no sort has yet been performed.

Returns:
True if the current sort column was last sorted in ascending direction.

listenTo

public void listenTo(javax.swing.JTable table)
This method adds the current instance as a mouse listener to the header of the specified table. Whenever it detects a click on a column header, it will cause the selected column to be sorted in the appropriate direction. Column selection is also disabled.

Parameters:
table - The table to listen to.
Throws:
java.lang.NullPointerException - If table is null.

setValueAt

public void setValueAt(java.lang.Object value,
                       int rowIndex,
                       int columnIndex)
This method sets the object at the specified row and column in the sorted table model. The object is passed through to the appropriate row in the unsorted model.

Specified by:
setValueAt in interface javax.swing.table.TableModel
Overrides:
setValueAt in class TableMap
Parameters:
value - The new value.
rowIndex - The row to set data in.
columnIndex - The column to set data in.

sort

public void sort(int columnIndex,
                 boolean sortAscending)
This method can be used to trigger a sort on the specified column in the specified direction. It is used internally when sorting at initialisation and when the user clicks on a JTable header that this instance is listenining to.

Parameters:
columnIndex - The column to sort on.
sortAscending - True if the sort should be ascending.
Throws:
java.lang.IllegalArgumentException - If columnIndex is out of bounds.

tableChanged

public void tableChanged(javax.swing.event.TableModelEvent tableModelEvent)
This will be called by the underlying table model whenever the contents of the table are changed. The indices are reallocated, and the superclass is used to notify any listeners of the change.

Specified by:
tableChanged in interface javax.swing.event.TableModelListener
Overrides:
tableChanged in class TableMap
Parameters:
tableModelEvent - Details of the event.