【发布时间】:2012-06-28 05:59:58
【问题描述】:
我希望用户输入时间,比如 12:00,但我需要弄清楚一些事情,我迷路了。
- 我可以将文本限制为 5 个字符吗?如何限制?
- 我可以在代码中嵌入冒号以使其不能被用户删除吗?
- 最后,我可以拿那个代码并验证它是否只是数字(当然忽略冒号)
【问题讨论】:
标签: java swing jtextfield colon jformattedtextfield
我希望用户输入时间,比如 12:00,但我需要弄清楚一些事情,我迷路了。
【问题讨论】:
标签: java swing jtextfield colon jformattedtextfield
一个老问题的迟到的答案;使用DocumentFilter 可以实现这三个req。
非生产质量代码可能是这样的
String TIME_PATTERN = "^\\d\\d:\\d\\d\\s[AP]M$";
final JTextField tf = new JTextField("00:00 AM", 8);
((AbstractDocument)tf.getDocument()).setDocumentFilter(new DocumentFilter() {
public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a) throws BadLocationException {
String text = fb.getDocument().getText(0, fb.getDocument().getLength());
text = text.substring(0, offs) + str + text.substring(offs + length);
if(text.matches(TIME_PATTERN)) {
super.replace(fb, offs, length, str, a);
return;
}
text = fb.getDocument().getText(0, fb.getDocument().getLength());
if(offs == 2 || offs == 5)
tf.setCaretPosition(++offs);
if(length == 0 && (offs == 0 ||offs == 1 ||offs == 3 ||offs == 4 ||offs == 6))
length = 1;
text = text.substring(0, offs) + str + text.substring(offs + length);
if(!text.matches(TIME_PATTERN))
return;
super.replace(fb, offs, length, str, a);
}
public void insertString(FilterBypass fb, int offs, String str, AttributeSet a) throws BadLocationException { }
public void remove(FilterBypass fb, int offset, int length) throws BadLocationException { }
});
【讨论】:
或者只是放弃您的文本字段并选择两个JSpinner 实例,由包含冒号的JLabel 分隔(或两个JTextField 实例)。
不完全确定此解决方案对用户来说是否更直观,但我认为如此。
【讨论】:
答案是使用JFormattedTextField 和MaskFormatter。
例如:
String mask = "##:##";
MaskFormatter timeFormatter = new MaskFormatter(mask);
JFormattedTextField formattedField = new JFormattedTextField(timeFormatter);
Java 编译器会要求您在创建 MaskFormatter 时捕获或抛出 ParseException,因此请务必这样做。
【讨论】: