TextInput
имеет TextFormatter
, который можно использовать для форматирования, преобразования и ограничения типов текста, который можно вводить.
TextFormatter
имеет фильтр, который можно использовать для отклонения ввода. Нам нужно установить это, чтобы отклонить все, что не является допустимым целым числом. Он также имеет конвертер, который нам нужно установить для преобразования строкового значения в целочисленное значение, которое мы можем связать позже.
Позволяет создать фильтр многократного использования:
public class IntegerFilter implements UnaryOperator<TextFormatter.Change> {
private final static Pattern DIGIT_PATTERN = Pattern.compile("\\d*");
@Override
public Change apply(TextFormatter.Change aT) {
return DIGIT_PATTERN.matcher(aT.getText()).matches() ? aT : null;
}
}
Фильтр может выполнять одно из трех действий: он может вернуть изменение без изменений, чтобы принять его таким, какой он есть, он может изменить изменение некоторым способом, который он сочтет нужным, или он может вернуть null
, чтобы полностью отклонить изменение.
Мы будем использовать стандарт IntegerStringConverter
в качестве конвертера.
Собрав все вместе, мы имеем:
TextField textField = ...;
TextFormatter<Integer> formatter = new TextFormatter<>(
new IntegerStringConverter(), // Standard converter form JavaFX
defaultValue,
new IntegerFilter());
formatter.valueProperty().bindBidirectional(myIntegerProperty);
textField.setTextFormatter(formatter);
Если вы не нуждаетесь в многоразовом фильтре, вы можете вместо этого сделать этот модный однострочный:
TextFormatter<Integer> formatter = new TextFormatter<>(
new IntegerStringConverter(),
defaultValue,
c -> Pattern.matches("\\d*", c.getText()) ? c : null );