seleccionada - jtable java
Problemas para configurar un comparador de columnas en una JTable (2)
En otro hilo encontré este comparador (parte inferior de la publicación) para ordenar columnas JTable que podrían estar compuestas por enteros, cadenas o ambos. No puedo encontrar la forma de aplicarlo a mi JTable. Mi mesa estaba usando el clasificador de fila creado automáticamente antes. Configuré eso en falso y ahora estoy usando:
TableRowSorter<MyTableModel> rowSorter = new TableRowSorter<MyTableModel>();
jtable.setRowSorter(rowSorter);
rowSorter.setComparator(0, c1);
Obtengo una excepción de índice fuera de límites que dice que proporciono un rango no válido. Mi mesa tiene múltiples columnas sin embargo. ¿Es esta la forma correcta de aplicar el comparador? Siento que esta no es la manera de hacerlo.
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);
}
}
}
}
}
};
Cuando configura manualmente un RowSorter, debe tener cuidado de mantenerlo sincronizado con el modelo usted mismo:
TableRowSorter sorter = new TableRowSorter();
table.setRowSorter(sorter);
sorter.setModel(table.getModel());
sorter.setComparator(myComparator);
@kleopatra, es posible que no tenga un modelo cuando obtiene datos de un archivo de texto sin formato, por ejemplo, como un .csv. Por lo tanto, todas las columnas son Cadenas, mientras que hay números fidedignos en ellas, por lo que le conviene ordenar esas columnas como números, no como cadenas (evitando así el famoso 1 <11 <10000 <2 <200 ...).
Gracias user1202394 por haber encontrado este otro hilo, ¿podría proporcionarnos el enlace?
Me las arreglé para hacer que funcione como se esperaba con tres nuevas partes del código:
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);