Edit:
Я пытаюсь создать Combobox с функцией поиска, и вот что я придумал:
public class SearchableComboBox<T> extends ComboBox<T> {
private ObservableList<T> filteredItems;
private ObservableList<T> originalItems;
private T selectedItem;
private StringProperty filter = new SimpleStringProperty("");
public SearchableComboBox () {
this.setTooltip(new Tooltip());
this.setOnKeyPressed(this::handleOnKeyPressed);
this.getTooltip().textProperty().bind(filter);
this.showingProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
// If user "closes" the ComboBox dropdown list: reset filter, reset list to the full original list, hide tooltip
if (newValue == false) {
filter.setValue("");;
setItems(originalItems);
getTooltip().hide();
// If user opens the combobox dropdown list: get a copy of the items and show tooltip
} else {
originalItems = getItems();
Window stage = getScene().getWindow();
getTooltip().show(stage);
}
}
});
}
public void handleOnKeyPressed(KeyEvent e) {
//Only execute if the dropdown list of the combobox is opened
if (this.showingProperty().getValue() == true) {
// Get key and add it to the filter string
String c = e.getText();
filter.setValue(filter.getValue() + c);
//Filter out objects that dont contain the filter
this.filteredItems = this.originalItems.filtered(a -> this.getConverter().toString(a).toLowerCase().contains(filter.getValue().toLowerCase()));
//Set the items of the combox to the filtered list
this.setItems(filteredItems);
}
}
Идея проста: пока открыт раскрывающийся список Combobox, я слушаю нажатия клавиш и добавляю символы в фильтр. С помощью этих фильтров список элементов Combobox фильтруется в список, содержащий только те элементы, которые содержат строку фильтра. Затем я использую setItems, чтобы установить список элементов в мой отфильтрованный список. Моя проблема в том, что valueProperty Combobox изменяется, но я хочу, чтобы выбранный объект оставался прежним, пока пользователь не выберет другой из выпадающего списка. Я добавил ChangeListener в ValueProperty:
public void changed(ObservableValue<? extends PersonalModel> observable, PersonalModel oldValue,
PersonalModel newValue) {
System.out.println("Value changed");
if (newValue == null) {
System.out.println(newValue);
} else {
System.out.println(personalauswahl.getConverter().toString(newValue));
labelArbeitszeitAnzeige.setText(String.valueOf(newValue.getArbeitszeit()));
}
}
});
Когда значение изменяется, консоль выглядит следующим образом:
Значение изменено
Андерсен, Вибке (Строковое представление объекта)
или как это:
Значение изменено
ноль (объект ноль)
Есть в основном 3 случая, которые происходят. Во-первых, я открываю выпадающий список, не выбираю элемент и не набираю фильтр. Затем я выбираю предмет, и мои отпечатки покажут мне это:
Значение изменено
Андерсен, Вибке
Значение изменено
нуль
Значение изменено
Андерсен, Вибке
Во втором случае я открываю выпадающий список и выбираю предмет. Теперь я перехожу к типу фильтра, и выбранный элемент содержит фильтр. Мои отпечатки покажут мне это:
Значение изменено
1037 * пустой *
Значение изменено
Андерсен, Вибке
Каждый раз, когда я нажимаю клавишу и снова, когда выбираю Андерсена, Вибке снова / закрывает выпадающий список.
Третий случай - выбор элемента, а затем приступить к вводу фильтра, который не содержит выбранный элемент. Как только выбранный Item больше не содержит фильтра, значение valueProperty изменяется на null. Если я выберу новый предмет, я получу это:
Значение изменено
Будзишевски, Карин
Значение изменено
1053 * пустой *
Значение изменено
Будзишевски, Карин
Я хочу, чтобы ValueProperty не менялся, пока пользователь не выберет новый элемент из выпадающего списка. Также мне бы очень хотелось узнать, почему именно значение свойства все время меняется для меня. Особенно потому, что я не думаю, что есть принципиальная разница между моим решением и тем, которое предоставил Зефир. Мы оба фильтруем исходный список с помощью строки фильтра и затем используем setItems (), чтобы установить список Combobox на вновь отфильтрованный. И, как упоминалось в комментарии ниже, я даже не могу использовать его решение », потому что я не могу заставить setEditable из Combobox работать:
Когда я пытаюсь использовать personalauswahl.setEditable (true); Вызывается: java.lang.NullPointerException в de.statistik_nord.klr.controller.EingabeController $ 1.toString (EingabeController.java:93) в de.statistik_nord.klr.controller.EingabeController который указывает на эту строку кода: return object.getName () + "," + object.getVorname ();