Final (hopefully :)
Summary of the first edit:
- DatePickerFormatter already implements a lookup strategy (or CompoundFormat, as suggested by @Robin)
- the lookup sequence for parsing is configurable by client code
- the idea is to try parsing starting with the first (typically the "longest"), if that fails try the next (typically "not-so-long") and so on until succeeded or a parseException is thrown
- for year parsing, SimpleDateFormat has rules that conflict with that longest-first lookup: it requires that "yy" is tried before "yyyy"
- doing so in datePicker has the unwanted side-effect of always showing the date with the short year format
The reason is DatePickerFormatter: it doesn't allow to specify the formatting format (simply uses the first). The way out is a custom DatePickerFormatter, which supports it (in the snippet, it's hardcoded to use the second):
SimpleDateFormat longFormat = new SimpleDateFormat( "dd.MM.yyyy" );
SimpleDateFormat shortFormat = new SimpleDateFormat( "dd.MM.yy" );
Date startDate = new Date( 0 );//01.01.1970
shortFormat.set2DigitYearStart( startDate );
DatePickerFormatter formatter = new DatePickerFormatter(
// invers sequence for parsing to satisfy the year parsing rules
new DateFormat[] {shortFormat, longFormat}) {
@Override
public String valueToString(Object value) throws ParseException {
if (value == null) return null;
return getFormats()[1].format(value);
}
} ;
DefaultFormatterFactory factory = new DefaultFormatterFactory(formatter );
picker.getEditor().setFormatterFactory(factory);
Not entirely sure if we should support configuring the formatter in the base class. The DatePickerFormatter is a bit strange beast, not extending InternalFormatter and with the lookup process being a bit in competition with a FormatterFactory...
Original
It's not exactly the datePicker which handles it that way, it's the core formatting (as D1e already noted). None of the default format/ter/s support two formats at the same time: to see, try to achieve your goal with a core JFormattedTextField :-)
The way out might be a FormatterFactory: it allows to use different formats, depending on context: display and edit - the latter is used when the field is focused, the former at all other times. As the picker's editor is a JFormattedTextField, you can configure it directly (instead of using the setFormats methods)
SimpleDateFormat format = new SimpleDateFormat( "dd.MM.yyyy" );
SimpleDateFormat editFormat = new SimpleDateFormat( "dd.MM.yy" );
final Date startDate = new Date( 0 );//01.01.1970
instance.setTime(startDate);
editFormat.set2DigitYearStart( instance.getTime() );
DefaultFormatterFactory factory = new DefaultFormatterFactory(
new DatePickerFormatter(new DateFormat[] {format}),
new DatePickerFormatter(new DateFormat[] {format}),
new DatePickerFormatter(new DateFormat[] {editFormat})
);
picker.getEditor().setFormatterFactory(factory);
Edit
head banging after reading Robin's recent answer (+1!) - at last, embarassingly after years and years, I understand what SwingX' DatePickerFormatter is trying to do: that is to support a lookup chain of formatters (from longer to shorter), the longest used after committing, the shorter to ease the typing by users.
Unfortunately that doesn't work as intuitively expected. Given a sequence of formats, longer to shorter (and appropriately configured to the century):
"yyyy", "yy"
and given input
"10"
feels like being passed on from first to second, resulting in
2010
but isn't. As documented (who reads documention ... lazy me, cough ...) in SimpleDateFormat
Year: [ ... ] For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits. So using the pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.
At the end of the day - as DatePickerFormatter tries to support that lookup but isn't successful - this might be considered a SwingX problem, after all :-)