📄 sortingtablemodel.java
字号:
package net.sf.jawp.gui.client.data;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import tuple.Pair;
import net.sf.jawp.gf.api.Entity;
/**
* Table model with support for column sorting.
* @author jarek
* @version $Revision$
*
* @param <ENTITY>
*/
public abstract class SortingTableModel<ENTITY extends Entity> extends AbstractTableModel
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* known objects
*/
private ArrayList<ENTITY> objects;
/**
* describe current sorting status
* there is list of pairs - each one defines columnIndex, and sorting order
* first pair( index 0) is most important
*/
private final ArrayList< Pair<Integer, Sorting> > order;
private final HashMap<Integer, Comparator<ENTITY> > columnComparators;
private final Comparator<ENTITY> localComparator;
private final List< SortableColumn<ENTITY> > columns;
private EntityColumnModel columnModel;
private JTableHeader tableHeader;
public SortingTableModel()
{
this.order = new ArrayList< Pair<Integer, Sorting> >();
this.columns = createColumns();
this.columnComparators = new HashMap<Integer, Comparator<ENTITY> >();
this.localComparator = new LocalTableComparator();
initColumnComparators();
}
protected abstract List< SortableColumn<ENTITY> > createColumns();
public final JTableHeader getTableHeader()
{
if ( this.tableHeader == null)
{
this.tableHeader = new JTableHeader( getColumnModel());
}
return this.tableHeader;
}
private void initColumnComparators()
{
for ( int index = 0; index < this.columns.size(); ++index )
{
this.columnComparators.put( index, this.columns.get(index).getComparator() );
}
}
public final Object getValueAt(final int rowIndex, final int colIndex)
{
final ENTITY elem = getElementAtRow(rowIndex);
return this.columns.get( colIndex).getValue( elem);
}
public final ENTITY getElementAtRow( final int index)
{
return getObjects().get(index);
}
protected abstract Collection<ENTITY> retrieveObjects();
private ArrayList<ENTITY> getObjects()
{
if ( this.objects == null)
{
final ArrayList<ENTITY> fs = new ArrayList<ENTITY>( retrieveObjects());
Collections.sort( fs, this.localComparator );
this.objects = fs;
}
return this.objects;
}
public final void refresh()
{
//this.objects = null;
//this.fireTableDataChanged(); This was very evil :-)
updateValues();
}
private void updateValues( )
{
final ArrayList<ENTITY> fs = new ArrayList<ENTITY>( retrieveObjects());
Collections.sort( fs, this.localComparator );
//checking what to update
if ( fs.size() == this.objects.size())
{
for ( int row = 0; row < this.objects.size(); ++row)
{
final ENTITY old = this.objects.get( row);
final ENTITY newObject = fs.get( row);
columnsUpdate( row, old, newObject);
}
}
else
{
fireTableDataChanged();
}
this.objects = fs;
}
private void columnsUpdate( final int row, final ENTITY old, final ENTITY newObject)
{
for (int colIndex = 0; colIndex < this.columns.size(); ++colIndex)
{
final SortableColumn<ENTITY> col = this.columns.get( colIndex);
if ( col.hasChanged( old, newObject))
{
fireTableCellUpdated(row, colIndex);
}
}
}
public int getColumnCount()
{
return this.columns.size();
}
public int getRowCount()
{
return getObjects().size();
}
/**
* Column model for this table model.
* @author jarek
* @version $Revision$
*
*/
public class EntityColumnModel
extends DefaultTableColumnModel
{
/**
*
*/
private static final long serialVersionUID = 1L;
public EntityColumnModel()
{
super();
for ( int index = 0; index < columns.size(); ++index)
{
final SortableColumn<ENTITY> col = columns.get(index);
final TableColumn tc = new TableColumn( index);
tc.setHeaderValue( col.getName());
final TableCellRenderer rend = col.getCellRenderer();
if ( rend != null)
{
tc.setCellRenderer( rend);
}
addColumn( tc );
}
}
}
private Comparator<ENTITY> getColumnComparator(final int index)
{
return this.columnComparators.get( index);
}
private class LocalTableComparator implements Comparator<ENTITY>
{
public int compare(final ENTITY f1, final ENTITY f2)
{
for ( final Pair<Integer, Sorting> sort : order)
{
if ( sort.snd != Sorting.NONE)
{
final Comparator<ENTITY> cmp = getColumnComparator( sort.fst);
final int res = cmp.compare( f1, f2);
if ( res != 0 )
{
if ( sort.snd == Sorting.DESCENDING )
{
return -res;
}
else
{
return res;
}
}
}
}
return 0;
}
}
/**
* @return null if column not on list
*/
private Pair<Integer, Sorting> findColOrder(final int colIndex)
{
for ( final Pair<Integer, Sorting> p : this.order)
{
if ( p.fst.equals(colIndex) )
{
return p;
}
}
return null;
}
protected final Sorting findColSorting( final int colIndex)
{
final Pair<Integer, Sorting> def = findColOrder( colIndex);
if (def != null)
{
return def.snd;
}
else
{
return Sorting.NONE;
}
}
/**
* changes order (from NONE to ASC, from ASC to DESC, from DESC to ASC
* puts column in front
*/
public final void changeOrder( final int colIndex)
{
final Pair<Integer, Sorting> old = findColOrder( colIndex);
Sorting srt = Sorting.NONE;
if (old != null)
{
srt = old.snd;
order.remove( old );
}
Sorting newSrt = Sorting.ASCENDING;
if (srt.equals(Sorting.ASCENDING))
{
newSrt = Sorting.DESCENDING;
}
setSorting( colIndex, newSrt);
sort();
fireTableDataChanged();
}
private void setSorting( final int colIndex, final Sorting newSrt)
{
this.order.add( 0, new Pair<Integer, Sorting> (colIndex, newSrt) );
this.getTableColumn( colIndex).setHeaderValue( this.columns.get(colIndex).getName() + " " + newSrt.toString());
}
private void resetSorting( final int colIndex)
{
this.getTableColumn( colIndex).setHeaderValue( this.columns.get(colIndex).getName());
}
public final void resetOrder( final int colIndex)
{
final Pair<Integer, Sorting> old = findColOrder( colIndex);
if (old != null)
{
order.remove( old);
resetSorting(colIndex);
sort();
fireTableDataChanged();
}
}
private void sort()
{
Collections.sort( this.objects, this.localComparator);
}
public final TableColumnModel getColumnModel()
{
if ( this.columnModel == null )
{
this.columnModel = new EntityColumnModel();
}
return this.columnModel;
}
private TableColumn getTableColumn(final int index)
{
return this.getColumnModel().getColumn( index);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -