package de.muntjak.tinylookandfeel.controlpanel; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.Vector; import javax.swing.JTable; import de.muntjak.tinylookandfeel.table.SortableTableData; /** * An example table model implementing SortableTableData. See * de.muntjak.tinylookandfeel.controlpanel.NonSortableTableModel for details * about the data structure. * * @author Hans Bickel */ @SuppressWarnings ( { "all" } ) public class TinyTableModel extends NonSortableTableModel implements SortableTableData { public TinyTableModel () { super ( true ); } // SortableTableData implementation public boolean isColumnSortable ( int column ) { // Note: For TinyTableModel this works fine. You may // take another approach depending on your kind of data. if ( data.isEmpty () ) return false; // value at column #1 is of type Icon (which doesn't implement Comparable) return ( getValueAt ( 0, column ) instanceof Comparable ); } public boolean supportsMultiColumnSort () { // We support multi column sort return true; } public void sortColumns ( final int [] columns, final int [] sortingDirections, JTable table ) { // Prerequisites for restoring the selection int [] sr = table.getSelectedRows (); int [] sc = table.getSelectedColumns (); int rowIndex = 0; Iterator ii = data.iterator (); while ( ii.hasNext () ) { ( ( Record ) ii.next () ).setOldRow ( rowIndex++ ); } // The sorting part... if ( columns.length == 0 ) { // The natural order of our data depends on first (Integer) column Collections.sort ( data, new Comparator () { public int compare ( Object o1, Object o2 ) { // For our data we know that arguments are // non-null and are of type Record. Record r1 = ( Record ) o1; Record r2 = ( Record ) o2; Comparable val1 = ( Comparable ) r1.getValueAt ( 0 ); Comparable val2 = ( Comparable ) r2.getValueAt ( 0 ); return val1.compareTo ( val2 ); } } ); } else { // Multi column sort Collections.sort ( data, new Comparator () { public int compare ( Object o1, Object o2 ) { // For our data we know that arguments are // non-null and are of type Record. Record r1 = ( Record ) o1; Record r2 = ( Record ) o2; for ( int i = 0 ; i < columns.length ; i++ ) { Comparable val1 = ( Comparable ) r1.getValueAt ( columns [ i ] ); Comparable val2 = ( Comparable ) r2.getValueAt ( columns [ i ] ); int result = val1.compareTo ( val2 ); if ( result != 0 ) { if ( sortingDirections [ i ] == SORT_DESCENDING ) { return -result; } return result; } } return 0; } } ); } // Tell our listeners that data has changed fireTableDataChanged (); // Restore selection rowIndex = 0; ii = data.iterator (); while ( ii.hasNext () ) { ( ( Record ) ii.next () ).setNewRow ( rowIndex++ ); } Vector temp = ( Vector ) data.clone (); Collections.sort ( temp, new Comparator () { public int compare ( Object o1, Object o2 ) { Record r1 = ( Record ) o1; Record r2 = ( Record ) o2; if ( r1.getOldRow () > r2.getOldRow () ) return 1; return -1; } } ); // Adding one row selection interval after another is // probably inefficient. for ( int i = 0 ; i < sr.length ; i++ ) { int row = ( ( Record ) temp.get ( sr [ i ] ) ).getNewRow (); table.addRowSelectionInterval ( row, row ); } for ( int i = 0 ; i < sc.length ; i++ ) { table.addColumnSelectionInterval ( sc [ i ], sc [ i ] ); } } }