I have a JXTable with two columns that hold string values and one column that holds a date time value that follows this format: yyyy-MM-dd HH:mm:ss.
Since I only care about the users changing the date, I thought I'd make use of DatePickerCellEditor from the Swingx package with a custom SimpleDateFormat("yyyy-MM-dd HH:mm:ss").
So far so good, except the problems start to occur when editing starts. The date part of the datetime is maintained, however, the time portion of it gets reset to "00:00:00" and to make matters worse, when I move to edit another cell, the value that remains in the cell that was being edited is the proper date, but the time at 00:00:00.
In other words, this
becomes this 
I have tried many things to fix this, including overriding the getTableCellEditorComponent from DatePickerCellEditor and printing the date directly from the JXDatePicker. I found out that somewhere along the way, the time part of the day was being reset to "00:00:00". I couldn't find out where. I then tried, within the getTableCellEditorComponent, manually setting the date by using JXDatePicker#setDate and that also didn't work.
One workaround I found was, inside getTableCellEditorComponent, calling JXDatePicker#getEditor and manually setting the date there, however, the time part of the cell value still gets reset when editing stops.
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;
}
}
Here's the sample code to work with:
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;
}
Is this behaviour intended? I am aware that JXDatePicker is for dates only, but I naturally assumed that it would preserve the time as long as the user didn't change the date.
Oh god, I think I did it. After MUCH digging, the problem lays with the
JXMonthViewcomponent that is inside theJXDatePicker. In short, it's using the wrong selection model. For it to properly work, we need to instantiate a newSingleDaySelectionModeland pass it to theJXMonthView.Documentation for the
JXDatePicker#setDatemethod that gave me the answer to my problem:Default initialisation in
JXDatePicker.java- as you can see, the line we need is commented:Since inheriting from
JXDatePickerwasn't an option, what I did was create a custom CellEditor like so:This preserves the time as needed.
Note: I'm using the compiled .jar so I can't edit source files. If using editable source files, naturally the best solution is to simply uncomment the line.