JFormattedTextField: valor de duración del tiempo de entrada

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 bash actual:

  mFormattedText.setFormatterFactory( new DefaultFormatterFactory( new DateFormatter( new SimpleDateFormat("H mm")))); 

Este sorta funciona excepto que:

  • No puedo hacer que h y m aparezcan como texto sin formato (intenté escapar) *
  • El número de horas tiene un máximo

*: Ver la respuesta de @nanda

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); } 

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 validForms = new ArrayList(); 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); } } 

¿Has probado H'h' mm'm' ?

hmm, lo que creo es que puedes lograr el mismo objective al crear 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 …

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 Stack Overflow 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 .

    Intereting Posts