JXDatePicker 使用 SimpleDateFormat 将 dd.MM.yy 格式化为当前世纪的 dd.MM.yyyy
正如已经解释过的,我想要实现的目标是,当用户在 JXDatePicker 中编辑日期时,他可以选择是否以相同的格式再次键入日期,默认情况下是 dd.MM.yyyy 或只是 dd.MM.yy 。当他使用缩写形式时,我希望选择器选择当前世纪。
示例:
27.01.2012 edited to 27.01.10 should result in 27.01.2010
以及:
27.01.2012 edited to 27.01.2010 should also result in 27.01.2010
默认情况下,JXDatePicker 按以下方式处理它:
27.01.2012 edited to 27.01.10 results in 27.01.0010
这并不是我真正想要的工作方式。经过一些简短的研究后,我在 SimpleDateFormat 中发现了以下方法
/**
* Sets the 100-year period 2-digit years will be interpreted as being in
* to begin on the date the user specifies.
*
* @param startDate During parsing, two digit years will be placed in the range
* <code>startDate</code> to <code>startDate + 100 years</code>.
*/
public void set2DigitYearStart(Date startDate)
第一次查看时,这听起来与我所需要的完全一样。所以我测试了它,不幸的是它没有像我希望的那样工作。这是因为我想使用 dd.MM.yyyy 作为显示日期的格式,并且还希望它像编辑模式下那样显示。例如,当用户单击像 2012 年 1 月 27 日这样的日期时,我也希望它在编辑模式下也如此,而不仅仅是缩写形式:27.01.12。
我现在的问题是,不幸的是,当我选择在编辑模式下使用简写形式时, set2DigitYearStart(Date) 才有效。我做了一个小例子来展示这种情况(需要 SwingX 库,因为 jxdatepicker,可以在 此处 找到)。
public class DatePickerExample extends JPanel
{
static JFrame frame;
public DatePickerExample()
{
JXDatePicker picker = new JXDatePicker();
JTextField field = new JTextField( 10 );
add( field );
add( picker );
final Calendar instance = Calendar.getInstance();
instance.set( 2012, 01, 26 );
Date date = instance.getTime();
picker.setDate( date );
// SimpleDateFormat format = new SimpleDateFormat( "dd.MM.yy" );//Works, but I wonna display and edit it with dd.MM.yyyy
SimpleDateFormat format = new SimpleDateFormat( "dd.MM.yyyy" );
final Date startDate = new Date( 0 );//01.01.1970
format.set2DigitYearStart( startDate );
picker.setFormats( format );
}
public static void main( String[] args )
{
frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setBounds( 400, 400, 400, 400 );
frame.setLayout( new BorderLayout() );
frame.add( new DatePickerExample() );
frame.setVisible( true );
}
}
有人已经有相同的要求并且可以告诉我如何使这项工作有效吗?欢迎任何想法。预先非常感谢您。伊梅内
as already explained I want to achieve, that when the user is editing a date within a JXDatePicker, he can choose, weather he types it again in the same format, which is by default dd.MM.yyyy or just dd.MM.yy. When he uses the short form I want the Picker to choose the current century.
Example:
27.01.2012 edited to 27.01.10 should result in 27.01.2010
as well as:
27.01.2012 edited to 27.01.2010 should also result in 27.01.2010
By default the JXDatePicker handels it the following way:
27.01.2012 edited to 27.01.10 results in 27.01.0010
Which is not really the way I wanted it to work. After some short research I found the following Method in SimpleDateFormat
/**
* Sets the 100-year period 2-digit years will be interpreted as being in
* to begin on the date the user specifies.
*
* @param startDate During parsing, two digit years will be placed in the range
* <code>startDate</code> to <code>startDate + 100 years</code>.
*/
public void set2DigitYearStart(Date startDate)
On first view this sounded exactly like what I need. So I tested it and unfortunatly it didnt work like I hoped it would. This is because I want to use dd.MM.yyyy as format to display dates and also want it to be displayed like that in editmode. For example when the user klicks on a date like 27.01.2012, I also want it to be like that in editmode, too and not just the short form: 27.01.12.
My Problem now is, that set2DigitYearStart(Date) unfortunatly only works, when I choose to use the shortform in editmode. I made a small example to show this case (SwingX Library is required, because of jxdatepicker and can be found be here).
public class DatePickerExample extends JPanel
{
static JFrame frame;
public DatePickerExample()
{
JXDatePicker picker = new JXDatePicker();
JTextField field = new JTextField( 10 );
add( field );
add( picker );
final Calendar instance = Calendar.getInstance();
instance.set( 2012, 01, 26 );
Date date = instance.getTime();
picker.setDate( date );
// SimpleDateFormat format = new SimpleDateFormat( "dd.MM.yy" );//Works, but I wonna display and edit it with dd.MM.yyyy
SimpleDateFormat format = new SimpleDateFormat( "dd.MM.yyyy" );
final Date startDate = new Date( 0 );//01.01.1970
format.set2DigitYearStart( startDate );
picker.setFormats( format );
}
public static void main( String[] args )
{
frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setBounds( 400, 400, 400, 400 );
frame.setLayout( new BorderLayout() );
frame.add( new DatePickerExample() );
frame.setVisible( true );
}
}
Anyone already had the same requirement and can tell me how to make this work? Any ideas are welcome. Thank you very much in advance. ymene
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
最终(希望:)
第一次编辑摘要:
原因是 DatePickerFormatter:它不允许指定格式化格式(仅使用第一个)。出路是自定义 DatePickerFormatter,它支持它(在代码片段中,它被硬编码为使用第二个):
不完全确定我们是否应该支持在基类中配置格式化程序。 DatePickerFormatter 是一个有点奇怪的野兽,没有扩展InternalFormatter,并且查找过程与FormatterFactory 有点竞争......
原始
这并不完全是datePicker 以这种方式处理它,它是核心格式化(正如 D1e 已经指出的那样)。没有一个默认格式同时支持两种格式:要看看,尝试使用核心 JFormattedTextField 来实现您的目标:-)
出路可能是 FormatterFactory:它允许根据上下文使用不同的格式:显示和编辑 - 后者在字段聚焦时使用,前者在所有其他时间使用。由于选择器的编辑器是一个JFormattedTextField,因此您可以直接配置它(而不是使用setFormats方法)
编辑
在阅读Robin最近的答案后(+1!) - 在最后,令人尴尬的是,多年后,我明白了 SwingX 的 DatePickerFormatter 正在尝试做的事情:那就是支持格式化程序的查找链(从长到短),提交后使用最长的,更短以方便用户打字。
不幸的是,这并不像直观预期的那样工作。给定一系列格式,从长到短(并根据世纪进行适当配置):
给定的输入
感觉像是从第一个传递到第二个,结果是
但不是。正如 SimpleDateFormat 中记录的那样(谁读文档...懒惰的我,咳嗽...)
结束时 - 由于 DatePickerFormatter 尝试支持该查找但没有成功 - 这可能会被考虑毕竟是 SwingX 问题:-)
Final (hopefully :)
Summary of the first edit:
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):
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)
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):
and given input
feels like being passed on from first to second, resulting in
but isn't. As documented (who reads documention ... lazy me, cough ...) in SimpleDateFormat
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 :-)
我不太清楚 JXDatePicker 具体情况,但如果您要模拟的具体功能是:用户输入 27.01.2010 和 27.01.10 独立应该得到 27.01.2010
那么这将起作用:
<事情是,首先您使用“dd.MM.yy”模式解析输入,然后使用“dd.MM.yyyy”格式返回它 图案。
希望这有助于或有助于将其应用到您的场景中。
I am not quite aware of JXDatePicker specifically, but if the concrete functionality you want to simulate is: Both user inputs 27.01.2010 and 27.01.10 independently should result in 27.01.2010
Then this will work:
The thing is that first you parse input with "dd.MM.yy" pattern and then return it formatting with "dd.MM.yyyy" pattern.
Hope this helps or helps applying this to your scenario.
kleopatra 已经解释了如何在日期选择器上设置
格式
。对于此用例,我将应用CompositeFormat
和ParseAllFormat
的组合,而不是使用单独的格式进行编辑和常规模式,以避免更改String< /code> 当您开始编辑时(正如您已经注意到的那样)。
复合格式
复合格式,顾名思义,是一种复合实现Format 类的 > 但仅用于解析。对于格式设置,它使用一种
Format
。这允许用户以多种形式输入他/她的日期,同时通过使用一种特定的格式来格式化一致的日期。您也可以通过编写一种更复杂的
Format
来获得此行为。但在这种情况下,使用 JDK 的 SimpleDateFormat 类提供的格式化/解析功能会更容易。ParseAllFormat
通常,对于用户输入,您希望可以对整个用户输入进行格式化/解析,以避免用户输入半正确的字符串。
ParseAllFormat
是常规Format装饰器当只能解析部分
String
时,它会抛出ParseException
。这两个类的组合允许使用以下代码,
从而产生以下输出
请注意,有一个小问题我没有找到合适的解决方案。将
Format
实例添加到CompositeFormat
的顺序也是对它们进行解析的评估顺序。在这种情况下,您需要以正确的顺序添加它们,因为即使new SimpleDateFormat( "dd.MM.yyyy" )
似乎也接受输入字符串27.01.10
并且可以将整个String
解析为相当于27.01.0010
的Date
对象。kleopatra already explained on how to set a
Format
on the date picker. For this use-case, I would apply a combination of aCompositeFormat
andParseAllFormat
instead of having a separate format for editing and regular mode to avoid changing theString
when you start editing (as you already noticed).Composite format
The composite format, as the name suggests, is a composite implementation of the
Format
class but only for the parsing. For the formatting, it uses oneFormat
. This allows the user to input his/her date in many forms, while it is formatted consistently by using one specific format to format.You can obtain this behavior as well by writing one more sophisticated
Format
. But in this case, it is easier to just use the formatting/parsing functionality offered by theSimpleDateFormat
class of the JDK.ParseAllFormat
Typically for user input you want that the whole user input can be formatted/parsed to avoid that the user can input a String which is half-correct. The
ParseAllFormat
is a decorator for a regularFormat
which throwsParseException
s when only part of theString
can be parsed.The combination of these both classes allows for the following code
resulting in the following output
Note that there is a small catch for which I did not found a decent solution. The order in which you add
Format
instances to theCompositeFormat
is also the order in which they are evaluated for the parsing. In this case you need to add them in the correct order as even thenew SimpleDateFormat( "dd.MM.yyyy" )
seems to accept the input string27.01.10
and can parse the wholeString
to aDate
object equivalent to27.01.0010
.