I have found quite a few questions related to this but I haven't found a simple solution to my issue though.
I can't find a way to make my JTable sort Double values properly.
I extended AbstractTableModel to receive a Class array and return the proper types per column:
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];
}
...
And then in my custom JTable constructor:
TableRowSorter<TableModelMod> sorter = new TableRowSorter<TableModelMod>((TableModelMod)getModel());
But then I get this error when adding rows:
java.lang.IllegalArgumentException: Cannot format given Object as a Number
It fails at method DecimalFormat.format(Object number, StringBuffer toAppendTo, FieldPosition pos)
that accepts most numeric types but Double.
If I use another class for the Double columns I get no error but still the sorting does not work as expected. I tried with different numeric classes but none seem to sort doubles correctly:
@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];
}
I'm not sure if I what I need is to implement a custom RowSorter, a custom CellRenderer, or both.
Could someone guide me on how to fix this the simpler way?
Thanks a lot and best regards.
EDITED: SOLVED
It's quite embarrassing to tell where the problem was.
The ArrayList containing the Object[] rows was filled from a database ResultSet using getString(int) instead of getObject(int) or getDouble(int), therefore the value could not be used as Double by the renderer. It's weird that it didn't give exceptions using Integer or Number as column class, but it was being sorted as a String anyways. I was looking for an issue in the wrong classes since I was convinced my ArrayList contained just Objects.
Thanks a lot for your examples, looking at them I noticed my doubles were actually Strings and then I could find where the conversion was happening.
Check out this code. It sorts double values.
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);
}
}
I modified the source given at this link a little bit so that it takes double values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With