0

Sorry for asking basic question once again. As new to java, so i thought better to take guidance instead of doing something stupid.

In my jtable, i have following data

Id | Name | Date(month-year)
1  | XYZ  | August-2014
2  | ABc  | April-2014

my Modelclass is as follows

class MyTableModel extends AbstractTableModel {

 private String[] columnNames = {"Id", "Country","Date"};

 public final Object[] longValues = {Integer.class,"",Date.class};

now as recommended, i have overriden the getColumnClass in my model table

@Override
 public Class getColumnClass(int c)
 {
     if(c == 2)
     {
              //return Date.class;
              return getValueAt(0,c).getClass();
     }
      else
         return getValueAt(0,c).getClass();
  }

and i have enabled default column sorter.

Now as default, all string columns work fine in shorting but for Date column also it consider as string and short it as string.

If i force the column to short as date it give me error.

What am i doing wrong and what is correct way of doing it.

Thanks

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • whats value that returns this column, is there Date.class in return, otherwise this question doesn't make me sence – mKorbel Sep 30 '14 at 12:33
  • 1
    for more info to read Oracle tutorial How to use Tables - part about renderers (description about data types) – mKorbel Sep 30 '14 at 12:34
  • Hi @mKorbel i have added some detail about model class, so that it make more readable. – javadotnetcoder Sep 30 '14 at 12:43
  • 2
    you could get rid of the entire `if`/`else` by the look of those identical statements! For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example). – Andrew Thompson Sep 30 '14 at 13:16

2 Answers2

2

Now as recommended, I have overriden the getColumnClass in my model table

Note that your implementation is wrong mainly because you never have to ask for model's value to get the column's class (not to mention redundant/useless if-else block). Since you know your model then you are perfectly capable to return the right column class with no need to query the model:

@Override
public Class<?> getColumnClass(int columnIndex) {
    switch (columnIndex) {
        case 0: return Integer.class; // Id column
        case 1: return String.class; // Name column
        case 2: return Date.class; // Date column
            default: return super.getColumnClass(columnIndex);
    }
}

This should be enough to properly sort dates column, even if your renderer shows month-year pattern:

table.setDefaultRenderer(Date.class, new DefaultTableCellRenderer() {
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

        if (value instanceof Date) {
            SimpleDateFormat formatter = new SimpleDateFormat("MMMM-yyyy");
            value = formatter.format((Date)value);
        }

        return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    }
});

For example if you have 9/27/2014 and 9/30/2014 then this should be the natural ascending order when you sort this column, regardless both cells display September-2014.

dic19
  • 17,821
  • 6
  • 40
  • 69
  • Hi @dic19, it solve the problem, but i didnt get table.setDefaultRenderer(Date.class , new DefaultTableCellRenderer), in this why did we mention Date.class, why we used it here – javadotnetcoder Sep 30 '14 at 15:26
  • 1
    @javadotnetcoder: yes, `JTable` uses [*Class Literals as Runtime-Type Tokens*](http://docs.oracle.com/javase/tutorial/extra/generics/literals.html) to associate a data type with a custom renderer. – trashgod Sep 30 '14 at 17:42
2

Several things must work in concert:

  • Let column two, labeled Date, return Date.class from getColumnClass().

  • Ensure that only values of type Date.class are added to the TableModel.

  • Enforce the date format using a custom renderer and suitable DateFormat, e.g. "MMMM/yyyy", as shown here.

  • Adopt a convention regarding dates that are accurate to a month, e.g. first day of the month, and enforce it in your model's public interface.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045