У меня есть программа, использующая javafx и Springboot. У меня есть таблица с двумя столбцами: столбец кода и столбец описания. Конечный пользователь может вводить текст в текстовое поле поиска, а столбцы фильтруются в зависимости от вводимого текста.
Раньше мне удавалось использовать функцию FilterList для фильтрации, однако после реализации Springboot мне не удалось заставить ее работать должным образом.
КодДиагностики.java
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
codeCol.setCellValueFactory((new PropertyValueFactory<>("Code")));
descripCol.setCellValueFactory((new PropertyValueFactory<>("Description")));
newDiagCodeTable.getColumns().setAll(codeCol, descripCol);
newDiagCodeTable.setItems(FXCollections.observableArrayList(diagnosisService.findAll()));
sortData();
}
@FXML
public void sortData(){
FilteredList<IDiagnosisModel> filteredData = new FilteredList<>(listView, b -> true);
searchCodes.textProperty().addListener((obs, oldValue, newValue) -> {
filteredData.setPredicate(diagnosisCode -> {
if (newValue == null || newValue.isEmpty()) {
return true;
}
String lowerCaseFilter = newValue.toLowerCase();
if (diagnosisCode.getDiagnosisDescription().toLowerCase().contains(lowerCaseFilter)) {
return true;
} else if (diagnosisCode.getDiagnosisCode().toLowerCase().contains(lowerCaseFilter)) {
return true;
} else return false;
});
});
SortedList<IDiagnosisModel> sortedData = new SortedList<>(filteredData);
sortedData.comparatorProperty().bind(newDiagCodeTable.comparatorProperty());
newDiagCodeTable.setItems(sortedData);
}
Я попытался использовать findByCode (строковый код). Например, я настроил событие setOnKeyPressed, которое получало бы текст того, что было введено, и использовало функцию findByCode() для получения строки того, что было напечатано. Это не сработало.
Есть ли какой-то конкретный метод Springboot, который мне не хватает?
КодДиагностики.java
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
sortData();
codeCol.setCellValueFactory((new PropertyValueFactory<>("Code")));
descripCol.setCellValueFactory((new PropertyValueFactory<>("Description")));
newDiagCodeTable.getColumns().setAll(codeCol, descripCol);
newDiagCodeTable.setItems(FXCollections.observableArrayList(diagnosisService.findAll()));
this.searchCodes.setOnKeyPressed(keyEvent -> {
String name = this.searchCodes.getText().trim();
diagnosisService.findByCode(name);
});
}
Если у вас по-прежнему возникают проблемы, вы можете проверить это, предоставив жестко запрограммированную версию DiagnosticService. Затем вы можете предоставить минимально воспроизводимый пример в вопросе (для которого вообще не понадобится SpringBoot), который воспроизводит проблему путем копирования и вставки без изменений или дополнений ->, что позволит вам получить некоторую помощь в отладке, если вам нужно. это.
Простой вызов diagnosisService.findByCode(...) ничего не даст, если вы не сделаете что-нибудь с возвращаемым списком. Вам нужно решить, будете ли вы фильтровать таблицу на стороне клиента (с помощью кода JavaFX) или на стороне базы данных (с использованием методов репозитория).
Не по теме: не используйте PropertyValueFactory. См. stackoverflow.com/questions/72437983/….
Не по теме: не используйте обработчики событий низкого уровня (например, onKeyPressed) с элементами управления высокого уровня (например, TextField). Вместо этого зарегистрируйте слушателя с помощью textProperty().
Не по теме: является ли sortData() методом обработчика событий (зарегистрированным с помощью элемента управления в файле FXML)? Если это так, вам не следует добавлять прослушиватели в textProperty(), потому что в конечном итоге у вас будет несколько прослушивателей, выполняющих одну и ту же функциональность. (А если нет, то, очевидно, это не должно быть аннотировано @FXML.)
@James_D - нет, это не метод обработчика событий. Вся логика фильтра находится внутри метода инициализатора. Похоже, я пытаюсь фильтровать данные, используя ОБА код javafx и методы репозитория.
Если это не метод обработчика событий, его не следует аннотировать @FXML.
Чего вы на самом деле пытаетесь достичь с помощью обработчика ключевых событий searchCodes? Что должен делать этот код?
Это правда! Я даже не заметил, что поставил @FXML в качестве аннотации к методу. Я вообще-то только что это понял. Сейчас происходит следующее: когда пользователь начинает вводить слово, таблица внизу фильтрует и сортирует код для выбора. Таким образом, им не придется прокручивать весь список вниз. Я обновлю основной вопрос решением. Спасибо за помощь!
Это была логическая ошибка.
Ниже приведено решение:
codeCol.setCellValueFactory((new PropertyValueFactory<>("Code")));
descripCol.setCellValueFactory((new PropertyValueFactory<>("Description")));
newDiagCodeTable.getColumns().setAll(codeCol, descripCol);
listView.addAll(diagnosisService.findAll());
newDiagCodeTable.setItems(listView);
FilteredList<IDiagnosisModel> filteredData = new FilteredList<>(listView, b -> true);
searchCodes.textProperty().addListener((obs, oldValue, newValue) -> {
filteredData.setPredicate(diagnosisCode -> {
if (newValue == null || newValue.isEmpty()) {
return true;
}
String lowerCaseFilter = newValue.toLowerCase();
if (diagnosisCode.getDiagnosisDescription().toLowerCase().contains(lowerCaseFilter)) {
return true;
} else if (diagnosisCode.getDiagnosisCode().toLowerCase().contains(lowerCaseFilter)) {
return true;
} else return false;
});
});
SortedList<IDiagnosisModel> sortedData = new SortedList<>(filteredData);
sortedData.comparatorProperty().bind(newDiagCodeTable.comparatorProperty());
newDiagCodeTable.setItems(sortedData);
Я создал список для хранения кодов, найденных в функции findAll(), затем создал фильтр, сортировку и добавил его в таблицу.
В
sortData()у вас естьnewDiagCodeTable.setItems(sortedData);, затем в вашем обновлении DiagnosisCode.initialize у вас естьnewDiagCodeTable.setItems(FXCollections.observableArrayList(diagnosisService.findAll()));-> который заменит отсортированный список отфильтрованных элементов новым списком со всеми элементами -> ваша сортировка и фильтрация никогда не будут работать. Могут быть и другие проблемы, которые я не проверял, но это похоже на простую логическую ошибку, а не на какую-то фундаментальную проблему с Springboot или вашей реализацией сортировки и фильтрации JavaFX, особенно если она работала до того, как вы внесли изменения.