2013-03-01 57 views
2

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

TableRowSorter<MyTableModel> rowSorter = new TableRowSorter<MyTableModel>(); 
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); 
        } 
       } 
      } 
     } 
    } 
}; 
+0

为了更好地帮助越早,张贴[SSCCE(http://sscce.org/)。 – 2013-03-01 16:37:49

回答

7

手动设置RowSorter的时候,你必须要与模型自己保持它同步的护理:

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

@kleopatra,您可能没有一个模型,当你从获取数据例如原始文本文件,如.csv。因此,所有的列都是字符串,而其中有合法的数字,所以您想要将这些列作为数字进行排序,而不是字符串(因此避免着名的数字1( 200 ...)。

谢谢user1202394找到了这个其他线程,你能提供给我们链接吗?

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

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);