我有一个JXTable
,其中两列包含字符串值,另一列包含遵循此格式的日期时间值:yyyy-MM-dd HH:mm:ss
。
由于我只关心用户更改日期,因此我认为我会使用自定义DatePickerCellEditor
的Swingx包中的SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
。
到目前为止一切顺利,除了编辑开始时问题开始发生。保留日期时间的日期部分,但是,它的时间部分被重置为“00:00:00”并且更糟糕的是,当我移动编辑另一个单元格时,剩余的单元格中的值仍然存在编辑是正确的日期,但时间是00:00:00。
我尝试过很多方法来解决这个问题,包括从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
仅适用于日期,但我自然认为只要用户没有更改日期,它就会保留时间。
答案 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,因此无法编辑源文件。如果使用可编辑的源文件,自然最好的解决方案是简单地取消注释该行。