2010-02-10 55 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