JavaFX+H2项目搜索栏联动总计TextField异常问题求助
JavaFX+H2 CRUD项目筛选后总价计算问题解决
问题描述
搜索栏可正常筛选TableView的记录,但用于显示当前TableView内所有记录总价的total TextField,始终显示数据库中该列所有记录的总和,而非筛选后的结果。
问题分析
- 原始代码缺陷:
searchData()方法仅在初始化TableView数据后调用了一次total(),后续搜索文本变化导致FilteredList更新时,没有触发重新计算总和,因此total显示的始终是初始全量数据的总和。 - 修改尝试错误:将
total()放在Predicate的判断逻辑中,而Predicate是对每条数据进行筛选判断的方法,每一条数据都会触发一次total()调用,不仅会重复计算导致性能问题,而且此时筛选操作尚未完成,计算的结果也不准确。
解决方案
核心思路是:每次筛选条件变化并完成列表更新后,重新计算当前TableView中显示数据的总和。可以通过在搜索文本的监听器内,设置完筛选条件后立即调用total(),同时在初始化列表时也调用一次total()确保初始值正确。
修改后的代码
搜索方法优化
private void searchData() { FilteredList<Data> filteredData = new FilteredList<>(getDataList(), b -> true); search.textProperty().addListener((observable, oldValue, newValue) -> { // 设置筛选规则 filteredData.setPredicate(data -> { if(newValue.isEmpty() || newValue.isBlank()) { return true; } String lowerCase = newValue.toLowerCase(); return data.getName().toLowerCase().contains(lowerCase) || data.getCategory().toLowerCase().contains(lowerCase) || String.valueOf(data.getPrice()).toLowerCase().contains(lowerCase) || String.valueOf(data.getDate()).toLowerCase().contains(lowerCase); }); // 筛选完成后立即计算当前列表总和 total(); }); SortedList<Data> sortedData = new SortedList<>(filteredData); sortedData.comparatorProperty().bind(table.comparatorProperty()); table.setItems(sortedData); // 初始化列表时计算一次全量数据总和 total(); }
总价计算方法(简化优化)
private void total() { int totalAmount = table.getItems() .stream() .mapToInt(Data::getPrice) .sum(); total.setText(String.valueOf(totalAmount)); }
注:这里将原有的
reduce替换为更简洁的mapToInt().sum(),逻辑完全一致,可读性更强。
额外优化建议
如果希望更实时地响应列表变化(比如后续可能有其他操作修改TableView数据),可以给TableView的items添加监听器,只要列表内容变化就自动计算总和:
// 在初始化方法中添加监听器 table.getItems().addListener((ListChangeListener<Data>) c -> { total(); });
这样无论通过搜索筛选还是其他操作修改列表数据,total都会自动更新。
内容的提问来源于stack exchange,提问作者Damian
相关产品推荐
相关产品推荐

