【问题标题】:Override getColumnClass not working for Date Columns覆盖 getColumnClass 不适用于日期列
【发布时间】:2016-04-10 03:20:47
【问题描述】:

我在 Matlab 中使用 JIDE 网格排序和自动筛选功能。我已经覆盖了 getColumnClass 并且过滤和排序对于整数、双精度和字符串列都运行良好(对数字进行数字排序,对字符串进行词法排序)。

但是,我面临日期列的一个主要问题。我已经覆盖了 getColumn 类并定义为 Date.class。但我认为我必须定义将日期(如原始数据)传递给过滤和排序的格式,以便它理解格式并正常工作。

我看到 JIDE 自动过滤中的默认日期格式是 '07-Apr-2016'。我尝试将我的数据转换为相同的格式,但没有运气。如果我尝试过滤日期,它会抛出(未知来源)异常。我认为它不理解我的日期格式。覆盖日期列的类时如何定义日期格式?

    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)

这是我的 TableModel 类,它覆盖了 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;
        }
    }
}

【问题讨论】:

    标签: java swing matlab date jide


    【解决方案1】:

    我对 JIDE 一无所知,所以我所有的 cmets 都是 JDK 中的常规类。

    我看到 JIDE 自动过滤中的默认日期格式是 '07-Apr-2016'。

    对我来说这看起来像一个字符串。如果希望列包含Date,则需要在TableModel 中存储Date 对象,而不是日期的字符串表示形式。

    然后,您通常会在表格中添加自定义渲染器,以便以适当的格式显示日期。

    例如:

    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);
        }
    }
    

    您还可以查看Table Format Renderers,其中包含可重复使用的渲染器,您只需向渲染器提供一个 Format 对象即可使用。这将节省您为所需的每种数据格式创建唯一的渲染器。

    编辑:

    我想我必须使用某种格式转换器来做到这一点

    您可以使用SimpleDateFormat 类和 parse(String) 方法将 String 解析为 Date 对象。

    【讨论】:

    • 关于 JIDE 日期格式:很抱歉造成混淆,但我在日期上添加了引号以使格式在文本中脱颖而出。我已经使用自定义 TableRenderer 控制了日期、颜色等外观。您已经正确指出我的 TableModel 中有日期字符串而不是日期对象。我想我必须使用某种形式的 FormatConverter 来做到这一点,对不起,我不是程序员,任何有关这方面的指导都会有所帮助。谢谢。
    【解决方案2】:

    异常说:java.util.Date 不能转换为 java.lang.String。这意味着,就像 Camickr 指出的那样,日期实际上是作为字符串存储在我的 TableModel 中的,而不是 Date 对象中。我使用 SimpleDateFormat 类将字符串转换为日期对象。为了其他 java 初学者的利益,下面是执行此操作的代码 sn-p。

    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;
            }
        }
    }
    

    可以使用与上面提到的 Camickr 相同的类 (SimpleDateFormat) 来控制 uitable 中日期数据的显示。

    我后来发现的另一个帖子解释并解决了同样的问题:HERE

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 2011-03-02
      • 1970-01-01
      • 2016-03-31
      • 2014-03-18
      • 2016-12-16
      相关资源
      最近更新 更多