无法将列比较器设置为JTable

在另一个线程中,我找到了这个比较器(post的底部),用于对JTable列进行排序,这些列可以由整数,字符串或两者组成。 我无法弄清楚如何将它应用于我的JTable。 我的表之前使用过自动创建的行排序器。 我将其设置为false,我现在正在使用:

TableRowSorter rowSorter = new TableRowSorter(); jtable.setRowSorter(rowSorter); rowSorter.setComparator(0, c1); 

我得到一个索引超出范围的例外,说我提供的无效范围。 我的表有多列。 这是应用比较器的正确方法吗? 我觉得这不是这样做的方法。

 Comparator c1 = new java.util.Comparator() { /** * Custom compare to sort numbers as numbers. * Strings as strings, with numbers ordered before strings. * * @param o1 * @param o2 * @return */ @Override public int compare(Object oo1, Object oo2) { boolean isFirstNumeric, isSecondNumeric; String o1 = oo1.toString(), o2 = oo2.toString(); isFirstNumeric = o1.matches("\\d+"); isSecondNumeric = o2.matches("\\d+"); if (isFirstNumeric) { if (isSecondNumeric) { return Integer.valueOf(o1).compareTo(Integer.valueOf(o2)); } else { return -1; // numbers always smaller than letters } } else { if (isSecondNumeric) { return 1; // numbers always smaller than letters } else { isFirstNumeric = o1.split("[^0-9]")[0].matches("\\d+"); isSecondNumeric = o2.split("[^0-9]")[0].matches("\\d+"); if (isFirstNumeric) { if (isSecondNumeric) { int intCompare = Integer.valueOf(o1.split("[^0-9]")[0]).compareTo(Integer.valueOf(o2.split("[^0-9]")[0])); if (intCompare == 0) { return o1.compareToIgnoreCase(o2); } return intCompare; } else { return -1; // numbers always smaller than letters } } else { if (isSecondNumeric) { return 1; // numbers always smaller than letters } else { return o1.compareToIgnoreCase(o2); } } } } } }; 

手动设置RowSorter时,您必须自己保持与模型同步:

  TableRowSorter sorter = new TableRowSorter(); table.setRowSorter(sorter); sorter.setModel(table.getModel()); sorter.setComparator(myComparator); 

@kleopatra,从原始文本文件中获取数据时可能没有模型,例如.csv。 因此,所有列都是String,而其中有合法数字,因此您可能希望将这些列排序为数字,而不是字符串(因此避免着名的1 <11 <10000 <2 <200 ...)。

感谢user1202394找到了这个其他post,你能给我们链接吗?

我设法使其按预期工作,有三个新的代码部分:

 Comparator myComparator = new java.util.Comparator() { /** * Custom compare to sort numbers as numbers. * Strings as strings, with numbers ordered before strings. * * @param o1 * @param o2 * @return */ @Override public int compare(Object oo1, Object oo2) { boolean isFirstNumeric, isSecondNumeric; String o1 = oo1.toString(), o2 = oo2.toString(); isFirstNumeric = o1.matches("\\d+"); isSecondNumeric = o2.matches("\\d+"); if (isFirstNumeric) { if (isSecondNumeric) { return Integer.valueOf(o1).compareTo(Integer.valueOf(o2)); } else { return -1; // numbers always smaller than letters } } else { if (isSecondNumeric) { return 1; // numbers always smaller than letters } else { // Those lines throw ArrayIndexOutOfBoundsException // isFirstNumeric = o1.split("[^0-9]")[0].matches("\\d+"); // isSecondNumeric = o2.split("[^0-9]")[0].matches("\\d+"); // Trying to parse String to Integer. // If there is no Exception then Object is numeric, else it's not. try{ Integer.parseInt(o1); isFirstNumeric = true; }catch(NumberFormatException e){ isFirstNumeric = false; } try{ Integer.parseInt(o2); isSecondNumeric = true; }catch(NumberFormatException e){ isSecondNumeric = false; } if (isFirstNumeric) { if (isSecondNumeric) { int intCompare = Integer.valueOf(o1.split("[^0-9]")[0]).compareTo(Integer.valueOf(o2.split("[^0-9]")[0])); if (intCompare == 0) { return o1.compareToIgnoreCase(o2); } return intCompare; } else { return -1; // numbers always smaller than letters } } else { if (isSecondNumeric) { return 1; // numbers always smaller than letters } else { return o1.compareToIgnoreCase(o2); } } } } } }; TableRowSorter sorter = new TableRowSorter(); table.setRowSorter(sorter); sorter.setModel(table.getModel()); sorter.setComparator(myComparator); // Apply Comparator to all columns for(int i = 0 ; i < table.getColumnCount() ; i++) rowSorter.setComparator(i, c1);