I want to use a JFormattedTextField
to allow the user to input time duration values into a form. Sample valid values are:
2h 30m
72h 15m
6h
0h
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 JTextField
as well.
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:
h
and
m
to appear as plain text (I tried escaping)
*: See @nanda's answer
Here's an example of using InputVerifier
to accommodate multiple input formats.
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'
吗?
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);
}
嗯,我认为你可以达到同样的目标,为所有三个时间组件创建三个不同的JTextField,一个用于HOUR,MINUTE和Second(如果它包括在内)来获取你的输入...只是一个想法,如果你有必要,你可以将它们连接起来...只是一个想法......
Duration.parse( "PT2H30M" )
If you are willing to redefine your desired input formats, I suggest using the already-existing formats defined by the ISO 8601 standard.
The pattern PnYnMnDTnHnMnS
uses a P
to mark the beginning, a T
to separate any years-months-days portion from any hours-minutes-seconds portion.
An hour-and-a-half is PT1H30M
, for example.
The java.time classes use the ISO 8601 formats by default when parsing/generating strings. This includes the Period
and Duration
classes for representing spans of time not attached to the timeline.
Duration d = Duration.ofHours( 1 ).plusMinutes( 30 );
String output = d.toString();
Going the other direction, parsing a string.
Duration d = Duration.parse( "PT1H30M" );
See live code in IdeOne.com .
See my similar Answer to a similar Question .
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode , advises migration to the java.time classes.
To learn more, see the Oracle Tutorial . And search Stack Overflow for many examples and explanations. Specification is JSR 310 .
Where to obtain the java.time classes?
The ThreeTen-Extra project 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 .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.