password - maskformatter en java
JFormattedTextField: valor de duraciĆ³n del tiempo de entrada (5)
Quiero usar un JFormattedTextField
para permitir al usuario ingresar valores de duración de tiempo en un formulario. Los valores válidos de la muestra son:
2h 30m
72h 15m
6h
0h
Sin embargo, estoy teniendo un éxito limitado con esto. ¿Puede alguien sugerir por favor cómo se puede lograr esto? Estoy bien si este resultado se puede lograr usando un JTextField
también.
¡Gracias!
Si vale algo, aquí está mi intento actual:
mFormattedText.setFormatterFactory(
new DefaultFormatterFactory(
new DateFormatter(
new SimpleDateFormat("H mm"))));
Este sorta funciona excepto que:
-
No puedo hacer que*h
ym
aparezcan como texto sin formato (intenté escapar) - El número de horas tiene un máximo
*: Ver la respuesta de @nanda
tl; dr
Duration.parse( "PT2H30M" )
ISO 8601
Si está dispuesto a redefinir sus formatos de entrada deseados, le sugiero que utilice los formatos ya existentes definidos por la norma ISO 8601 .
El patrón PnYnMnDTnHnMnS
usa una P
para marcar el comienzo, una T
para separar cualquier porción de años-meses-días de cualquier porción de horas-minutos-segundos.
Una hora y media es PT1H30M
, por ejemplo.
java.time
Las clases java.time usan los formatos ISO 8601 de forma predeterminada al analizar / generar cadenas. Esto incluye las clases de Period
y Duration
para representar tramos de tiempo no asociados a la línea de tiempo.
Duration d = Duration.ofHours( 1 ).plusMinutes( 30 );
String output = d.toString();
Yendo en la otra dirección, analizando una cadena.
Duration d = Duration.parse( "PT1H30M" );
Vea el código en vivo en IdeOne.com .
Ver mi respuesta similar a una pregunta similar .
Acerca de java.time
El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases heredadas de fecha y hora como java.util.Date
, Calendar
y SimpleDateFormat
.
El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .
Para obtener más información, consulte el Tutorial de Oracle . Y busque para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
¿Dónde obtener las clases de java.time?
- Java SE 8 y SE 9 y posteriores
- Incorporado.
- Parte de la API Java estándar con una implementación integrada.
- Java 9 agrega algunas características y correcciones menores.
- Java SE 6 y SE 7
- Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
- Androide
- El proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente) específicamente para Android.
- Consulte Cómo utilizar ThreeTenABP ....
El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval
, YearWeek
, YearQuarter
y más .
¿Has probado H''h'' mm''m''
?
Aquí hay un ejemplo del uso de InputVerifier
para acomodar múltiples formatos de entrada.
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);
}
}
El código:
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);
}
hmm, lo que creo es que puedes lograr el mismo objetivo creando tres JTextField diferentes para los tres componentes de tiempo, uno para HORA, MINUTO y Segundo (si está incluido) para obtener tu opinión ... solo un pensamiento, podrías concatenarlos si es necesario ... solo un pensamiento ...