java - programacion - Clasificando valores dobles en JTable
manual de programacion android pdf (2)
He encontrado bastantes preguntas relacionadas con esto, pero no he encontrado una solución simple para mi problema.
No puedo encontrar una manera de hacer que mi JTable clasifique correctamente los valores Dobles.
Extendí AbstractTableModel para recibir una matriz Class y devolver los tipos adecuados por columna:
class TableModelMod extends AbstractTableModel{
private ArrayList data;
private String [] headers;
private Class [] types;
TableModelMod(String [] heads, ArrayList datas, Class [] classes){
headers = heads;
data = datas;
types = classes;
}
...
@Override public Class getColumnClass(int c){
if (c > types.length - 1)
return null;
else
return types[c];
}
...
Y luego en mi constructor JTable personalizado:
TableRowSorter<TableModelMod> sorter = new TableRowSorter<TableModelMod>((TableModelMod)getModel());
Pero luego aparece este error al agregar filas:
java.lang.IllegalArgumentException: Cannot format given Object as a Number
Falla en el método DecimalFormat.format(Object number, StringBuffer toAppendTo, FieldPosition pos)
que acepta la mayoría de los tipos numéricos excepto Double.
Si utilizo otra clase para las columnas dobles, no obtengo ningún error, pero la ordenación no funciona como se esperaba. Intenté con diferentes clases numéricas, pero ninguna parece ordenar los dobles correctamente:
@Override public Class getColumnClass(int c){
if (c > types.length - 1)
return null;
else if (types[c] == Double.class)
return Number.class;
else
return types[c];
}
No estoy seguro de si lo que necesito es implementar un RowSorter personalizado, un CellRenderer personalizado o ambos.
¿Podría alguien guiarme sobre cómo solucionar esto de la manera más simple?
Muchas gracias y un saludo.
EDITADO: SOLUCIONADO
Es bastante vergonzoso decir dónde estaba el problema.
ArrayList que contiene las filas de Object [] se rellenó a partir de una base de datos ResultSet utilizando getString (int) en lugar de getObject (int) o getDouble (int), por lo tanto el renderizador no pudo usar el valor como Double. Es extraño que no haya excepciones usando Número entero o Número como clase de columna, pero de todos modos se ordenó como una Cadena. Estaba buscando un problema en las clases incorrectas ya que estaba convencido de que mi ArrayList solo contenía Objects.
Muchas gracias por sus ejemplos, mirándolos noté que mis dobles eran en realidad Cuerdas y luego pude encontrar dónde estaba ocurriendo la conversión.
Mira este código Clasifica valores dobles.
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class RowSorterDemo {
public static void main(String args[]) {
JFrame frame = new JFrame("Sort Table Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Object rows[][] = { { "J", 23.1 }, { "R", 21.1, }, { "E", 21.2, }, { "B", 27.1, }, { "A", 25.2, },
{ "S", 22.9, }, };
String columns[] = { "Name", "Age" };
TableModel model = new DefaultTableModel(rows, columns) {
public Class getColumnClass(int column) {
Class returnValue;
if ((column >= 0) && (column < getColumnCount())) {
returnValue = getValueAt(0, column).getClass();
} else {
returnValue = Object.class;
}
return returnValue;
}
};
JTable table = new JTable(model);
RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
table.setRowSorter(sorter);
JScrollPane pane = new JScrollPane(table);
frame.add(pane, BorderLayout.CENTER);
frame.setSize(300, 150);
frame.setVisible(true);
}
}
Modifiqué un poco la fuente dada en este enlace para que tome valores dobles.
este código podría ser su SSCCE , ¿puede demostrar su problema en este código, nada de código cortado que haya publicado?
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableTest2 {
public void initGUI() {
String[] columnNames = {"numbers","double", "text"};
Object[][] data = {{1, 0.81, "A"}, {10, 5.268752005, "B"}, {7, 100.0,"C"},{6, 52.879999, "A"},
{4, 62.50, "B"}, {2, 854.9999, "C"},{11, 19.01, "A"}, {100, 0.0009, "B"}, {20, 100.09, "C"}};
JTable table = new JTable(new DefaultTableModel(data, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public java.lang.Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
});
table.setAutoCreateRowSorter(true);
table.getRowSorter().setSortKeys(Arrays.asList(new RowSorter.SortKey(0, SortOrder.ASCENDING)));
JFrame frame = new JFrame("LFIXimate");
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TableTest2().initGUI();
}
});
}
}