java - TableRowSorter 和非法比较器转换的问题

标签 java swing sorting jtable

只是想知道为什么在特定列上使用比较器对表格行进行排序不起作用。对话框如下图所示,“项目类型”表正在排序。

Image of items/item groups dialog

如您所见,“名称”列工作正常。如果我点击 ID 列,我会得到

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at org.overlord.rfm.rfcsv.ItemGroupsDialog$ItemTable$2.compare(ItemGroupsDialog.java:1)

这里是定义和使用行排序器的地方:

        rowSorter = new TableRowSorter<>(model);

        rowSorter.setComparator(1, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return (o1<o2 ? -1 : (o1.equals(o2) ? 0 : 1));
            }
        });
        rowSorter.setSortable(1, true);
        rowSorter.setComparator(2, new HumaneStringComparator());
        rowSorter.setSortable(2, true);
        rowSorter.setRowFilter(searchFilter);
        setRowSorter(rowSorter);

这是在表格模型中,一切看起来都很正常:

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        if (columnIndex < 0 || columnIndex >= 3) {
            throw new IndexOutOfBoundsException("Illegal col index: " + columnIndex);
        }
        if (rowIndex < 0 || rowIndex >= rows.size()) {
            throw new IndexOutOfBoundsException("Illegal row index: " + rowIndex);
        }
        ItemRow ir = rows.get(rowIndex);
        switch (columnIndex) {
            case 0: return ir.getItem().getImage(); 
            case 1: return ir.getItem().getId();
            case 2: return ir.getItem().getName();
        }
        throw new IllegalStateException("Column index invalid?");
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex) {
            case 0: return Image.class;
            case 1: return Integer.class;
            case 2: return String.class;
        }
        throw new IllegalStateException("Column index invalid?");
    }

出了什么问题?在此先感谢您的帮助。

最佳答案

使用 JTableClassCastException 的一个重要来源是 getValueAtgetColumnClass 和最好的组合-默认渲染器的努力(而不是快速失败)行为。

在这里,您声明第二列(第 1 列)的类型是 Integer,并将用于它的 Comparator 设置为 Integer 比较器。到目前为止似乎很合理。但是,您实际上可以在 getValueAt 方法中自由返回任何内容,除非您指定自定义呈现器 - 您的非整数值将呈现得很好。编译器无法检查您声明的类型是否实际匹配!因此,您只能通过仔细检查、设置自定义渲染器/编辑器或尝试排序(因为默认比较器不那么宽松)来发现类不匹配。

在这种情况下,事实证明 getId() 实际上返回的是 String 而不是 Integer

关于java - TableRowSorter 和非法比较器转换的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27383893/

相关文章:

ios - 如何将数组排序到字典中?

c++ - 排序问题如何访问私有(private) vector 值

java - 使用堆栈从算术表达式中删除不必要/重复的括号

java - 我需要一种更好的方法来减少代码行,其中有很多 if 语句和条件调用方法

c# - 默认比较器在 C# 中如何工作?

Java:在读取/写入文件时加载某种文本(来自 URL 的 DL)

java - 监听键/鼠标事件

java - 乘法错误

java - 使用 spring 更新单个对象并通过 url 发送

java - 循环遍历 JPanel