Java比较器始终将值读取为字符串 [英] Java Comparator always reading values as Strings

查看:81
本文介绍了Java比较器始终将值读取为字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图弄清楚我问的另一个问题的答案(

In trying to figure out the answer to another question I asked (How to sort a jtable with null values always at the end), I ran into another problem.

我正在实现创建自定义Comparator的自定义TableRowSorter.但是,Comparator似乎总是将每个Object读为类型String.这个让我感到困惑.

I am implementing a custom TableRowSorter that creates a custom Comparator. However, the Comparator always seems to read every Object as a type String. This one has me baffled.

如果您在下面的SSCCE中注意到这一行

If you'll notice in the SSCCE below, the line

System.out.println(o1.getClass() + " - " + o2.getClass());

总是添加输出

class java.lang.String - class java.lang.String

即使Object[][]数据数组中的项目是多种类型,

Even though the items in the Object[][] data array are varied types.

import java.awt.Component;
import java.util.Comparator;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class Test {

    public static void main(String args[]) {
        JFrame frame = new JFrame();
        JTable table = new JTable();
        Object[][] data = new Object[8][3];
        data[0][0] = 6.5d; data[0][1] = "Name1";
        data[1][0] = new NullClassFiller(); data[1][1] = "Name2";
        data[2][0] = 2.6d; data[2][1] = "Name3";
        data[3][0] = 0d; data[3][1] = "Name4";
        data[4][0] = new NullClassFiller(); data[4][1] = "Name5";
        data[5][0] = -4d; data[5][1] = "Name6";
        data[6][0] = 0d; data[6][1] = "Name7";
        data[7][0] = -4.3d; data[7][1] = "Name8";
        table.setModel(new DefaultTableModel(data, new String[]{"One", "Two"}));

        TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()) {
            @Override
            public Comparator<?> getComparator(final int column) {
                Comparator c = new Comparator() {
                    @Override
                    public int compare(Object o1, Object o2) {
                        System.out.println(o1.getClass() + " - " + o2.getClass());
                        if (o1 instanceof NullClassFiller) {
                            return -1;
                        } else if (o2 instanceof NullClassFiller) {
                            return -1;
                        } else {
                            return ((Comparable<Object>) o1).compareTo(o2);
                        }

                    }
                };
                return c;
            }
        };
        table.setRowSorter(sorter);
        table.getColumnModel().getColumn(0).setCellRenderer(new CustomRenderer());
        JScrollPane pane = new JScrollPane(table);
        frame.add(pane);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setSize(500, 500);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    static class NullClassFiller {}

    static class CustomRenderer extends DefaultTableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

            if(value instanceof NullClassFiller)
                renderer.setText("");

            return renderer;
        }

    }
}

推荐答案

有很多复合问题...

There are number of compound problems...

第一个是DefaultTableModel. DefaultTableModel#getColumnClass返回Object.class.

第二个是TableRowSorter. TableRowSorter检查从模型返回的Class是否为Comparable,如果不是,则将其自动转换为String,因为Object不是Comparable ...

The second is with the TableRowSorter. TableRowSorter checks to see if the Class returned from the model is Comparable, if it is not, it is automatically converted to String, because Object is not Comparable...

因此,基本解决方案是覆盖DefaultTableModelgetColumnClass以返回特定列的Class的适当类型

So, the basic solution is to override the getColumnClass of the DefaultTableModel to return the appropriate type of Class of a particular column

TableModel model = new DefaultTableModel(data, new String[]{"One", "Two"}) {
    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return columnIndex == 0 ? Double.class : String.class;
    }
};
table.setModel(model);

TableRowSorter检查列的Class时,现在将找到Comparable值,并将使用表模型中的实际值,而不先将其转换为String.

When the TableRowSorter checks the column's Class it will now find Comparable values and will use the actual value from the table model and not convert it to String first.

现在,当您尝试对第一列进行排序时,您应该会看到更多类似...

Now when you try and sort the first column, you should be seeing something more like...

class testtablesort.TestTableSort$NullClassFiller) - class java.lang.Double
class java.lang.Double) - class testtablesort.TestTableSort$NullClassFiller
class java.lang.Double) - class java.lang.Double
class testtablesort.TestTableSort$NullClassFiller) - class java.lang.Double
class java.lang.Double) - class testtablesort.TestTableSort$NullClassFiller
class java.lang.Double) - class java.lang.Double
class java.lang.Double) - class java.lang.Double
class java.lang.Double) - class testtablesort.TestTableSort$NullClassFiller
class java.lang.Double) - class java.lang.Double
class java.lang.Double) - class java.lang.Double
class java.lang.Double) - class java.lang.Double
class java.lang.Double) - class java.lang.Double

这篇关于Java比较器始终将值读取为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆