2

I am querying a MySQL table and selecting varchar, Date, Time, Double, and Boolean data types. I take the data from the ResultSet and put it in a DefaultTableModel, which then gets put in a JTable, and then a JScrollPane for displaying.

All of the data is displayed correctly except the columns with java.sql.Time objects in them. These are being displayed as a date object, and they all have the value of Jan 1, 1970.

It seems that java.sql.Time objects are being read as java.sql.Date objects (I am guessing Jan 1, 1970 is being returned because the time value is outside of the range that would be valid for a date object).

I am confused because if I override the getColumnClass method in the DefaultTableModel to always return String.class and use the table method setAutoCreateRowSorter(true), when I click on the header of a column containing java.sql.Time objects to sort it, a java.lang.ClassCastException is thrown, and it says that java.sql.time can't be cast as a String. Why does this correctly identify the data as java.sql.Time, but if I override the DefaultTableModel getColumnClass to return the correct class, it sees it as a date instead of a time? Any help resolving the issue would be greatly appreciated. Here is how I am overriding he getColumnClass method in the DefaultTableModel:

        model = new DefaultTableModel() {
            @Override
            public Class<?> getColumnClass(int columnIndex) {
                if (columnIndex == numberOfColumns) {
                    return Boolean.class;
                } else {
                    return getValueAt(1, columnIndex).getClass(); //return actual class
                    return String.class; //return string regardless of what class is
                }
            }
        };
Riggster
  • 107
  • 3
  • 15
  • 1
    Does [this](http://stackoverflow.com/questions/3323618/handling-mysql-datetimes-and-timestamps-in-java) help? You're parsing `java.sql.Time` timestamps into a `String`. That's bad form. – S.R.I May 13 '12 at 05:23
  • The link gave me a better idea of what is happening. The JTable sees both java.sql.time and java.sql.date objects as subclasses of java.util.date, and so both get displayed as dates, instead of dates being displayed as dates and times being displayed as times. Any ideas on how to properly display java.sql.time objects? – Riggster May 13 '12 at 06:00
  • again, doing this by hand is not correct. Your MySQL JDBC driver should hide all specifics about the timestamp and should only return timestamps. As said in the link, use `ResultSet#getTimestamp()` – S.R.I May 13 '12 at 06:15

1 Answers1

3

The ClassCastException is coming because you are trying to cast the Time class as an String. It appears as an Date object because java.sql.Time and java.sql.Date are both subclasses of java.util.Date. These subclasses are just thin wrappers (Same thing with just enough extra information to be mapped in to SQL columns). So in a Swing JTable it's being used as java.util.Date since java.sql types are irrelevant to swing components for the most part.

Thihara
  • 7,031
  • 2
  • 29
  • 56
  • I'm not actually trying to cast the Time class as a string. I just did that to show that if I cast a Time object as a String, then a ClassCastException correctly identifies it as a java.sql.Time object, but if I don't cast it incorrectly, the JTable mistakes the Time object as a Date object. Any suggestions on how to get around this? – Riggster May 13 '12 at 05:45
  • 1
    Like I said Time is a subclass of Date. So JTable is handling Date objects and don't see any difference between Date and Time. What exactly do you mean by get around this?? Are you asking how to display just the time or what? – Thihara May 13 '12 at 06:24
  • Yes I am trying to figure out how to display the time. Please don't tell me to not override getColumnClass. I need to manually specify the class of one column for some custom rendering I am doing in my JTable. If I don't override the getColumnClass method in the DefaultTableModel the time displays correctly. However, if I override the above method to return getValueAt(row, column).getClass() then a column containing java.sql.time displays Jan 1, 1970 and a column containing java.sql.Timestamp displays just the date part of the object. – Riggster May 14 '12 at 15:05
  • Well if you want to override the default behavior of how date is displayed you can use a CustomRenderer http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#renderer. Or you can just format the date with just the time and display it as a String. Whichever works for you mate. Let me know if that also doesn't work! – Thihara May 15 '12 at 02:11