Java 为什么我的JTable对整型列排序不正确?

Java 为什么我的JTable对整型列排序不正确?,java,swing,sorting,jtable,Java,Swing,Sorting,Jtable,我有一个使用DefaultTableModel的JTable,当用户单击列标题时,我允许排序。但是,当用户单击数据类型为integer的列的标题时,它不会正确排序。它似乎是按字符串排序,而不是按整数类型排序 下面是我的代码部分,我实际将数据添加到表中: DefaultTableModel aModel = (DefaultTableModel) mainView.logEntryTable.getModel(); ResultSetMeta

我有一个使用DefaultTableModel的JTable,当用户单击列标题时,我允许排序。但是,当用户单击数据类型为integer的列的标题时,它不会正确排序。它似乎是按字符串排序,而不是按整数类型排序

下面是我的代码部分,我实际将数据添加到表中:

        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);
DefaultTableModel aModel=(DefaultTableModel)mainView.logEntryTable.getModel();
结果元数据rsmd;试一试{
mainView.logEntriesTableModel.setRowCount(0);
rsmd=rs.getMetaData();
int colNo=rsmd.getColumnCount();
while(rs.next()){
Object[]objects=新对象[colNo];

对于(int i=0;iWell),DefaultTableModel的文档会声明:

警告:DefaultTableModel返回对象的列类。当DefaultTableModel与TableRowSorter一起使用时,这将导致大量使用toString,这对于非字符串数据类型来说是昂贵的。如果将DefaultTableModel与TableRowSorter一起使用,强烈建议您重写getColumnClass以返回适当的类型

听起来它只是将值转换成字符串,这与您看到的一致


您是否尝试过覆盖
getColumnClass()
或调用
setComparator()

更好的方法 正如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);
    }
}
原件,使用比较器 答案如下:

其思想是为列定义类

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];
    }
});
返回对象的列类。因此,所有比较都将使用toString完成。这可能会造成不必要的开销。如果列仅包含一种类型的值,例如整数,则应重写getColumnClass并返回相应的类。这将大大提高此类的性能

在这种情况下,应在表模型中添加以下代码段:

    @Override
public Class<?> getColumnClass(int columnIndex) {
    if (db.isEmpty()) {
        return Object.class;
    }
    return getValueAt(0, columnIndex).getClass();
}
@覆盖
公共类getColumnClass(int columnIndex){
if(db.isEmpty()){
返回Object.class;
}
返回getValueAt(0,columnIndex).getClass();
}

几乎总是建议重写getColumnClass:不仅(可比数据)的排序按预期完成,而且通常还会处理编辑时的格式化呈现和类型转换。顺便说一句:getColumnClass永远不会返回null…在示例中使用optionPane作为顶级容器很好:-)是的,但将GUI调用封装在Runnable中并在以后调用可能更好。我不确定我的辩护是“不包括电池”还是“(耸耸肩)我只是太懒了。”;)我看到了——可以克制住不提它,经过努力,他现在几乎所有我想要的答案都得到了你优雅的回答:)@MarounMaroun我想这是吸引眼球的截图(偶尔向上投一票)。有点“在那里,做了那件事,得到了截图”。)
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];
    }
});
    @Override
public Class<?> getColumnClass(int columnIndex) {
    if (db.isEmpty()) {
        return Object.class;
    }
    return getValueAt(0, columnIndex).getClass();
}