我试图通过正则表达式避免在JTextField中输入无效的数字,但是当我输入有效的数字时,它也会去消耗方法来消耗。请指导我。
private void txtphoneKeyTyped(java.awt.event.KeyEvent evt) {
char c = evt.getKeyChar();
String regex = "^(\\+93|0)?[7][0-9]{8}$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(String.valueOf(c));
if(matcher.matches() == false){
evt.consume();
}
}
最佳答案
您不应该为此使用KeyListener。
一方面,您试图将单个键入的字符与整个电话号码模式进行匹配。 evt.getKeyChar()
返回单个字符的事实应告诉您,它不可能与整个电话号码匹配。
正确的方法是使用JTextField的子类JFormattedTextField,而不是普通的JTextField。
String regex = "^(\\+93|0)?7[0-9]{8}$";
Pattern pattern = Pattern.compile(regex);
JFormattedTextField.AbstractFormatter formatter =
new JFormattedTextField.AbstractFormatter() {
private static final long serialVersionUID = 1;
@Override
public Object stringToValue(String text)
throws ParseException {
if (text != null && !pattern.matcher(text).matches()) {
throw new ParseException(text, 0);
}
return text;
}
@Override
public String valueToString(Object value) {
return Objects.toString(value, null);
}
};
JTextField txtphone = new JFormattedTextField(formatter);
您实际上并不需要限制键入的键;如果用户键入无效字符,则该值将被拒绝,并且该字段将恢复为最后输入的正确值。但是,如果您坚持限制每个键入的字符,则可以使用DocumentFilter:
Pattern allowedCharactersPattern = Pattern.compile("[0-9+]*");
DocumentFilter filter = new DocumentFilter() {
@Override
public void insertString(FilterBypass bypass,
int position,
String newText,
AttributeSet attr)
throws BadLocationException {
if (allowedCharactersPattern.matcher(newText).matches()) {
super.insertString(bypass, position, newText, attr);
}
}
@Override
public void replace(FilterBypass bypass,
int position,
int length,
String newText,
AttributeSet attr)
throws BadLocationException {
if (allowedCharactersPattern.matcher(newText).matches()) {
super.replace(bypass, position, length, newText, attr);
}
}
};
String regex = "^(\\+93|0)?7[0-9]{8}$";
Pattern pattern = Pattern.compile(regex);
JFormattedTextField.AbstractFormatter formatter =
new JFormattedTextField.AbstractFormatter() {
private static final long serialVersionUID = 1;
@Override
protected DocumentFilter getDocumentFilter() {
return filter;
}
@Override
public Object stringToValue(String text)
throws ParseException {
if (text != null && !pattern.matcher(text).matches()) {
throw new ParseException(text, 0);
}
return text;
}
@Override
public String valueToString(Object value) {
return Objects.toString(value, null);
}
};
JTextField txtphone = new JFormattedTextField(formatter);
您可能想知道为什么allowedCharactersPattern是
"[0-9+]*"
,而不是完整的电话号码模式。这是因为具有带有可移动光标的文本字段的原因之一是,用户一次只能输入一点信息,可能会乱序输入。例如,用户可以键入一些数字,然后使用箭头键将光标移到开头并键入“ +937”。最好在用户完成编辑后才实施模式。 stringToValue
方法仍然强制执行整体模式。关于java - 带JTextField事件的正则表达式不起作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55672184/