我有一个使用DefaultTableModel的JTable,我允许在用户点击列标题时进行排序。但是,当用户单击具有integer类型数据的列的标头时,它不能正确排序。看起来它是按String而不是整数类型排序。
这是我的代码中我实际将数据添加到表中的部分:
DefaultTableModel aModel = (DefaultTableModel) mainView.logEntryTable.getModel();
ResultSetMetaData rsmd; try {
mainView.logEntriesTableModel.setRowCount(0);
rsmd = rs.getMetaData();
int colNo = rsmd.getColumnCount();
while(rs.next()){
Object[] objects = new Object[colNo];
for(int i=0;i<colNo;i++){
objects[i]=rs.getObject(i+1);
}
aModel.addRow(objects);
count++;
}
mainView.logEntryTable.setModel(aModel);
mainView.logEntryTable.getColumnModel().getColumn(0).setMaxWidth(80);
所以我尝试覆盖了这个方法并最终得到了这个:
@Override
public Class<?> getColumnClass(int columnIndex){
if( columnIndex == 0){
// Return the column class for the integer column
}else{
// Return the column class like we normally would have if we didn't override this method
}
return null;
}
};
我以前从未覆盖过这个,我不太确定我在这里做什么。
答案 0 :(得分:18)
试试这个小例子。
正如Kleopatra所建议的那样,定义与每个列相关的列类就足以让数据正确排序。
import javax.swing.*;
import javax.swing.table.*;
import java.util.Comparator;
class TableSorting {
public static void main(String[] args) {
Object[][] data = {
{new Integer(1), "Don't Let Go", new Integer(179)},
{new Integer(2), "Photograph", new Integer(29)},
{new Integer(3), "Hash Pipe", new Integer(186)},
{new Integer(4), "Island In The Sun", new Integer(200)},
{new Integer(5), "Crab", new Integer(154)},
{new Integer(6), "Knock-Down Drag-Out", new Integer(128)},
{new Integer(7), "Smile", new Integer(158)},
{new Integer(8), "Simple Pages", new Integer(176)},
{new Integer(9), "Glorious Day", new Integer(160)},
{new Integer(10), "O Girlfriend", new Integer(230)}
};
Object[] columns = {"Track #", "Title", "Length"};
DefaultTableModel model = new DefaultTableModel(data,columns) {
@Override
public Class getColumnClass(int column) {
switch (column) {
case 0:
return Integer.class;
case 1:
return String.class;
case 2:
return Integer.class;
default:
return String.class;
}
}
};
JTable table = new JTable(model);
JScrollPane scroll = new JScrollPane(table);
table.setAutoCreateRowSorter(true);
JOptionPane.showMessageDialog(null, scroll);
}
}
import javax.swing.*;
import javax.swing.table.*;
import java.util.Comparator;
class TableSorting {
public static void main(String[] args) {
Object[][] data = {
{new Integer(1), "Don't Let Go", new Integer(179)},
{new Integer(2), "Photograph", new Integer(29)},
{new Integer(3), "Hash Pipe", new Integer(186)},
{new Integer(4), "Island In The Sun", new Integer(200)},
{new Integer(5), "Crab", new Integer(154)},
{new Integer(6), "Knock-Down Drag-Out", new Integer(128)},
{new Integer(7), "Smile", new Integer(158)},
{new Integer(8), "Simple Pages", new Integer(176)},
{new Integer(9), "Glorious Day", new Integer(160)},
{new Integer(10), "O Girlfriend", new Integer(230)}
};
Object[] columns = {"Track #", "Title", "Length"};
JTable table = new JTable(data, columns);
JScrollPane scroll = new JScrollPane(table);
DefaultTableModel model = new DefaultTableModel(data,columns);
TableRowSorter trs = new TableRowSorter(model);
class IntComparator implements Comparator {
public int compare(Object o1, Object o2) {
Integer int1 = (Integer)o1;
Integer int2 = (Integer)o2;
return int1.compareTo(int2);
}
public boolean equals(Object o2) {
return this.equals(o2);
}
}
trs.setComparator(0, new IntComparator());
table.setRowSorter(trs);
scroll = new JScrollPane(table);
table.setAutoCreateRowSorter(false);
JOptionPane.showMessageDialog(null, scroll);
}
}
答案 1 :(得分:8)
嗯,DefaultTableModel的文档的状态为:
警告:DefaultTableModel返回Object的列类。当DefaultTableModel与TableRowSorter一起使用时,这将导致广泛使用toString,对于非String数据类型来说,这是非常昂贵的。如果将DefaultTableModel与TableRowSorter一起使用,强烈建议您覆盖getColumnClass以返回相应的类型。
所以听起来它只是将值转换为字符串,这与您所看到的一致。
您是否尝试覆盖getColumnClass()
或致电setComparator()
以获取相应的TableRowSorter
?
答案 2 :(得分:2)
以下是答案: Problems with JTable sorting of integer values
我们的想法是为列定义类。
myTable.setModel(new DefaultTableModel(Object[][] tableData, String[] columnsNames){
Class[] types = { Boolean.class, Boolean.class, String.class, String.class };
@Override
public Class getColumnClass(int columnIndex) {
return this.types[columnIndex];
}
});
答案 3 :(得分:0)
DefaultTableModel返回Object的列类。因此,所有比较将使用toString进行。这可能不必要地昂贵。如果列仅包含一种类型的值,例如Integer,则应重写getColumnClass并返回适当的Class。这将大大提高此类的性能。
在这种情况下,您应该在表格模型中添加以下代码段:
@Override
public Class<?> getColumnClass(int columnIndex) {
if (db.isEmpty()) {
return Object.class;
}
return getValueAt(0, columnIndex).getClass();
}