You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX+SpringBoot下TableView搜索过滤失效问题求助

问题

开发了一个基于JavaFX和SpringBoot的程序,包含带“代码”列和“描述”列的TableView。需求是用户在搜索文本框输入内容时,表格实时过滤数据。此前用FilteredList实现了过滤功能,但集成SpringBoot后失效。尝试给searchCodes设置按键事件,调用diagnosisService的findByCode(String code)方法也未成功,询问是否遗漏SpringBoot相关实现方式。

相关代码

最初实现代码(DiagnosisCode.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);
    }

尝试的按键事件实现代码(DiagnosisCode.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);
        });


    }
解决方案

问题分析

  1. 最初FilteredList实现的核心问题:

    • 初始化顺序错误:先给表格设置原始数据,再调用sortData,但sortData中使用的listView未赋值(应基于原始数据创建FilteredList),导致过滤逻辑绑定到空数据源。
    • 未保留原始数据的ObservableList引用,无法正确构建过滤链。
  2. 按键事件实现的核心问题:

    • 调用diagnosisService.findByCode(name)后,未将查询结果设置到TableView的items中,表格数据无更新。
    • 未考虑UI线程更新:Spring服务方法可能在非UI线程执行,直接更新UI会报错。

修正后的FilteredList实现(本地过滤,推荐小数据量场景)

步骤1:添加成员变量保存原始数据

在控制器类中声明:

private ObservableList<IDiagnosisModel> originalData;

步骤2:调整初始化逻辑与过滤方法

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    // 初始化表格列
    codeCol.setCellValueFactory(new PropertyValueFactory<>("Code"));
    descripCol.setCellValueFactory(new PropertyValueFactory<>("Description"));
    newDiagCodeTable.getColumns().setAll(codeCol, descripCol);
    
    // 从Spring服务获取原始数据并保存
    originalData = FXCollections.observableArrayList(diagnosisService.findAll());
    
    // 初始化过滤与排序逻辑
    setupFilterAndSort();
}

@FXML
public void setupFilterAndSort(){
    // 基于原始数据创建FilteredList
    FilteredList<IDiagnosisModel> filteredData = new FilteredList<>(originalData, b -> true);
    
    // 监听搜索框文本变化,动态更新过滤规则
    searchCodes.textProperty().addListener((obs, oldValue, newValue) -> {
        filteredData.setPredicate(diagnosisCode -> {
            if (newValue == null || newValue.isEmpty()) {
                return true;
            }
            String lowerCaseFilter = newValue.toLowerCase();
            
            // 匹配描述或代码
            return diagnosisCode.getDiagnosisDescription().toLowerCase().contains(lowerCaseFilter)
                    || diagnosisCode.getDiagnosisCode().toLowerCase().contains(lowerCaseFilter);
        });
    });
    
    // 绑定表格排序到SortedList
    SortedList<IDiagnosisModel> sortedData = new SortedList<>(filteredData);
    sortedData.comparatorProperty().bind(newDiagCodeTable.comparatorProperty());
    
    // 将最终的SortedList设置为表格数据源
    newDiagCodeTable.setItems(sortedData);
}

修正后的按键事件实现(服务端查询,适合大数据量场景)

@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()));
    
    // 绑定搜索框按键事件
    this.searchCodes.setOnKeyPressed(keyEvent -> {
        String name = this.searchCodes.getText().trim();
        // 确保在JavaFX UI线程更新表格数据
        Platform.runLater(() -> {
            List<IDiagnosisModel> searchResult = diagnosisService.findByCode(name);
            newDiagCodeTable.setItems(FXCollections.observableArrayList(searchResult));
        });
    });
}

SpringBoot相关注意事项

  • 确保服务Bean正确注入:控制器类需被Spring托管(可通过@Component注解),或通过Spring上下文获取diagnosisService实例,避免空指针。
  • 服务方法实现规范:若使用Spring Data JPA,findByCode方法需符合命名规范(或添加@Query注解),确保能正确查询数据库。
  • 异步查询优化:若服务端查询耗时,可使用@Async注解标记服务方法,配合CompletableFuture异步获取结果后更新UI。

内容的提问来源于stack exchange,提问作者Haze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 11:29:56