Как сделать поиск элементов в ListSelectionView (JavaFX)?
Мне нужно реализовать поиск в компоненте ListSelectionView из ControlsFX. И для списка "available", и для списка "selected", но основная проблема следующая - при сбросе текста в TextField, список возвращается к первоначальному виду.
Пробовал найти в документации, пробовал нейронку, вообщем искал везде, но нашёл лишь вариант с FilteredList.
Мой код:
public class selectionViewController implements Initializable {
@FXML
private TextField listSearchAvailable;
@FXML
private TextField listSearchSelected;
@FXML
private ListSelectionView<RetailStore> listSelectionView;
private ObservableList<RetailStore> availableRetailStores;
private FilteredList<RetailStore> filteredList;
@Override
public void initialize(URL location, ResourceBundle resources) {
availableRetailStores = FXCollections.observableArrayList();
loadData();
searchHandler();
}
private void loadData() {
// ЗАГРУЖАЮ ДАННЫЕ
// И ИНИЦИАЛИЗИРУЮ ВСЕ СПИСКИ
List<RetailStore> retailStores = this.skladRequest.getRetailStoresFromSklad(node);
ObservableList<RetailStore> observableRetailStores = FXCollections.observableArrayList();
observableRetailStores.addAll(retailStores);
listSelectionView.setSourceItems(observableRetailStores);
availableRetailStores.addAll(listSelectionView.getSourceItems());
filteredList = new FilteredList<>(availableRetailStores, p -> true);
listSelectionView.setSourceItems(filteredList);
}
// САМ МЕТОД ПОИСКА
private void searchHandler() {
listSearchAvailable.textProperty().addListener((obs, oldVal, newVal) -> {
String lower = (newVal == null) ? "" : newVal.toLowerCase();
filteredList.setPredicate(store -> store.getName().toLowerCase().contains(lower));
});
}
При таком варианте список возвращается к исходному виду каждый раз. Вероятно нужно добавить ещё какой-то список, через который обрабатывать это всё, но что-то не получается придумать как.
Ответы (1 шт):
Ввёл 2 отдельные переменные для выбранных и оставшихся списков
private final ObservableList<RetailStore> availableRetailStores = FXCollections.observableArrayList();
private final ObservableList<RetailStore> selectedRetailStores = FXCollections.observableArrayList();
Отдельно через них фильтрую и обновляю списки
private void filterAvailableList(String filter) {
availableRetailStores.clear();
String lowerFilter = filter == null ? "" : filter.toLowerCase();
List<RetailStore> filtered = retailStores.stream()
.filter(store -> store.getName().toLowerCase().contains(lowerFilter))
.filter(store -> !selectedRetailStores.contains(store))
.collect(Collectors.toList());
availableRetailStores.addAll(filtered);
}
Затем использую в слушателе на TextField
private void searchAvailable() {
listSearchAvailable.textProperty().addListener((obs, oldVal, newVal) -> {
filterAvailableList(newVal);
});
}
В init обновляю списки, которые выводятся и вызываю методы фильтрации
@Override
public void initialize(URL location, ResourceBundle resources) {
listSelectionView.setSourceItems(availableRetailStores);
listSelectionView.setTargetItems(selectedRetailStores);
searchAvailable();
searchSelected();
}