JFormattedTextField: значение продолжительности ввода времени
Я хочу использовать JFormattedTextField
чтобы позволить пользователю вводить значения длительности времени в форму. Примерные допустимые значения:
2h 30m
72h 15m
6h
0h
Однако у меня ограниченный успех в этом. Кто-нибудь может подсказать, как это можно сделать? Я в порядке, если этот результат может быть достигнут с помощью JTextField
также.
Спасибо!
Если это чего-то стоит, вот моя нынешняя попытка:
mFormattedText.setFormatterFactory(
new DefaultFormatterFactory(
new DateFormatter(
new SimpleDateFormat("H mm"))));
Эта Сорта работает за исключением того, что:
-
Я не могу получитьh
а такжеm
отображаться в виде простого текста (я пытался убежать)* - Количество часов имеет максимум
*: См. Ответ @nanda
5 ответов
Код:
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
для размещения нескольких форматов ввода.
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);
}
}
Хм, я думаю, что вы можете достичь одной и той же цели, создав три разных JTextField для всех трех временных компонентов: один для ЧАСОВ, МИНУТ и Второй (если он включен), чтобы получить ваш вклад... просто мысль, Вы можете просто объединить их, если вам это необходимо... просто мысль...
ТЛ; др
Duration.parse( "PT2H30M" )
ISO 8601
Если вы хотите переопределить желаемые форматы ввода, я предлагаю использовать уже существующие форматы, определенные стандартом ISO 8601.
Шаблон PnYnMnDTnHnMnS
использует P
чтобы отметить начало, T
отделить любую часть лет-месяцев-дней от любой части часов-минут-секунд.
Полтора часа PT1H30M
, например.
java.time
Классы java.time по умолчанию используют форматы ISO 8601 при разборе / генерации строк. Это включает в себя Period
а также Duration
классы для представления отрезков времени, не привязанных к временной шкале.
Duration d = Duration.ofHours( 1 ).plusMinutes( 30 );
String output = d.toString();
Идем в другом направлении, разбираем строку.
Duration d = Duration.parse( "PT1H30M" );
Смотрите живой код в IdeOne.com.
Смотрите мой аналогичный ответ на похожий вопрос.
О java.time
Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые классы даты и времени, такие как java.util.Date
, Calendar
& SimpleDateFormat
,
Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.
Чтобы узнать больше, смотрите Oracle Tutorial. И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310.
Где взять классы java.time?
- Java SE 8 и SE 9 и позже
- Встроенный.
- Часть стандартного Java API со встроенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и SE 7
- Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
- Android
- Проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше) специально для Android.
- Смотрите Как использовать ThreeTenABP….
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь, такие как Interval
, YearWeek
, YearQuarter
и многое другое.