Проблема с установкой компаратора столбца в JTable
В другой теме я нашел этот компаратор (внизу поста) для сортировки столбцов JTable, которые могут состоять из целых чисел, строк или обоих. Я не могу понять, как применить его к моему 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);
}
}
}
}
}
};
2 ответа
При ручной настройке 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);