代码之家  ›  专栏  ›  技术社区  ›  Morgan

DatePickerCellEditor重置单元格编辑开始和停止的时间

  •  0
  • Morgan  · 技术社区  · 8 年前

    我有一个 JXTable 两列保存字符串值,一列保存日期时间值,格式如下: yyyy-MM-dd HH:mm:ss .

    由于我只关心用户更改日期,我想我应该利用 DatePickerCellEditor 从带有自定义 SimpleDateFormat("yyyy-MM-dd HH:mm:ss") .

    到目前为止还不错,只是编辑开始时问题开始出现。datetime的日期部分是保留的,但是,它的时间部分被重置为“00:00:00”,更糟糕的是,当我移动到编辑另一个单元格时,被编辑的单元格中保留的值是正确的日期,但时间是00:00:00。

    换句话说 Before edit 变成这样 enter image description here

    我尝试了很多方法来修复此问题,包括重写 getTableCellEditorComponent 从…起 日期选择器Celleditor 并直接从 JXDatePicker . 我发现一路上的某个地方,一天的时间部分被重置为“00:00:00”。我找不到在哪里。然后我试着在 GetTableCellEditor组件 ,使用手动设置日期 JXDatePicker#setDate 这也没用。

    我找到的一个解决方法是 GetTableCellEditor组件 使命感 JXDatePicker#getEditor 但是,当编辑停止时,单元格值的时间部分仍会重置。

    public class SQLDatePickerCellEditor extends DatePickerCellEditor {
    
        public SQLDatePickerCellEditor(DateFormat dateFormat) {
            super(dateFormat);
        }
    
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            JXDatePicker picker = (JXDatePicker) super.getTableCellEditorComponent(table, value, isSelected, row, column);
            picker.getEditor().setText(value.toString());
            System.out.println(picker.getDate()); //this prints the correct date but for some reason at 00:00:00
            return picker;
        }
    
    }
    

    下面是要使用的示例代码:

    public class DateForm extends javax.swing.JFrame {
    
        public DateForm() {
            initComponents();
            pack();
            setLocationRelativeTo(null);
            initModel();
        }
    
        public void initModel() {
            Class<?>[] types = new Class<?>[]{String.class, String.class, Date.class};
            Object[][] data = new Object[][]{
                {"John", "Smith", new Date(System.currentTimeMillis())}
            };
            DefaultTableModel model = new DefaultTableModel(data, new String[]{"Name", "Surname", "Date"}) {
                @Override
                public Class<?> getColumnClass(int columnIndex) {
                    return types[columnIndex];
                }
            };
    
            table.setModel(model);
            table.getColumn(2).setCellEditor(new DatePickerCellEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")));
            StringValue sv = new FormatStringValue(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            TableCellRenderer r = new DefaultTableRenderer(sv);
            table.getColumn(2).setCellRenderer(r);
        }
    
        @SuppressWarnings("unchecked")                      
        private void initComponents() {
    
            scrPane = new javax.swing.JScrollPane();
            table = new org.jdesktop.swingx.JXTable();
    
            setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
            setPreferredSize(new java.awt.Dimension(500, 500));
            scrPane.setViewportView(table);
    
            getContentPane().add(scrPane, java.awt.BorderLayout.CENTER);
        }                     
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    DateForm df = new DateForm();
                    df.setVisible(true);
                }
            });
        }
    
        private javax.swing.JScrollPane scrPane;
        private org.jdesktop.swingx.JXTable table;               
    
    }
    

    这种行为是故意的吗?我知道 JXDatePicker 只针对日期,但我自然认为只要用户不更改日期,它就会保留时间。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Morgan    8 年前

    天啊,我想我做到了。经过大量挖掘,问题在于 JXMonthView 位于 JXDatePicker . 简而言之,它使用了错误的选择模型。为了让它正常工作,我们需要实例化一个新的 SingleDaySelectionModel 并将其传递给 JXMonthView .

    的文档 JXDatePicker#setDate 为我的问题提供答案的方法:

    设置日期属性。

    如果ui否决了新日期,则不会执行任何操作-如果 代码尝试设置在 monthView的背景。控制新日期的实际值 通过JXMonthView的DateSelectionModel。 默认实现 将日期标准化为模型日历中一天的开始 坐标,即所有时间字段均为零。要保留时间字段, 使用SingleDaySelectionModel配置monthView .

    中的默认初始化 JXDatePicker.java -正如您所看到的,我们需要的行被注释为:

    private void initMonthView() {
        _monthView = new JXMonthView();
        //        _monthView.setSelectionModel(new SingleDaySelectionModel());
        _monthView.setTraversable(true);
        _monthView.addPropertyChangeListener(getMonthViewListener());
    }
    

    自继承自 JXDatePicker 不是一个选项,我所做的是创建一个自定义CellEditor,如下所示:

    public class SQLDatePickerCellEditor extends DatePickerCellEditor {
    
        public SQLDatePickerCellEditor() {
            super(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            datePicker.getMonthView().setSelectionModel(new SingleDaySelectionModel());
        }
    
    }
    

    这样可以根据需要保留时间。

    注意:我使用的是编译后的。所以我不能编辑源文件。如果使用可编辑的源文件,最好的解决方案自然是取消对行的注释。