0

I have a JTable and have added sorting. Now the JTable has 5 columns and the 2nd column in a date field converted to DD/MM/YYYY and displayed in a JTextField in the cell.

When I sort it sorts as string and I the dates get mixed up, how do I change the behaviour of sorting for that particular column?

eg. after sorting in ASC order, I get this:

01/02/2012
01/03/2011
01/04/2011
01/05/2011
01/06/2011
01/07/2011
01/08/2011
01/09/2011
01/10/2011
01/12/2011

Which is wrong, and I should be getting the result like

01/03/2011
01/04/2011
01/05/2011
01/06/2011
01/07/2011
01/08/2011
01/09/2011
01/10/2011
01/12/2011
01/02/2012

My code now looks like this for sorting

List<SortKey> sortKeys = new ArrayList<SortKey>();
sortKeys.add(new SortKey(2, SortOrder.ASCENDING));
table.getRowSorter().setSortKeys(sortKeys);

What should I change for that specific column only?

jmj
  • 237,923
  • 42
  • 401
  • 438
Vivek
  • 1,451
  • 8
  • 42
  • 74

2 Answers2

5

Because java.util.Date implements Comparable<Date>, it should be sufficient to let your TableModel return Date.class from getColumnClass() for column two. Use a Custom Renderer to format the date as desired.

Addendum: Here's an example using setDefaultRenderer().

import java.awt.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

/** @see http://stackoverflow.com/questions/4553448 */
public class TableDate extends JPanel {

    private static final int INT_COL = 0;
    private static final int DATE_COL = 1;
    private final Calendar calendar = Calendar.getInstance();
    private final CustomModel model = new CustomModel();
    private final JTable table = new JTable(model);

    public TableDate() {
        super(new GridLayout(1, 0));
        table.setAutoCreateRowSorter(true);
        table.setDefaultRenderer(Date.class, new DateRenderer());
        table.setPreferredScrollableViewportSize(new Dimension(320, 240));
        JScrollPane sp = new JScrollPane(table);
        this.add(sp);
        for (int i = 1; i <= 20; i++) {
            model.addRow(newRow(i));
        }
    }

    private Object[] newRow(int i) {
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        return new Object[]{Integer.valueOf(i), calendar.getTime()};
    }

    private static class CustomModel extends DefaultTableModel {

        private final String[] columnNames = {"Index", "Date"};

        @Override
        public Class<?> getColumnClass(int col) {
            if (col == INT_COL) {
                return Integer.class;
            } else if (col == DATE_COL) {
                return Date.class;
            }
            return super.getColumnClass(col);
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public String getColumnName(int col) {
            return columnNames[col];
        }
    }

    private static class DateRenderer extends DefaultTableCellRenderer {

        DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");

        public DateRenderer() {
            super();
        }

        @Override
        public void setValue(Object value) {
            setText((value == null) ? "" : formatter.format(value));
        }
    }

    private void display() {
        JFrame f = new JFrame("TableDate");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TableDate().display();
            }
        });
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • In my gerColumnClass for column two, if I return Date.class, I get the following error Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Cannot format given Object as a Date at java.text.DateFormat.format(Unknown Source) at java.text.Format.format(Unknown Source) at javax.swing.JTable$DateRenderer.setValue(Unknown Source) at javax.swing.table.DefaultTableCellRenderer.getTableCellRendererComponent(Unknown Source) – Vivek Dec 29 '10 at 12:30
2

You need to implement comparator that treats date string as Date rather simple String have a look here

jmj
  • 237,923
  • 42
  • 401
  • 438
  • Thanks for the quick link, when I try to render it as a Date , I get an exception "Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Cannot format given Object as a Date", how do i resolve this? – Vivek Dec 29 '10 at 11:35
  • no render it as String only , but in comparator create Date from String and then compare – jmj Dec 29 '10 at 11:37