java 为什么我的 JTable 对整数列排序不正确?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6592192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:31:34  来源:igfitidea点击:

Why does my JTable sort an integer column incorrectly?

javaswingsortingjtable

提问by Brian T Hannan

I have a JTable that uses a DefaultTableModel and I allow for sorting when the user clicks on the column headers. However, when the user clicks on a header for a column that has data of type integer it does not sort properly. It seems like it is sorting by String instead of an integer type.

我有一个使用 DefaultTableModel 的 JTable,我允许在用户单击列标题时进行排序。但是,当用户单击具有整数类型数据的列的标题时,它不会正确排序。看起来它是按字符串而不是整数类型排序的。

Here is the part of my code where I actually add the data to the table:

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

        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);

So I tried to override that method and ended up with this:

所以我试图覆盖该方法并最终得到这个:

            @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;
            }
        };

I've never overridden this before and I'm not quite sure what it is expecting me to do here.

我以前从未覆盖过它,我不太确定它希望我在这里做什么。

回答by Andrew Thompson

Try this little example.

试试这个小例子。

Sorted 1st column

排序第一列

The better way

更好的方法

As suggested by Kleopatra, defining a column class relevant for each, will be enough to get the data to be sorted correctly.

正如 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);
    }
}

Original, using a comparator

原始,使用比较器

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);
    }
}

回答by Jon Skeet

Well, the docs for DefaultTableModel do state:

好吧, DefaultTableModel 的文档说明:

Warning: DefaultTableModel returns a column class of Object. When DefaultTableModel is used with a TableRowSorter this will result in extensive use of toString, which for non-String data types is expensive. If you use DefaultTableModel with a TableRowSorter you are strongly encouraged to override getColumnClass to return the appropriate type.

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

So it sounds like it's just going to be converting values to strings, which would be consistent with what you're seeing.

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

Have you tried either overriding getColumnClass()or calling setComparator()for the appropriate TableRowSorter?

您是否尝试过覆盖getColumnClass()或调用setComparator()适当的TableRowSorter

回答by Zakhar

Here is the answer: Problems with JTable sorting of integer values

这是答案: JTable 对整数值排序的问题

The idea is to define classes for columns.

这个想法是为列定义类。

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];
    }
});