我正在尝试创建一个只接受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);
}
答案 0 :(得分: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);
}
}
答案 1 :(得分:2)
我不知道,因为DateFormatter
似乎'几乎'所有的伎俩。
因此,为什么不覆盖执行最终验证和格式化的方法,以便将所有输入的String
视为空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("");
}
});