JTable实现排序大放送!!
前两天在这里问的,没有人回答,自己搞出来了,贡献一下,求人不如求己。
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.*;
import javax.swing.*;
import javax.swing.table.*;
public class SortableTableExample extends JPanel {
public SortableTableExample(){
setLayout(new BorderLayout());
Vector columnNames = new Vector();
columnNames.add("Name");
columnNames.add("Date");
columnNames.add("Size");
columnNames.add("Dir");
SortableTableModel dm = new SortableTableModel(columnNames, 0) {
public Class getColumnClass(int col) {
return Object.class;
}
public boolean isCellEditable(int row, int col) {
switch (col) {
case 1: return false;
default: return true;
}
}
public void setValueAt(Object obj, int row, int col) {
switch (col) {
case 2: super.setValueAt(new Integer(obj.toString()), row, col);
return;
default: super.setValueAt(obj, row, col);
return;
}
}
};
......
JTable table = new JTable(dm);
Object[] rows = {a, 2002/5/5, 1000, Hello};
dm.addRow(rows);
Object[] rows1 = {b, 2002/4/5, 1001, Test};
dm.addRow(rows1);
Object[] rows2 = {c, 2002/3/5, 1002, JTable};
dm.addRow(rows2);
Object[] rows3 = {d, 2002/2/5, 1003, God};
dm.addRow(rows3);
Object[] rows4 = {e, 2002/1/5, 1004, OK};
dm.addRow(rows4);
table.setShowVerticalLines(true);
table.setShowHorizontalLines(false);
SortButtonRenderer renderer = new SortButtonRenderer();
TableColumnModel model = table.getColumnModel();
for (int i=0;i<4;i++) {
model.getColumn(i).setHeaderRenderer(renderer);
}
JTableHeader header = table.getTableHeader();
header.addMouseListener(new HeaderListener(header,renderer));
JScrollPane pane = new JScrollPane(table);
add(pane, BorderLayout.CENTER);
}
public static void main(String[] args) {
JFrame f= new JFrame("SortableTable Example");
f.getContentPane().add(new SortableTableExample(), BorderLayout.CENTER);
f.setSize(400, 160);
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
}
private static DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.JAPAN);
private static Date getDate(String dateString) {
Date date = null;
try {
date = dateFormat.parse(dateString);
} catch(ParseException ex) {
date = new Date();
}
return date;
}
class HeaderListener extends MouseAdapter {
JTableHeader header;
SortButtonRenderer renderer;
HeaderListener(JTableHeader header,SortButtonRenderer renderer) {
this.header = header;
this.renderer = renderer;
}
public void mousePressed(MouseEvent e) {
int col = header.columnAtPoint(e.getPoint());
int sortCol = header.getTable().convertColumnIndexToModel(col);
renderer.setPressedColumn(col);
renderer.setSelectedColumn(col);
header.repaint();
if (header.getTable().isEditing()) {
header.getTable().getCellEditor().stopCellEditing();
}
boolean isAscent;
if (SortButtonRenderer.DOWN == renderer.getState(col)) {
isAscent = true;
}else{
isAscent = false;
}
((SortableTableModel)header.getTable().getModel()).sortByColumn(sortCol, isAscent);
}
public void mouseReleased(MouseEvent e) {
int col = header.columnAtPoint(e.getPoint());
renderer.setPressedColumn(-1);
// clear
header.repaint();
}
}
}
class SortableTableModel extends DefaultTableModel {
TableSorter sorter;
public SortableTableModel(Vector columnNames, int rowCount){
super(columnNames,rowCount);
}
public void sortByColumn(int column, boolean isAscent) {
if (sorter == null) {
sorter = new TableSorter(this);
}
sorter.sort(column, isAscent);
fireTableDataChanged();
}
}
class TableSorter {
SortableTableModel model;
public TableSorter(SortableTableModel model) {
this.model = model;
}
//n2 selection
public void sort(int column, boolean isAscent) {
int n = model.getRowCount();
Vector indexes = model.getDataVector();
for (int i=0; i<n-1; i++) {
int k = i;
for (int j=i+1; j<n; j++) {
if (isAscent) {
if (compare(column, j, k) < 0) {
k = j;
}
} else {
if (compare(column, j, k) > 0) {
k = j;
}
}
}
Vector tmp = (Vector)indexes.elementAt(i);
indexes.setElementAt(indexes.elementAt(k), i);
indexes.setElementAt(tmp, k);
}
}
// comparaters
public int compare(int column, int row1, int row2) {
Object o1 = model.getValueAt(row1, column);
Object o2 = model.getValueAt(row2, column);
if (o1 == null && o2 == null) {
return 0;
} else if (o1 == null) {
return -1;
} else if (o2 == null) {
return 1;
} else {
Class type = model.getColumnClass(column);
if (type.getSuperclass() == Number.class) {
return compare((Number)o1, (Number)o2);
} else if (type == String.class) {
return ((String)o1).compareTo((String)o2);
} else if (type == Date.class) {
return compare((Date)o1, (Date)o2);
} else if (type == Boolean.class) {
return compare((Boolean)o1, (Boolean)o2);
} else {
return ((String)o1).compareTo((String)o2);
}
}
}
public int compare(Number o1, Number o2) {
double n1 = o1.doubleValue();
double n2 = o2.doubleValue();
if (n1 < n2) {
return -1;
} else if (n1 > n2) {
return 1;
} else {
return 0;
}
}
public int compare(Date o1, Date o2) {
long n1 = o1.getTime();
long n2 = o2.getTime();
if (n1 < n2) {
return -1;
} else if (n1 > n2) {
return 1;
} else {
return 0;
}
}
public int compare(Boolean o1, Boolean o2) {
boolean b1 = o1.booleanValue();
boolean b2 = o2.booleanValue();
if (b1 == b2) {
return 0;
} else if (b1) {
return 1;
} else {
return -1;
}
}
}