Как я могу ограничить ввод данных пользователем только шестнадцатеричными значениями?
В десятичной системе счисления диапазон составляет от 0 до 16383, но я хотел бы позволить пользователю вводить шестнадцатеричное число в TextField. Следовательно, диапазон должен быть от 0x0000 до 0x3FFF. Я уже создал свой графический интерфейс через SceneBuilder, поэтому мне просто нужна функция для обработки ограничений и преобразования при вводе пользователем.
РЕДАКТИРОВАТЬ
Это моя версия:
startAddressField.textProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue.matches("^[0-9A-F]?")) {
startAddressField.setText(oldValue);
}
});
Подсказка: вам, вероятно, понадобится редактор по работе с клиентами на местах




Идея может заключаться в том, чтобы сначала преобразовать его в целочисленный формат. Ты можешь использовать:
int value = Integer.decode("your hex value here");
если строка не является правильным значением, она вызовет исключение числового формата, однако функция декодирования также будет работать для любого действительного целого числа (так что в этом случае будет работать и что-то с основанием 10).
Альтернатива, которую вы можете попробовать:
int value = Integer.parseInt("hex value",16)
Однако для этого метода вам нужно будет избавиться от заголовка «0x» в строке
Поскольку вы выполняете проверку, окружите ее блоком try catch, и все, что будет перехвачено, будет неправильно отформатированным шестнадцатеричным кодом.
Кроме того, если вам нужно проверить, находится ли значение от 0 до 16383, просто используйте значение, возвращаемое вышеуказанными методами.
лучший способ сделать это с помощью регулярных выражений:
yourTextField.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue,
String newValue) {
if (!newValue.matches("^[0-9A-F]+$")) {
yourTextField.setText(newValue.replaceAll("[^\\d]", ""));
}
}
});
Это то, что вы ищете?
Спасибо за ответ, я тоже сделал нечто подобное, вы можете увидеть это в редактировании. Однако я думал о том, как реализовать ограничение диапазона и преобразование Integer.
Вы не должны использовать шестнадцатеричные значения, а не только нецифровые значения (для них, кстати, можно использовать \D). В противном случае 3AC! приводит к 3, а не к 3AC.
нет, не слушайте и не возвращайтесь - вместо этого используйте TextFormatter, как объяснил @fabian в своем принятом (!) ответе
Используйте TextFormatter с UnaryOperator и StringConverter<Integer>, как показано ниже:
UnaryOperator<TextFormatter.Change> filter = change -> change.getControlNewText().matches("[0-3]?\\p{XDigit}{0,3}") ? change : null;
StringConverter<Integer> converter = new StringConverter<Integer>() {
@Override
public String toString(Integer object) {
return object == null ? "" : Integer.toHexString(object);
}
@Override
public Integer fromString(String string) {
return string == null || string.isEmpty() ? null : Integer.parseInt(string, 16);
}
};
TextFormatter<Integer> formatter = new TextFormatter<>(converter, null, filter);
textField.setTextFormatter(formatter);
Преобразованное значение доступно через свойство TextFormatter.value. Он обновляется только при нажатии Enter или при потере фокуса TextField.
Спасибо, я пробую ваше решение, и оно работает хорошо. однако я сталкиваюсь с ошибкой: как мне преодолеть недопустимый escape-символ в "[0-3]?\p{XDigit}{0,3}"? Пробую с двойной обратной косой чертой!
Что вы уже пробовали? Разместите свой код таким образом, чтобы мы могли помочь вам понять, в чем вы ошибаетесь. Вы можете установить TextFormatter в поле для отслеживания и ограничения ввода.