Событие нежелательного изменения JavaFX при удалении элементов из Combobox

0
задан Peng 7 March 2019 в 19:32
поделиться

1 ответ

Из вашего кода похоже, что у вас есть пункт, выполняющий функцию текста подсказки ComboBox. При выборе нового элемента вы хотите удалить элемент текста подсказки, оставив выбранным новый элемент 1 . Для этого вам нужно всего лишь удалить текст подсказки; нет необходимости пытаться вручную вызвать select для модели выбора - новый пункт уже выбран к этому моменту.

comboBox.getSelectionModel().selectedIndexProperty((obs, oldVal, newVal) -> {
    int oldIndex = oldVal.intValue();
    var items = comboBox.getItems();
    if (oldIndex >= 0 && oldIndex < items.size() && items.get(oldIndex).equalsIgnoreCase("prompt_txt")) {
        items.remove(oldIndex);
    }
});

Здесь я использую старый индекс, предполагая, что у вас есть элемент "prompt_txt" в качестве первоначально выбранного элемента.

Этот код все равно приведет к двум изменениям, поскольку удаление элемента "prompt_txt" изменит индексы всех оставшихся элементов. Это не имеет значения. Слушатель не будет ничего делать для любых последующих уведомлений, и вновь выбранный элемент остается прежним. Поскольку единственной задачей слушателя является удаление "prompt_txt", тем не менее, может быть целесообразно удалить слушателя после первого уведомления. Один из способов сделать это заключается в следующем:

comboBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<>() {

    @Override
    public void changed(ObservableValue<? extends Number> obs, Number oldVal, Number newVal) {
        int oldIndex = oldVal.intValue();
        var items = comboBox.getItems();
        if (oldIndex >= 0 && oldIndex < items.size() && items.get(oldIndex).equalsIgnoreCase("prompt_txt")) {
            obs.removeListener(this); // Needed anonymous class to reference "this"
            items.remove(oldIndex);
        }
    }

});

В этом случае, поскольку я удаляю слушателя перед вызовом remove(oldIndex), слушатель уведомляется только один раз.

Однако

Все это говорит о том, что нет необходимости добавлять специальный элемент для представления текста подсказки. Класс ComboBoxBase, от которого наследуется ComboBox, обладает свойством promptText . Вот документация:

Текст подсказки ComboBox для отображения или ноль, если текст подсказки не отображается. Текст подсказки отображается не во всех случаях, он зависит от подклассов ComboBoxBase, чтобы уточнить, когда будет отображаться подсказка. Например, в большинстве случаев текст подсказки никогда не будет отображаться, если поле со списком недоступно для редактирования (то есть текст подсказки отображается только тогда, когда пользовательский ввод разрешен посредством ввода текста).

Некоторое быстрое тестирование показывает, что ComboBox отображает текст подсказки, даже если нет editable (при условии, что элементы не выбраны).


1. У вас есть // some actions... между remove("prompt_text") и select(newvalue.intValue() - 1). То, что эти действия могут полностью аннулировать мой ответ.

0
ответ дан Slaw 7 March 2019 в 19:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: