Ограничение ввода TextField шестнадцатеричными значениями в Java FX

Как я могу ограничить ввод данных пользователем только шестнадцатеричными значениями? В десятичной системе счисления диапазон составляет от 0 до 16383, но я хотел бы позволить пользователю вводить шестнадцатеричное число в TextField. Следовательно, диапазон должен быть от 0x0000 до 0x3FFF. Я уже создал свой графический интерфейс через SceneBuilder, поэтому мне просто нужна функция для обработки ограничений и преобразования при вводе пользователем.

РЕДАКТИРОВАТЬ

Это моя версия:

startAddressField.textProperty().addListener((observable, oldValue, newValue) -> {
        if (!newValue.matches("^[0-9A-F]?")) {
            startAddressField.setText(oldValue);
        }
    });

Что вы уже пробовали? Разместите свой код таким образом, чтобы мы могли помочь вам понять, в чем вы ошибаетесь. Вы можете установить TextFormatter в поле для отслеживания и ограничения ввода.

purring pigeon 05.07.2018 15:45

Подсказка: вам, вероятно, понадобится редактор по работе с клиентами на местах

jr593 05.07.2018 16:12
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
2
1 057
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Идея может заключаться в том, чтобы сначала преобразовать его в целочисленный формат. Ты можешь использовать:

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.

GYBE 05.07.2018 16:21

Вы не должны использовать шестнадцатеричные значения, а не только нецифровые значения (для них, кстати, можно использовать \D). В противном случае 3AC! приводит к 3, а не к 3AC.

fabian 05.07.2018 16:48

нет, не слушайте и не возвращайтесь - вместо этого используйте TextFormatter, как объяснил @fabian в своем принятом (!) ответе

kleopatra 10.01.2019 13:56
Ответ принят как подходящий

Используйте 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}"? Пробую с двойной обратной косой чертой!

GYBE 08.07.2018 20:08

Другие вопросы по теме