2

I am using a JXTable to display, filter, and sort some data. However, I'm getting some unexpected behavior when sorting. As you can see, the values are not ascending as expected, but sorted how a string would be sorted.

To address the comments, I am sure this column is getting parsed in the correct part of the code (i.e. the Float.valueOf() block.) I know this through debugging. Also, I am sorting the column by clicking on the jxtable's header. I am not doing it programmatically.

Incorrect Sort Order

Just to be clear, I am adding them as Floats:

class FantasyProTableModel extends DefaultTableModel
{
   void loadData() throws BiffException, IOException
   {
      Workbook workbook = Workbook.getWorkbook(new File("Input.xls"));
      Sheet sheet = workbook.getSheet(0);

      int numCols = sheet.getColumns();
      for(int col=0;col<numCols;col++)
      {
          addColumn(sheet.getCell(col,0).getContents());
      }
      for(int rownum=1;rownum<sheet.getRows();rownum++)
      {
          Object[] row = new Object[numCols];
          for(int col=0;col<numCols;col++)
          {
              try
              {
                  row[col] = Float.valueOf(sheet.getCell(col,rownum).getContents());
                                 //parseFloat() doesn't work either
              }
              catch(NumberFormatException e)
              {
                  row[col] = sheet.getCell(col,rownum).getContents();
              }
          }
          addRow(row);
      }

      workbook.close();
   }
}

What can I do to get it to sort in the correct, ascending order, by value?

dberm22
  • 3,187
  • 1
  • 31
  • 46
  • Can you provide the `TableModel`? They appear to be getting treat as `String`... – MadProgrammer Nov 17 '14 at 05:26
  • @MadProgrammer Updated. What I had originally was its body. This is the only function in the class. – dberm22 Nov 17 '14 at 05:30
  • Add a debug statement in you catch clause, make sure that the values are been parsed correctly... – MadProgrammer Nov 17 '14 at 05:31
  • I already did that (as noted in the question). They are. I'm assuming they're being sorted as a generic Object as opposed to a Float. – dberm22 Nov 17 '14 at 05:37
  • How you are sorting the table? Consider providing a [runnable example](https://stackoverflow.com/help/mcve) which demonstrates your problem. This will result in less confusion and better responses – MadProgrammer Nov 17 '14 at 05:38
  • It's a JXTable, so the function is built-in. I'm just clicking on the column header, not doing it programatically. – dberm22 Nov 17 '14 at 05:40
  • Did a quick test and it seems to be working for me.... – MadProgrammer Nov 17 '14 at 05:54
  • @MadProgrammer Hmm. The only other thing I am doing is adding it to a JFrame. Strange. Are you sorting it after you display it? It displays right at first (because I am adding them sequentially), but not when you apply the sort. – dberm22 Nov 17 '14 at 05:57

1 Answers1

4

Okay, after much digging, I've found two things, one, JXTable has it's own "row sorter", which wraps the default one and two, because DefaultTableModel returns Object.class by default from getColumnClass, these things are getting screwed up (SwingX's sorter is trying to make use of the Comparator interface, but if the object class is not comparable, then it defaults to using toString)

You have two choices...

You can...

Implement the getColumnClass from DefaultTableModel and return a proper class reference...

DefaultTableModel model = new DefaultTableModel(0, 1) {
    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return Float.class;
    }
};

Or you can...

Provide your own comparator of the JXTable row sorter implementation...

((TableSortController)table.getRowSorter()).setComparator(0, new Comparator<Float>() {
    @Override
    public int compare(Float o1, Float o2) {
        return o1.compareTo(o2);
    }
});
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Surprisingly enough, the first option still allows you to sort String columns. These don't get me 100% there, but I can take it from here. Thanks! – dberm22 Nov 17 '14 at 06:17
  • 2
    Of course you should return a different class depending on the columnIndex. – keuleJ Nov 17 '14 at 06:30
  • @keuleJ Yup, some minor tweaking and now it works. Thanks MadProgrammer! – dberm22 Nov 17 '14 at 06:36