Question

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.

Was it helpful?

Solution

Check out this code. It sorts double values.

enter image description here

enter image description here

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.

OTHER TIPS

this code could be your SSCCE, can you demonstate you issue on this code, nothing from code snipped that you posted

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();
            }
        });
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top