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

时间:2018-01-10 23:54:51

标签: java swingx jxtable

我有一个JXTable,其中两列包含字符串值,另一列包含遵循此格式的日期时间值:yyyy-MM-dd HH:mm:ss

由于我只关心用户更改日期,因此我认为我会使用自定义DatePickerCellEditor的Swingx包中的SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

到目前为止一切顺利,除了编辑开始时问题开始发生。保留日期时间的日期部分,但是,它的时间部分被重置为“00:00:00”并且更糟糕的是,当我移动编辑另一个单元格时,剩余的单元格中的值仍然存在编辑是正确的日期,但时间是00:00:00。

换句话说,此Before edit成为enter image description here

我尝试过很多方法来解决这个问题,包括从getTableCellEditorComponent覆盖DatePickerCellEditor并直接从JXDatePicker打印日期。我发现在路上的某个地方,当天的部分时间被重置为“00:00:00”。我找不到哪里。然后,我尝试在getTableCellEditorComponent内使用JXDatePicker#setDate手动设置日期,但也无效。

我找到的一个解决方法是,在getTableCellEditorComponent内,调用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 个答案:

答案 0 :(得分:0)

天啊,我想我做到了。经过多次挖掘后,问题出现在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());
    }

}

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

注意:我正在使用已编译的.jar,因此无法编辑源文件。如果使用可编辑的源文件,自然最好的解决方案是简单地取消注释该行。