Java比较器始终将值读取为字符串 [英] Java Comparator always reading values as Strings
问题描述
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
...
因此,基本解决方案是覆盖DefaultTableModel
的getColumnClass
以返回特定列的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屋!