问题
I am using JIDE grids Sorting and Autofiltering capability in Matlab. I have overridden the getColumnClass and filtering and sorting is working well for Integers, Double and String Columns (sorting numerically for numbers and lexically respectively for strings).
However, I am facing a major issues with Date columns. I have overridden getColumn class and defined as Date.class. But I think I have to define the format in which the dates (as in raw data) are being passed to Filtering and Sorting for it to understand the format and work properly.
I see default date format in JIDE Autofiltering is '07-Apr-2016'. I have tried converting my data to same format but no luck. If I try to filter the dates, it throws (Unknown Source) exception. I think it does not understand my date format. How can I define the date format when overriding the class for Date column?
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException:
java.util.Date cannot be cast to java.lang.String
at java.lang.String.compareTo(Unknown Source)
at com.jidesoft.filter.LessThanFilter.isValueFiltered(Unknown Source)
at com.jidesoft.grid.FilterableTableModel.shouldBeFiltered(Unknown Source)
Here is my TableModel class that overrides DefaultTableModel.
import javax.swing.table.*;
import java.util.Date;
class MyTableModel extends DefaultTableModel {
public MyTableModel(Object rowData[][], Object columnNames[]) {
super(rowData, columnNames);
}
@Override
public Class getColumnClass(int col) {
switch (col){
case 0:
return Integer.class;
case 1: case 2: case 9:
case 10: case 33:
return String.class;
case 3:
return Date.class;
default:
return Double.class;
}
}
@Override
public boolean isCellEditable(int row, int col) {
switch (col){
case 28: case 29: case 30: case 31: case 32:
return true;
default:
return false;
}
}
}
回答1:
I don't know anything about JIDE so all my comments are for regular classes in the JDK.
I see default date format in JIDE Autofiltering is '07-Apr-2016'.
That looks like a String to me. If you want the column to contain a Date
, then you need to store a Date
object in the TableModel
, not a String representation of a date.
Then you would typically add a custom renderer to the table to display the date in an appropriate format.
For example:
public class YMDRenderer extends DefaultTableCellRenderer
{
private Format formatter = new SimpleDateFormat("yy/MM/dd");
public void setValue(Object value)
{
// Format the Object before setting its value in the renderer
try
{
if (value != null)
value = formatter.format(value);
}
catch(IllegalArgumentException e) {}
super.setValue(value);
}
}
You can also check out Table Format Renderers which contains reusable renderers you can use simply by providing a Format object to the renderer. This will save you creating unique renderers for each data format you want.
Edit:
I guess I have to use FormatConverter of some sort to do that
You can use the SimpleDateFormat
class and the parse(String) method to parse the String to a Date object.
回答2:
Exception said : java.util.Date cannot be cast to java.lang.String. That means, like Camickr pointed out, that the Dates were in fact stored as strings in my TableModel rather than Date object. I converted the Strings to Date object using SimpleDateFormat class. For the benefit of other novice java learners, below is the code snippet that performs just that.
import javax.swing.table.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MyTableModel extends DefaultTableModel{
public MyTableModel(Object rowData[][], Object columnNames[]){
super(rowData, columnNames);
String ExpectedDateFormat = (String) ("dd/mm/yyyy");
SimpleDateFormat format = new SimpleDateFormat(ExpectedDateFormat);
Date strToDate = null;
for (int i=0; i<rowData.length;i++){
String DateStr = (String) super.getValueAt(i,3);
try {
strToDate = format.parse(DateStr);
// System.out.println(strToDate);
} catch (ParseException e) {
// e.printStackTrace();
}
super.setValueAt(strToDate,i,3);
}
}
@Override
public Class getColumnClass(int col) {
switch (col){
case 0:
return Integer.class;
case 1: case 2: case 9:
case 10: case 33:
return String.class;
case 3:
return Date.class;
default:
return Double.class;
}
}
@Override
public boolean isCellEditable(int row, int col) {
switch (col){
case 28: case 29: case 30: case 31: case 32:
return true;
default:
return false;
}
}
}
The display of the date data in a uitable can be control using the same class (SimpleDateFormat) just as Camickr mentioned above.
Another thread that I found afterwards that explains and resolves the same issue: HERE
来源:https://stackoverflow.com/questions/36488426/override-getcolumnclass-not-working-for-date-columns