📄 tablesorter.java
字号:
//return getViewToModel()[viewIndex].modelIndex;
}
int[] getModelToView()
{
if ( modelToView == null )
{
int n = getViewToModel().length;
modelToView = new int[n];
for( int i = 0; i < n; i++ )
{
modelToView[modelIndex( i )] = i;
}
}
return modelToView;
}
// TableModel interface methods
public int getRowCount()
{
return ( tableModel == null ) ? 0 : tableModel.getRowCount();
}
public int getColumnCount()
{
return ( tableModel == null ) ? 0 : tableModel.getColumnCount();
}
public String getColumnName( int column )
{
return tableModel.getColumnName( column );
}
public Class getColumnClass( int column )
{
return tableModel.getColumnClass( column );
}
public boolean isCellEditable( int row, int column )
{
return tableModel.isCellEditable( modelIndex( row ), column );
}
public Object getValueAt( int row, int column )
{
return tableModel.getValueAt( modelIndex( row ), column );
}
public void setValueAt( Object aValue, int row, int column )
{
tableModel.setValueAt( aValue, modelIndex( row ), column );
}
// Helper classes
private class Row implements Comparable
{
int modelIndex;
public Row( int index )
{
this.modelIndex = index;
}
public int compareTo( Object o )
{
int row1 = modelIndex;
int row2 = ( ( Row )o ).modelIndex;
for( Iterator it = sortingColumns.iterator(); it.hasNext(); )
{
Directive directive = ( Directive )it.next();
int column = directive.column;
Object o1 = tableModel.getValueAt( row1, column );
Object o2 = tableModel.getValueAt( row2, column );
int comparison = 0;
// Define null less than everything, except null.
if ( o1 == null && o2 == null )
{
comparison = 0;
}
else if ( o1 == null )
{
comparison = -1;
}
else if ( o2 == null )
{
comparison = 1;
}
else
{
comparison = getComparator( column ).compare( o1, o2 );
}
if ( comparison != 0 )
{
return directive.direction == DESCENDING ? -comparison : comparison;
}
}
return 0;
}
}
private class TableModelHandler implements TableModelListener
{
public void tableChanged( TableModelEvent e )
{
// If we're not sorting by anything, just pass the event along.
if ( !isSorting() )
{
clearSortingState();
fireTableChanged( e );
return;
}
// If the table structure has changed, cancel the sorting; the
// sorting columns may have been either moved or deleted from
// the model.
if ( e.getFirstRow() == TableModelEvent.HEADER_ROW )
{
cancelSorting();
fireTableChanged( e );
return;
}
// We can map a cell event through to the view without widening
// when the following conditions apply:
//
// a) all the changes are on one row (e.getFirstRow() ==
// e.getLastRow()) and,
// b) all the changes are in one column (column !=
// TableModelEvent.ALL_COLUMNS) and,
// c) we are not sorting on that column (getSortingStatus(column) ==
// NOT_SORTED) and,
// d) a reverse lookup will not trigger a sort (modelToView != null)
//
// Note: INSERT and DELETE events fail this test as they have column
// == ALL_COLUMNS.
//
// The last check, for (modelToView != null) is to see if
// modelToView
// is already allocated. If we don't do this check; sorting can
// become
// a performance bottleneck for applications where cells
// change rapidly in different parts of the table. If cells
// change alternately in the sorting column and then outside of
// it this class can end up re-sorting on alternate cell updates -
// which can be a performance problem for large tables. The last
// clause avoids this problem.
int column = e.getColumn();
if ( e.getFirstRow() == e.getLastRow() && column != TableModelEvent.ALL_COLUMNS
&& getSortingStatus( column ) == NOT_SORTED && modelToView != null )
{
int viewIndex = getModelToView()[e.getFirstRow()];
fireTableChanged( new TableModelEvent( TableSorter.this, viewIndex, viewIndex, column, e.getType() ) );
return;
}
// Something has happened to the data that may have invalidated the
// row order.
clearSortingState();
fireTableDataChanged();
return;
}
}
private class MouseHandler extends MouseAdapter
{
public void mouseClicked( MouseEvent e )
{
JTableHeader h = ( JTableHeader )e.getSource();
TableColumnModel columnModel = h.getColumnModel();
int viewColumn = columnModel.getColumnIndexAtX( e.getX() );
int column = columnModel.getColumn( viewColumn ).getModelIndex();
if ( column != -1 )
{
int status = getSortingStatus( column );
if ( !e.isControlDown() )
{
cancelSorting();
}
// Cycle the sorting states through {NOT_SORTED, ASCENDING,
// DESCENDING} or
// {NOT_SORTED, DESCENDING, ASCENDING} depending on whether
// shift is pressed.
status = status + ( e.isShiftDown() ? -1 : 1 );
status = ( status + 4 ) % 3 - 1; // signed mod, returning {-1,
// 0, 1}
setSortingStatus( column, status );
}
}
}
private static class Arrow implements Icon
{
private boolean descending;
private int size;
private int priority;
public Arrow( boolean descending, int size, int priority )
{
this.descending = descending;
this.size = size;
this.priority = priority;
}
public void paintIcon( Component c, Graphics g, int x, int y )
{
Color color = c == null ? Color.GRAY : c.getBackground();
// In a compound sort, make each succesive triangle 20%
// smaller than the previous one.
int dx = ( int )( size / 2 * Math.pow( 0.8, priority ) );
int dy = descending ? dx : -dx;
// Align icon (roughly) with font baseline.
y = y + 5 * size / 6 + ( descending ? -dy : 0 );
int shift = descending ? 1 : -1;
g.translate( x, y );
// Right diagonal.
g.setColor( color.darker() );
g.drawLine( dx / 2, dy, 0, 0 );
g.drawLine( dx / 2, dy + shift, 0, shift );
// Left diagonal.
g.setColor( color.brighter() );
g.drawLine( dx / 2, dy, dx, 0 );
g.drawLine( dx / 2, dy + shift, dx, shift );
// Horizontal line.
if ( descending )
{
g.setColor( color.darker().darker() );
}
else
{
g.setColor( color.brighter().brighter() );
}
g.drawLine( dx, 0, 0, 0 );
g.setColor( color );
g.translate( -x, -y );
}
public int getIconWidth()
{
return size;
}
public int getIconHeight()
{
return size;
}
}
private class SortableHeaderRenderer implements TableCellRenderer
{
TableCellRenderer tableCellRenderer;
public SortableHeaderRenderer( TableCellRenderer tableCellRenderer )
{
this.tableCellRenderer = tableCellRenderer;
}
public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column )
{
Component c = tableCellRenderer.getTableCellRendererComponent( table, value, isSelected, hasFocus, row,
column );
if ( c instanceof JLabel )
{
JLabel l = ( JLabel )c;
l.setHorizontalTextPosition( SwingConstants.LEFT );
int modelColumn = table.convertColumnIndexToModel( column );
l.setIcon( getHeaderRendererIcon( modelColumn, l.getFont().getSize() ) );
}
return c;
}
}
private static class Directive
{
int column;
int direction;
public Directive( int column, int direction )
{
this.column = column;
this.direction = direction;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -