JFormattedTextField:input持续时间值
我想使用JFormattedTextField
来允许用户input时间值到表单中。 示例有效值是:
2h 30m
72h 15m
6h
0h
但是,我在这方面取得了有限的成功。 有人可以build议如何做到这一点? 如果使用JTextField
也可以实现这个结果,我很好。
谢谢!
如果这是值得的,这是我目前的尝试:
mFormattedText.setFormatterFactory( new DefaultFormatterFactory( new DateFormatter( new SimpleDateFormat("H mm"))));
这种工作除了:
-
我不能让*h
和m
显示为纯文本(我尝试转义) - 小时数有一个最大值
*:看@南达的答案
代码:
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); }
以下是使用InputVerifier
来适应多种input格式的示例。
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); } }
你试过H'h' mm'm'
吗?
嗯,我认为你可以达到相同的目标,为所有三个时间组件创build三个不同的JTextField,一个用于HOUR,MINUTE和Second(如果包含)来获得您的input…只是一个想法,你可以把它们连接起来,如果你有必要的话…只是一个想法…
TL;博士
Duration.parse( "PT2H30M" )
ISO 8601
如果你愿意重新定义你想要的input格式,我build议使用ISO 8601标准定义的已经存在的格式。
模式PnYnMnDTnHnMnS
使用P
来标记开始, T
将任何年 – 月 – 日部分与任何小时 – 分钟 – 秒部分分开。
例如,一个半小时是PT1H30M
。
java.time
parsing/生成string时,java.time类默认使用ISO 8601格式。 这包括用于表示时间跨度不附加到时间轴上的Period
和Duration
类。
Duration d = Duration.ofHours( 1 ).plusMinutes( 30 ); String output = d.toString();
去另一个方向,parsing一个string。
Duration d = Duration.parse( "PT1H30M" );
在IdeOne.com中查看实时代码 。
看到我的类似的问题 类似的答案 。
关于java.time
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧的遗留date时间类,如java.util.Date
, Calendar
和SimpleDateFormat
。
Joda-Time项目现在处于维护模式 ,build议迁移到java.time类。
要了解更多信息,请参阅Oracle教程 。 并search堆栈溢出了很多例子和解释。 规范是JSR 310 。
从何处获取java.time类?
- Java SE 8和SE 9及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小function和修复。
- Java SE 6和SE 7
- 大部分的java.timefunction都被移植到了ThreeTen-Backport中的 Java 6&7中。
- Android的
- ThreeTenABP项目专门针对Android,采用了ThreeTen-Backport (上文提到)。
- 请参阅如何使用ThreeTenABP …。
ThreeTen-Extra项目将java.time扩展到其他类。 这个项目是未来可能增加java.time的一个试验场。 你可能会在这里find一些有用的类,比如Interval
, YearWeek
, YearQuarter
等等 。