Java比较器始终以字符串形式读取值
在试图找出我问的另一个问题()的答案时,我遇到了另一个问题 我正在实现一个自定义Java比较器始终以字符串形式读取值,java,swing,sorting,jtable,comparator,Java,Swing,Sorting,Jtable,Comparator,在试图找出我问的另一个问题()的答案时,我遇到了另一个问题 我正在实现一个自定义表格行排序器,它创建一个自定义比较器。但是,比较器似乎总是将每个对象作为类型字符串读取。这件事让我困惑不解 如果您在下面的SSCCE中注意到 System.out.println(o1.getClass() + " - " + o2.getClass()); 总是输出Yeild class java.lang.String - class java.lang.String 即使对象[]【】数据数组中的项是不同的类
表格行排序器
,它创建一个自定义比较器
。但是,比较器
似乎总是将每个对象
作为类型字符串
读取。这件事让我困惑不解
如果您在下面的SSCCE中注意到
System.out.println(o1.getClass() + " - " + o2.getClass());
总是输出Yeild
class java.lang.String - class java.lang.String
即使对象[]【】
数据数组中的项是不同的类型
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;
}
}
}
导入java.awt.Component;
导入java.util.Comparator;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.table.DefaultTableCellRenderer;
导入javax.swing.table.DefaultTableModel;
导入javax.swing.table.TableModel;
导入javax.swing.table.TableRowSorter;
公开课考试{
公共静态void main(字符串参数[]){
JFrame=新JFrame();
JTable table=新的JTable();
对象[][]数据=新对象[8][3];
数据[0][0]=6.5d;数据[0][1]=Name1;
数据[1][0]=新的NullClassFiller();数据[1][1]=名称2;
数据[2][0]=2.6d;数据[2][1]=Name3;
数据[3][0]=0d;数据[3][1]=Name4;
数据[4][0]=新的NullClassFiller();数据[4][1]=名称5;
数据[5][0]=-4d;数据[5][1]=“名称6”;
数据[6][0]=0d;数据[6][1]=Name7;
数据[7][0]=-4.3d;数据[7][1]=“名称8”;
setModel(新的DefaultTableModel(数据,新字符串[]{“一”,“二”}));
TableRowSorter-sorter=新的TableRowSorter(table.getModel()){
@凌驾
公共比较器getComparator(最后一个int列){
比较器c=新比较器(){
@凌驾
公共整数比较(对象o1、对象o2){
System.out.println(o1.getClass()+“-”+o2.getClass());
if(NullClassFiller的o1实例){
返回-1;
}else if(NullClassFiller的o2实例){
返回-1;
}否则{
回报率((可比)o1),与(o2)相比;
}
}
};
返回c;
}
};
表.SetRow分拣机(分拣机);
table.getColumnModel().getColumn(0).setCellRenderer(新的CustomRenderer());
JScrollPane=新的JScrollPane(表);
框架。添加(窗格);
frame.pack();
frame.setLocationRelativeTo(空);
框架。设置尺寸(500500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
静态类NullClassFiller{}
静态类CustomRenderer扩展了DefaultTableCellRenderer{
@凌驾
公共组件GetTableCellRenderComponent(JTable表、对象值、布尔isSelected、布尔hasFocus、int行、int列){
DefaultTableCellRenderer=(DefaultTableCellRenderer)super.getTableCellRendererComponent(表、值、isSelected、hasFocus、行、列);
if(NullClassFiller的值实例)
.setText(“”);
返回渲染器;
}
}
}
问题在于:
table.setModel(new DefaultTableModel(data, new String[]{"One", "Two"}));
根据,
有两个JTable构造函数直接接受数据(SimpleTableDemo使用第一个):
他们很容易使用。但是,这些构造函数也有
缺点:
它们会自动使每个单元格都可编辑。它们处理所有数据类型
与字符串相同
问题在于:
table.setModel(new DefaultTableModel(data, new String[]{"One", "Two"}));
根据,
有两个JTable构造函数直接接受数据(SimpleTableDemo使用第一个):
他们很容易使用。但是,这些构造函数也有
缺点:
它们会自动使每个单元格都可编辑。它们处理所有数据类型
与字符串相同
有许多复杂的问题 第一个是使用
DefaultTableModel
DefaultTableModel#getColumnClass
返回Object.class
第二个是使用表格行分拣机
TableRowSorter
检查从模型返回的类
是否可比,如果不可比,则自动转换为字符串
,因为对象
不可比
因此,基本解决方案是覆盖DefaultTableModel
的getColumnClass
,以返回特定列的适当类型的Class
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);
有许多复杂的问题 第一个是使用
DefaultTableModel
DefaultTableModel#getColumnClass
返回Object.class
第二个是使用表格行分拣机
TableRowSorter
检查从模型返回的类
是否可比,如果不可比,则自动转换为字符串
,因为对象
不可比
因此,基本解决方案是覆盖DefaultTableModel
的getColumnClass
,以返回特定列的适当类型的Class
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);
问题和答案都存在一些问题:
- 在表的末尾排序空值,而不考虑排序顺序
- 该需求的干净解决方案需要对DefaultRowSorter及其子类进行几乎完全的重写,因为空值在比较算法中“早期”处理,并且被深埋在其私有内部。简单地说,定制比较器是不可能跳入的
- 一种方法是不添加null,而是使用专用的null替换,然后让自定义