2010-02-10 56 views
3

我想使用JFormattedTextField来允许用户输入时间持续时间值到表单中。样本有效值为:JFormattedTextField:输入持续时间值

2h 30m
72h 15m
6h
0h

但是我有这个有限的成功。有人可以建议如何实现?如果使用JTextField也可以实现此结果,那么我很好。

谢谢!


如果这是值得任何东西,这是我当前的尝试:

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

这八九不离十工作,除了:

  • 我不能让 hm显示为纯文本(我试过转义) *
  • 小时数最大为

*:请@南大的答案

回答

1

代码:

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

嗯,我认为是可以实现由同一个目标,为小时,分钟和秒为所有人创造三个时间分量的三个不同的JTextField,一个(如果它包括在内),让您的输入...只是一个想法,你可以只将它们连接起来,如果你有必要...只是一个想法...

+0

@ultrajohn,感谢您的意见,但是它的部分要求必须在一个字段中,而格式正如我在问题中所描述的那样。 – bguiz 2010-02-10 06:07:33

1

你试过H'h' mm'm'

+0

+1也可以使用'InputVerifier'。 – trashgod 2010-02-10 16:08:26

+0

@nanda,感谢您指出如何转义角色(工作),但什么都行不通,我希望用户输入'6h 42m',并导致'Unparseable date:“6h 42m”',所以我我仍然陷入困境。这只有当用户输入像'6:42:00 AM'这样的东西时才起作用,由于意图是输入持续时间,这对我不起作用。 – bguiz 2010-02-10 22:31:41

+0

@trashgod,你可以在这种情况下建议如何使用'InputVerifier'吗? – bguiz 2010-02-10 22:32:19

4

下面是使用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); 
    } 
} 
0

TL;博士

Duration.parse("PT2H30M") 

ISO 8601

如果你愿意重新定义所需的输入格式,我建议使用already-现有格式由ISO 8601标准定义。

模式PnYnMnDTnHnMnS使用P来标记开头,T将任何年 - 月 - 日部分与任何小时 - 分钟 - 秒部分分开。例如,一个半小时为PT1H30M

java.time

的java.time类解析/生成字符串时默认使用ISO 8601种格式。这包括用于表示时间跨度未附加到时间线的PeriodDuration类。

Duration d = Duration.ofHours(1).plusMinutes(30); 
String output = d.toString(); 

去另一个方向,解析一个字符串。

Duration d = Duration.parse("PT1H30M"); 

请参阅live code in IdeOne.com

查看my similar Answersimilar Question


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了日期时间类legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time项目现在位于maintenance mode,建议迁移到java.time类。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310

从何处获取java.time类?

ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval,YearWeek,YearQuartermore