Фильтрация представления таблицы

У меня есть программа, использующая 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);
        });


    }

В sortData() у вас есть newDiagCodeTable.setItems(sortedData);, затем в вашем обновлении DiagnosisCode.initialize у вас есть newDiagCodeTable.setItems(FXCollections.observableArrayList(‌​diagnosisService.fin‌​dAll())); -> который заменит отсортированный список отфильтрованных элементов новым списком со всеми элементами -> ваша сортировка и фильтрация никогда не будут работать. Могут быть и другие проблемы, которые я не проверял, но это похоже на простую логическую ошибку, а не на какую-то фундаментальную проблему с Springboot или вашей реализацией сортировки и фильтрации JavaFX, особенно если она работала до того, как вы внесли изменения.

jewelsea 19.08.2024 20:52

Если у вас по-прежнему возникают проблемы, вы можете проверить это, предоставив жестко запрограммированную версию DiagnosticService. Затем вы можете предоставить минимально воспроизводимый пример в вопросе (для которого вообще не понадобится SpringBoot), который воспроизводит проблему путем копирования и вставки без изменений или дополнений ->, что позволит вам получить некоторую помощь в отладке, если вам нужно. это.

jewelsea 19.08.2024 20:55

Простой вызов diagnosisService.findByCode(...) ничего не даст, если вы не сделаете что-нибудь с возвращаемым списком. Вам нужно решить, будете ли вы фильтровать таблицу на стороне клиента (с помощью кода JavaFX) или на стороне базы данных (с использованием методов репозитория).

James_D 19.08.2024 21:17

Не по теме: не используйте PropertyValueFactory. См. stackoverflow.com/questions/72437983/….

James_D 19.08.2024 21:19

Не по теме: не используйте обработчики событий низкого уровня (например, onKeyPressed) с элементами управления высокого уровня (например, TextField). Вместо этого зарегистрируйте слушателя с помощью textProperty().

James_D 19.08.2024 21:20

Не по теме: является ли sortData() методом обработчика событий (зарегистрированным с помощью элемента управления в файле FXML)? Если это так, вам не следует добавлять прослушиватели в textProperty(), потому что в конечном итоге у вас будет несколько прослушивателей, выполняющих одну и ту же функциональность. (А если нет, то, очевидно, это не должно быть аннотировано @FXML.)

James_D 19.08.2024 21:59

@James_D - нет, это не метод обработчика событий. Вся логика фильтра находится внутри метода инициализатора. Похоже, я пытаюсь фильтровать данные, используя ОБА код javafx и методы репозитория.

Kameron Hazelwood 21.08.2024 17:16

Если это не метод обработчика событий, его не следует аннотировать @FXML.

James_D 21.08.2024 17:20

Чего вы на самом деле пытаетесь достичь с помощью обработчика ключевых событий searchCodes? Что должен делать этот код?

James_D 21.08.2024 17:21

Это правда! Я даже не заметил, что поставил @FXML в качестве аннотации к методу. Я вообще-то только что это понял. Сейчас происходит следующее: когда пользователь начинает вводить слово, таблица внизу фильтрует и сортирует код для выбора. Таким образом, им не придется прокручивать весь список вниз. Я обновлю основной вопрос решением. Спасибо за помощь!

Kameron Hazelwood 21.08.2024 18:10
1
10
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это была логическая ошибка.

Ниже приведено решение:

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(), затем создал фильтр, сортировку и добавил его в таблицу.

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