Java « запретить ввод символов в jtextfield
Есть ли стандартный способ настроить jtextfield на ввод по маске/шаблону?
1 ответов
Специального механизма, именно у JTextField нет, но решение есть.
javax.swing.JTextField наследует от javax.swing.text.JTextComponent механизм CaretListener:
Каждое изменение позиции знака вставки генерирует событие CaretEvent. Эти события можно прослушивать реализовав интерфейс CaretListener.
CaretListener определяет только один метод:
void caretUpdate(CaretEvent ce)
Соответственно, любую поверку можно организовать через этот метод. Остается только дописать буфферизацию строки, а доступ к полю у нас есть через set/getText.
Так что это делается вручную:
...
JTextField textField;
...
textField = new JTextField(255);
...
textField.addCaretListener( new CaretListener() {
public void caretUpdate (CaretEvent ce) {
...
String value = textFiled.getText;
<обработка>
textField.setText(<либо строка из буфера, либо та, которая есть>);
...
}
});
А если често, то нужно использовать JFormattedTextField)
Если же Вы все таки решитесь обратиться к JFormattedTextField, то можно использовать MaskFormatter:
...
MaskFormatter formatter = new MaskFormatter("###-####");
formatter.setPlaceholderCharacter('_');
...
JFormattedTextField textField = new JFormattedTextField(formatter);
...
Аргументом в конструкторе является маска. Вот параметры, которые могут быть определены в маске и что они означают:
# - любое правильное (разрешенное) число;
' - удаление символа;
? - любая буква;
A - любая буква или число ;
* - что-нибудь;
U - любая буква, но все строчные станут заглавными;
L - заглавные буквы делает строчными;
H - определяет шестнадцатиричные символы.
Пробовал сделать так, как описано в первом ответе. При этом возникла проблема. Если в реализации caretUpdate использовать textField.setText(), то возникает бесконечный цикл - метод .setText() вызывает событие caretUpdate же.
Мой вариант фильтрации вводимых символов:
public static String digitsOnlyFilter (String value) {
int len = value.length();
String result = "";
boolean oneget = false;
for(int i = 0; i < len; i++) {
char ch = value.charAt(i);
if(Character.isDigit(ch)) {
result += value.substring(i, i+1);
} else if ((ch == '.') && !oneget) {
oneget = true;
result += value.substring(i, i+1);
}
}
return result;
}
public static void addKeyFilter(final JTextField field) {
field.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {}
public void keyPressed(KeyEvent e) {}
public void keyReleased(KeyEvent e) {
field.setText(digitsOnlyFilter(field.getText()));
}
});
}
Этот метод не дает вводить в поле ничего, кроме цифр и точки.
Пример использования:
...
JTextField tfSquare = new JTextField();
addKeyFilter(tfSquare);
...
Запретить ввод символов можно и проще:
jTextField.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent e) {
char a = e.getKeyChar();
if (!Character.isDigit(a)
&& (a != '.')
&& (a != '\b')) {
e.consume();
}
}
});
Если по какой то причине Вас не устроил метод предложенный в первом ответе, можно самостоятельно реализовать логику маски. На пример, для реализации поля ввода ip адреса можно реализовать метод:
private boolean isCorrectKey(char key, int position) {
/* Если нажата кнопка backspace */
if (key == '\b') {
return true;
}
/* Если вводится цифра */
if (Character.isDigit(key)) {
return
(position >= 0 && position < 3)
|| (position >= 4 && position < 7)
|| (position >= 8 && position < 11)
|| (position >= 12 && position < 15);
}
/* Если вводится точка */
if (key == '.') {
return
(position == 3)
|| (position == 7)
|| (position == 11);
}
/* Все остальные случаи */
return false;
}
*Данный метод не предусматривает проверки на диапазон IP адреса тк приводится для наглядности.
jTextField.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent e) {
char key = e.getKeyChar();
int position = jTextField.getText().length();
if (!isCorrectKey(key, position)) {
e.consume();
}
}
});
Надо заметить, что от вставки неверного текста это не спасет. На мой взгляд, в любом случае, после потери фокуса полем ввода надо проверять его текст по маске.