嗨,我试图在JTable中只为一个列使用自定义比较器.我用以下代码完成了这个.问题是这样做会破坏Integer的适当排序.
我有一个JTable,列类是:String | 整数| 整数| 布尔| 布尔
我正在使用的比较器就是这些.第一个使用如何拆分字母和数字之间(或数字和字母之间)的字符串?.
//compare strings being aware of numbers embedded in the string private static ComparatornumberAwareCompare = new Comparator () { public int compare(String s1, String s2) { String[] s1Parts = s1.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"); String[] s2Parts = s2.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"); int i = 0; while(i < s1Parts.length && i < s2Parts.length){ //if parts are the same if(s1Parts[i].compareTo(s2Parts[i]) == 0){ ++i; }else{ try{ int intS1 = Integer.parseInt(s1Parts[i]); int intS2 = Integer.parseInt(s2Parts[i]); //if the parse works int diff = intS1 - intS2; if(diff == 0){ ++i; }else{ return diff; } }catch(Exception ex){ return s1.compareTo(s2); } }//end else }//end while //Handle if one string is a prefix of the other. if(s1.length() < s2.length()){ return -1; }else if(s1.length() > s2.length()){ return 1; }else{ return 0; } return 0; } };
我将TableRowSorter扩展如下:
public class FeatureRowSorter extends TableRowSorter{ public FeatureRowSorter(TableModel tableModel) { super(tableModel); //setComparator(0, numberAwareCompare); //setComparator(1,intCompare); //setComparator(2,intCompare); } @Override public Comparator> getComparator(int column){ if(column == 0){ return numberAwareCompare; }else{ return super.getComparator(column); } } }
这会导致以下不希望的排序行为:
这可以通过创建整数排序来克服.这是问题所在.我不应该为Integer创建一个排序.如果默认的TableRowSorter知道类是Integer,为什么不能创建它呢?
所以我创建了一个简单的整数排序器,如下所示:
//Integer compare, need this to use the custom TableRowSorter public static ComparatorintCompare = new Comparator () { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } };
现在我删除上面的getComparator方法,并明确地将比较器添加到正确的列.(上面注释掉的代码).这具有正确的排序行为.
我使用以下代码将行分类器添加到表中.我的模型创建了一个新的自定义行分类器,并将其发送到控制器对象中的视图JTable.
//In the model, FeatureTableModel extends DefaultTableModel,getClass method implemented correctly public FeatureRowSorter getFeatureRowSorter(){ return new FeatureRowSorter(getFeatureTableModel()); }
然后将分拣机添加到表中,如下所示:
view.getFeatureTable().setRowSorter(model.getFeatureRowSorter());
所以问题是,如何在不必实现整数分拣机的情况下这样做呢?这看起来像是一个黑客,而且我正在实现一个整数比较器的事实看起来很可疑.由于FeatureTableModel的getClass方法正确实现,TableRowSorter知道这些列是Integer.(没关系,其中一个布尔列不是复选框.我正在覆盖该渲染器).
任何建议将不胜感激.
更新:
在阅读了Duncan的回答之后,我发现我没有正确地使用了getClass.我有:
@Override public Class> getColumnClass(int column){ if(column == 4){ return Boolean.class; }else if(column == 2){ return Integer.class; }else{ return Object.class; } }
我改为:
@Override public Class> getColumnClass(int column){ if(column == 4){ return Boolean.class; }else if(column == 1 || column == 2){ return Integer.class; }else{ return Object.class; } }
Duncan Jones.. 6
基于快速测试,我通过调用实例setComparator
上的方法实现了预期的结果TableRowSorter
.也就是说,我没有创建自己的扩展类TableRowSorter
.
JTable table = new JTable(model); TableRowSorterrowSorter = new TableRowSorter (model); table.setRowSorter(rowSorter); rowSorter.setComparator(0, new Comparator () { @Override public int compare(String o1, String o2) { // etc. } });
在我的测试中,这种方法对在同一个表中对整数列进行排序的能力没有负面影响.
我很欣赏这不是你遇到问题的原因的解释 ,但是作为一种可能更简单的解决办法,它值得一试.