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

JavaFX8添加FilteredList和SortedList实现搜索栏触发InvocationTargetException

解决JavaFX8中FilteredList/SortedList引发的InvocationTargetException异常

先看你提供的堆栈跟踪,最关键的错误是这行:

Caused by: java.lang.NullPointerException at javafx.collections.transformation.TransformationList.(TransformationList.java:65)

这说明你在创建FilteredList的时候,传入的源列表是null,根本没完成初始化。

问题出在哪?

你只声明了private ObservableList<DataHandler_ExamsListing> EListingData;但没给它赋值,而且应该是在控制器的构造函数里就尝试创建FilteredList了——这时候LoadEListingData()还没执行,EListingData还是个空引用,自然会抛出空指针。

怎么修复?

这里给你两个可行的方案:

方案1:提前初始化ObservableList

直接在声明的时候就初始化列表,哪怕还没加载数据,它也是个空列表而不是null:

private ObservableList<DataHandler_ExamsListing> EListingData = FXCollections.observableArrayList();

这样你之后创建FilteredList时,就不会因为源列表为null报错了。

方案2:调整FilteredList的创建时机

别在构造函数里碰FilteredList,把初始化逻辑移到initialize()方法里——这是JavaFX控制器的标准初始化方法,会在FXML加载完成后自动执行,而且你可以确保数据加载完成后再创建过滤和排序列表。

示例代码参考:

private ObservableList<DataHandler_ExamsListing> EListingData;
private FilteredList<DataHandler_ExamsListing> filteredData;
private SortedList<DataHandler_ExamsListing> sortedData;

@Override
public void initialize(URL url, ResourceBundle rb) {
    // 先加载数据库数据
    LoadEListingData();
    // 初始化过滤列表,默认显示所有数据
    filteredData = new FilteredList<>(EListingData, p -> true);
    
    // 给搜索文本框添加监听,实现实时过滤
    searchTextField.textProperty().addListener((observable, oldValue, newValue) -> {
        filteredData.setPredicate(data -> {
            // 搜索框为空时显示全部
            if (newValue == null || newValue.trim().isEmpty()) {
                return true;
            }
            // 按你的需求编写匹配逻辑,这里示例匹配ID、考试名、日期
            String filter = newValue.toLowerCase().trim();
            return String.valueOf(data.getExamID()).contains(filter)
                    || data.getExamName().toLowerCase().contains(filter)
                    || data.getExamDate().toLowerCase().contains(filter);
        });
    });
    
    // 初始化排序列表,绑定到TableView的排序规则
    sortedData = new SortedList<>(filteredData);
    sortedData.comparatorProperty().bind(yourTableView.comparatorProperty());
    // 把排序后的数据设置给TableView
    yourTableView.setItems(sortedData);
}

另外,你提供的LoadEListingData()代码不完整,记得要完整读取ResultSet的数据,最好用try-with-resources来自动关闭数据库资源,避免泄漏:

private void LoadEListingData(){
    EListingData = FXCollections.observableArrayList();
    // try-with-resources自动关闭连接、statement、resultSet
    try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT * FROM Exam")) {
        
        while (rs.next()) {
            EListingData.add(new DataHandler_ExamsListing(
                    rs.getInt("ExamID"),
                    rs.getString("ExamName"),
                    rs.getString("ExamDate")
                    // 这里补充你需要的其他字段
            ));
        }
    } catch (SQLException e) {
        e.printStackTrace();
        // 这里可以添加错误提示,比如弹出Alert
    }
}

小提醒

永远别在控制器的构造函数里操作FXML组件或者依赖未初始化的数据——构造函数执行时,FXML里的控件还没完成加载,你的数据列表也大概率还没准备好,initialize()方法才是做初始化工作的正确地方。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:08:33