org.ka2ddo.yaac.gui.table
Class FastTableRowSorter<M extends javax.swing.table.TableModel>

java.lang.Object
  extended by javax.swing.RowSorter<M>
      extended by org.ka2ddo.yaac.gui.table.FastTableRowSorter<M>

public class FastTableRowSorter<M extends javax.swing.table.TableModel>
extends javax.swing.RowSorter<M>

This class provides a replacement for javax.swing.TableRowSorter that does not excessively malloc transient objects (and therefore runs much faster when extremely large tables > 100000 rows are being used). We shall see if the embedded sort algorithm is acceptable, or whether we need to go back to the copying mergesort as used in the Arrays class.

To get its speed-ups, this Sorter makes a few assumptions:

  1. the caller will never specify a column index exceeding the valid indexes for the associated TableModel
  2. all columns are sortable, so the setSortable() method isn't needed

See Also:
FastRowFilter

Nested Class Summary
 
Nested classes/interfaces inherited from class javax.swing.RowSorter
javax.swing.RowSorter.SortKey
 
Constructor Summary
FastTableRowSorter(M model)
          Creates a TableRowSorter using model as the underlying TableModel.
 
Method Summary
 void allRowsChanged()
          
 int convertRowIndexToModel(int index)
          
 int convertRowIndexToView(int index)
          
 java.util.Comparator<?> getComparator(int column)
          Returns the Comparator for the specified column.
 int getMaxSortKeys()
          Returns the maximum number of sort keys.
 M getModel()
          Returns the underlying model.
 int getModelRowCount()
          
 FastRowFilter<? super M> getRowFilter()
          Returns the filter that determines which rows, if any, should be hidden from view.
 java.util.List<? extends javax.swing.RowSorter.SortKey> getSortKeys()
          Returns the current sort keys.
 boolean getSortsOnUpdates()
          Returns true if a sort should happen when the underlying model is updated; otherwise, returns false.
 int getViewRowCount()
          
 void modelStructureChanged()
          
 void rowsDeleted(int firstRow, int endRow)
          
 void rowsInserted(int firstRow, int endRow)
          
 void rowsUpdated(int firstRow, int endRow)
          
 void rowsUpdated(int firstRow, int endRow, int column)
          
 void setComparator(int column, java.util.Comparator<?> comparator)
          Sets the Comparator to use when sorting the specified column.
 void setMaxSortKeys(int max)
          Sets the maximum number of sort keys.
 void setRowFilter(FastRowFilter<? super M> filter)
          Sets the filter that determines which rows, if any, should be hidden from the view.
 void setSortKeys(java.util.List<? extends javax.swing.RowSorter.SortKey> sortKeys)
          Sets the sort keys.
 void setSortsOnUpdates(boolean sortsOnUpdates)
          If true, specifies that a sort should happen when the underlying model is updated (rowsUpdated is invoked).
 void sort()
          Sorts and filters the rows in the view based on the sort keys of the columns currently being sorted and the filter, if any, associated with this sorter.
 void toggleSortOrder(int column)
          Reverses the sort order from ascending to descending (or descending to ascending) if the specified column is already the primary sorted column; otherwise, makes the specified column the primary sorted column, with an ascending sort order.
protected  boolean useToString(int column)
           
 
Methods inherited from class javax.swing.RowSorter
addRowSorterListener, fireRowSorterChanged, fireSortOrderChanged, removeRowSorterListener
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

FastTableRowSorter

public FastTableRowSorter(M model)
Creates a TableRowSorter using model as the underlying TableModel.

Parameters:
model - the underlying TableModel to use, null is treated as an empty model
Method Detail

getModel

public final M getModel()
Returns the underlying model.

Specified by:
getModel in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>
Returns:
the underlying model

getComparator

public java.util.Comparator<?> getComparator(int column)
Returns the Comparator for the specified column. If a Comparator has not been specified using the setComparator method a Comparator will be returned based on the column class (TableModel.getColumnClass) of the specified column. If the column class is String, Collator.getInstance is returned. If the column class implements Comparable a private Comparator is returned that invokes the compareTo method. Otherwise Collator.getInstance is returned.

Parameters:
column - int zero-based column index into table model
Returns:
Comparator instance to use for the specified column
Throws:
java.lang.IndexOutOfBoundsException - if column number is out of range for the associated table model

useToString

protected boolean useToString(int column)

setSortKeys

public void setSortKeys(java.util.List<? extends javax.swing.RowSorter.SortKey> sortKeys)
Sets the sort keys. This creates a copy of the supplied List; subsequent changes to the supplied List do not effect this DefaultRowSorter. If the sort keys have changed this triggers a sort.

Specified by:
setSortKeys in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>
Parameters:
sortKeys - the new SortKeys; null is a shorthand for specifying an empty list, indicating that the view should be unsorted
Throws:
java.lang.IllegalArgumentException - if any of the values in sortKeys are null or have a column index outside the range of the model

getSortKeys

public java.util.List<? extends javax.swing.RowSorter.SortKey> getSortKeys()
Returns the current sort keys. This returns an unmodifiable non-null List. If you need to change the sort keys, make a copy of the returned List, mutate the copy and invoke setSortKeys with the new list.

Specified by:
getSortKeys in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>
Returns:
the current sort order

setMaxSortKeys

public void setMaxSortKeys(int max)
Sets the maximum number of sort keys. The number of sort keys determines how equal values are resolved when sorting. For example, assume a table row sorter is created and setMaxSortKeys(2) is invoked on it. The user clicks the header for column 1, causing the table rows to be sorted based on the items in column 1. Next, the user clicks the header for column 2, causing the table to be sorted based on the items in column 2; if any items in column 2 are equal, then those particular rows are ordered based on the items in column 1. In this case, we say that the rows are primarily sorted on column 2, and secondarily on column 1. If the user then clicks the header for column 3, then the items are primarily sorted on column 3 and secondarily sorted on column 2. Because the maximum number of sort keys has been set to 2 with setMaxSortKeys, column 1 no longer has an effect on the order.

The maximum number of sort keys is enforced by toggleSortOrder. You can specify more sort keys by invoking setSortKeys directly and they will all be honored. However if toggleSortOrder is subsequently invoked the maximum number of sort keys will be enforced. The default value is 3.

Parameters:
max - the maximum number of sort keys
Throws:
java.lang.IllegalArgumentException - if max < 1

getMaxSortKeys

public int getMaxSortKeys()
Returns the maximum number of sort keys.

Returns:
the maximum number of sort keys

setSortsOnUpdates

public void setSortsOnUpdates(boolean sortsOnUpdates)
If true, specifies that a sort should happen when the underlying model is updated (rowsUpdated is invoked). For example, if this is true and the user edits an entry the location of that item in the view may change. The default is false.

Parameters:
sortsOnUpdates - whether or not to sort on update events

getSortsOnUpdates

public boolean getSortsOnUpdates()
Returns true if a sort should happen when the underlying model is updated; otherwise, returns false.

Returns:
whether or not to sort when the model is updated

setRowFilter

public void setRowFilter(FastRowFilter<? super M> filter)
Sets the filter that determines which rows, if any, should be hidden from the view. The filter is applied before sorting. A value of null indicates all values from the model should be included.

FastRowFilter's include method is passed the underlying model. The identifier is the row index into the model.

This method triggers a sort.

Parameters:
filter - the filter used to determine what entries should be included

getRowFilter

public FastRowFilter<? super M> getRowFilter()
Returns the filter that determines which rows, if any, should be hidden from view.

Returns:
the filter

toggleSortOrder

public void toggleSortOrder(int column)
Reverses the sort order from ascending to descending (or descending to ascending) if the specified column is already the primary sorted column; otherwise, makes the specified column the primary sorted column, with an ascending sort order. If the specified column is not sortable, this method has no effect.

Specified by:
toggleSortOrder in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>
Parameters:
column - index of the column to make the primary sorted column, in terms of the underlying model
Throws:
java.lang.IndexOutOfBoundsException
See Also:
setMaxSortKeys(int)

convertRowIndexToView

public int convertRowIndexToView(int index)

Specified by:
convertRowIndexToView in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>
Throws:
java.lang.IndexOutOfBoundsException

convertRowIndexToModel

public int convertRowIndexToModel(int index)

Specified by:
convertRowIndexToModel in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>
Throws:
java.lang.IndexOutOfBoundsException

sort

public void sort()
Sorts and filters the rows in the view based on the sort keys of the columns currently being sorted and the filter, if any, associated with this sorter. An empty sortKeys list indicates that the view should unsorted, the same as the model.

See Also:
setRowFilter(org.ka2ddo.yaac.gui.table.FastRowFilter), setSortKeys(java.util.List)

setComparator

public void setComparator(int column,
                          java.util.Comparator<?> comparator)
Sets the Comparator to use when sorting the specified column. This does not trigger a sort. If you want to sort after setting the comparator you need to explicitly invoke sort.

Parameters:
column - the index of the column the Comparator is to be used for, in terms of the underlying model
comparator - the Comparator to use
Throws:
java.lang.IndexOutOfBoundsException - if column is outside the range of the underlying model

getViewRowCount

public int getViewRowCount()

Specified by:
getViewRowCount in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>

getModelRowCount

public int getModelRowCount()

Specified by:
getModelRowCount in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>

modelStructureChanged

public void modelStructureChanged()

Specified by:
modelStructureChanged in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>

allRowsChanged

public void allRowsChanged()

Specified by:
allRowsChanged in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>

rowsInserted

public void rowsInserted(int firstRow,
                         int endRow)

Specified by:
rowsInserted in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>
Throws:
java.lang.IndexOutOfBoundsException

rowsDeleted

public void rowsDeleted(int firstRow,
                        int endRow)

Specified by:
rowsDeleted in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>
Throws:
java.lang.IndexOutOfBoundsException

rowsUpdated

public void rowsUpdated(int firstRow,
                        int endRow)

Specified by:
rowsUpdated in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>
Throws:
java.lang.IndexOutOfBoundsException

rowsUpdated

public void rowsUpdated(int firstRow,
                        int endRow,
                        int column)

Specified by:
rowsUpdated in class javax.swing.RowSorter<M extends javax.swing.table.TableModel>
Throws:
java.lang.IndexOutOfBoundsException