java JFormattedTextField :输入持续时间值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2234726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JFormattedTextField : input time duration value
提问by bguiz
I want to use a JFormattedTextFieldto allow the user to input time durationvalues into a form. Sample valid values are:
我想使用 aJFormattedTextField来允许用户将持续时间值输入到表单中。示例有效值为:
2h 30m72h 15m6h0h
2h 30m72h 15m6h0h
However I am having limited success with this. Can some one please suggest how this can be accomplished? I am OK if this result can be achieved using a JTextFieldas well.
但是,我在这方面取得的成功有限。有人可以建议如何做到这一点吗?如果使用 a 也可以实现此结果,我就可以了JTextField。
Thanks!
谢谢!
If it is worth anything, here's my current attempt:
如果值得的话,这是我目前的尝试:
mFormattedText.setFormatterFactory(
new DefaultFormatterFactory(
new DateFormatter(
new SimpleDateFormat("H mm"))));
This sorta works except that:
这种工作方式除了:
I cannot get*handmto appear as plain text (I tried escaping)- The number of hours has a max
我无法获取*h并m显示为纯文本(我尝试转义)- 小时数有最大值
*: See @nanda's answer
*:见@nanda 的回答
采纳答案by nanda
The code:
代码:
public static void main(String[] args) {
JFrame jFrame = new JFrame();
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setLayout(new BorderLayout());
jFrame.setPreferredSize(new Dimension(500, 500));
final JFormattedTextField comp = new JFormattedTextField();
comp.setFormatterFactory(new DefaultFormatterFactory(new DateFormatter(new SimpleDateFormat(
"H'h' mm'm'"))));
comp.setValue(Calendar.getInstance().getTime());
comp.addPropertyChangeListener("value", new PropertyChangeListener() {
@Override public void propertyChange(PropertyChangeEvent evt) {
System.out.println(comp.getValue());
}
});
jFrame.getContentPane().add(comp, BorderLayout.CENTER);
jFrame.pack();
jFrame.setVisible(true);
}
回答by trashgod
Here's an example of using InputVerifierto accommodate multiple input formats.
这是一个InputVerifier用于适应多种输入格式的示例。
import java.awt.EventQueue;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.Box;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.text.DateFormatter;
import javax.swing.text.DefaultFormatterFactory;
public class FormattedFields {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
//@Override
public void run() {
new FormattedFields();
}
});
}
FormattedFields() {
Box form = Box.createVerticalBox();
form.add(new JLabel("Date & Time:"));
DateTimeField dtField = new DateTimeField(new Date());
form.add(dtField);
form.add(new JLabel("Amount:"));
JFormattedTextField amtField = new JFormattedTextField(
NumberFormat.getCurrencyInstance());
amtField.setValue(100000);
form.add(amtField);
JFrame frame = new JFrame();
frame.add(form);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class DateTimeField extends JFormattedTextField {
public DateTimeField() {
super(DateTimeVerifier.getDefaultFormat());
this.setInputVerifier(new DateTimeVerifier(this));
}
public DateTimeField(Date date) {
this();
this.setValue(date);
}
@Override
protected void invalidEdit() {
if (!this.getInputVerifier().verify(this)) {
super.invalidEdit();
}
}
}
class DateTimeVerifier extends InputVerifier {
private static List<SimpleDateFormat> validForms =
new ArrayList<SimpleDateFormat>();
static {
validForms.add(new SimpleDateFormat("dd-MMM-yyyy HH'h':mm'm'"));
validForms.add(new SimpleDateFormat("dd-MMM-yyyy HH:mm"));
}
private JFormattedTextField tf;
private Date date;
public DateTimeVerifier(JFormattedTextField tf) {
this.tf = tf;
}
@Override
public boolean verify(JComponent input) {
boolean result = false;
if (input == tf) {
String text = tf.getText();
for (SimpleDateFormat format : validForms) {
try {
date = format.parse(text);
result |= true;
} catch (ParseException pe) {
result |= false;
}
}
}
return result;
}
@Override
public boolean shouldYieldFocus(JComponent input) {
if (verify(input)) {
tf.setValue(date);
return true;
} else {
return false;
}
}
public static SimpleDateFormat getDefaultFormat() {
return validForms.get(0);
}
}
回答by nanda
Have you tried H'h' mm'm'?
你试过H'h' mm'm'吗?
回答by Basil Bourque
tl;dr
tl;博士
Duration.parse( "PT2H30M" )
ISO 8601
ISO 8601
If you are willing to redefine your desired input formats, I suggest using the already-existing formats defined by the ISO 8601standard.
如果您愿意重新定义所需的输入格式,我建议使用ISO 8601标准定义的现有格式。
The pattern PnYnMnDTnHnMnSuses a Pto mark the beginning, a Tto separate any years-months-days portion from any hours-minutes-seconds portion.
该模式PnYnMnDTnHnMnS使用 aP来标记开始,使用 aT将任何年-月-日部分与任何时-分-秒部分分开。
An hour-and-a-half is PT1H30M, for example.
PT1H30M例如,一个半小时。
java.time
时间
The java.time classes use the ISO 8601 formats by default when parsing/generating strings. This includes the Periodand Durationclasses for representing spans of time not attached to the timeline.
java.time 类在解析/生成字符串时默认使用 ISO 8601 格式。这包括用于表示未附加到时间线的时间跨度的Period和Duration类。
Duration d = Duration.ofHours( 1 ).plusMinutes( 30 );
String output = d.toString();
Going the other direction, parsing a string.
走向另一个方向,解析一个字符串。
Duration d = Duration.parse( "PT1H30M" );
See my similar Answerto a similar Question.
About java.time
关于 java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8and SE 9and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- The ThreeTenABPproject adapts ThreeTen-Backport(mentioned above) for Android specifically.
- See How to use ThreeTenABP….
- Java SE 8和SE 9及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 所述ThreeTenABP项目适应ThreeTen-反向移植(上述)为Android特异性。
- 请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval,YearWeek,YearQuarter,和更多。
回答by ultrajohn
hmm, what i think is that you can achieve the same goal by, creating three different JTextField for all the three time components, one for the HOUR, MINUTE and Second (if it's included) to get your input... just a thought, you could just concatenate them if you it's necessary... just a thought...
嗯,我认为您可以通过为所有三个时间组件创建三个不同的 JTextField 来实现相同的目标,一个用于 HOUR、MINUTE 和 Second(如果包含)以获取您的输入......只是一个想法,如果有必要,你可以将它们连接起来......只是一个想法......

