6

我正在尝试创建一个只接受 24 小时时间的 JFormattedTextField。

我非常接近解决方案,但有一种情况下以下代码示例不起作用。

如果您输入时间“222”并从字段中更改焦点,则时间将更正为“2202”。我希望它只接受完整的 4 位数 24 小时时间。这段代码几乎在所有情况下都能按我的意愿工作,除了我刚才提到的那个。有什么建议么?

    public static void main(String[] args) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("HHmm");
        dateFormat.setLenient(false);

        DateFormatter dateFormatter =  new DateFormatter(dateFormat);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JFormattedTextField textField = new JFormattedTextField(dateFormatter);
        frame.add(textField, BorderLayout.NORTH);

        frame.add(new JTextField("This is here so you can change focus."), BorderLayout.SOUTH);
        frame.setSize(250, 100);
        frame.setVisible(true);
    }
4

2 回答 2

5

正如其他人所提到的,您最好的选择可能是验证输入字符串的长度。我首选的方法是子类化SimpleDateFormat以将所有解析逻辑保存在一个地方:

public class LengthCheckingDateFormat extends SimpleDateFormat {

  public LengthCheckingDateFormat(String pattern) { super(pattern); }

  @Override
  public Date parse(String s, ParsePosition p) {
    if (s == null || (s.length() - p.getIndex()) < toPattern().length()) {
      p.setErrorIndex(p.getIndex());
      return null;
    }
    return super.parse(s, p);
  }
}
于 2012-06-15T13:37:55.793 回答
2

我想知道,因为它DateFormatter似乎“几乎”完成了所有的把戏。

因此,为什么不覆盖其进行最终验证和格式化的方法一,以将所有输入String的太短的 s 视为 empty String

        DateFormatter dateFormatter = new DateFormatter(dateFormat) {
            @Override
            public Object stringToValue(String text) throws ParseException {
                if(!getFormattedTextField().hasFocus())
                    if (text.length() != 4) {
                        return null;
                    }
                return super.stringToValue(text);
            }            
        };

编辑:

正如@nIcE cOw 所建议的,最简单的方法是在失去焦点时提供它:

    final JFormattedTextField textField = new JFormattedTextField(dateFormatter);
    textField.addFocusListener(new FocusAdapter() {
        @Override
        public void focusLost(FocusEvent e) {
            super.focusLost(e);
            if(textField.getText().length() != 4)
                textField.setText("");
        }
    });
于 2012-06-15T13:26:50.130 回答