[英]Trouble setting a column comparator to a JTable
在另一個線程中,我發現了這個比較器(帖子的底部),用於對JTable列進行排序,這些列可能由整數,字符串或兩者組成。 我不知道如何將其應用於我的JTable。 我的表以前使用過自動創建的行排序器。 我將其設置為false,現在使用:
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);
}
}
}
}
}
};
手動設置RowSorter時,您必須注意使其與模型保持同步:
TableRowSorter sorter = new TableRowSorter();
table.setRowSorter(sorter);
sorter.setModel(table.getModel());
sorter.setComparator(myComparator);
@kleopatra,例如從原始文本文件(例如.csv)中獲取數據時,可能沒有模型。 因此,所有列都是字符串,而其中有合法數字,因此您希望將這些列按數字而不是字符串排序(因此避免使用著名的1 <11 <10000 <2 <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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.