0

0

JavaFX TableView筛选与搜索结果动态获取教程

霞舞

霞舞

发布时间:2025-11-07 15:31:01

|

591人浏览过

|

来源于php中文网

原创

JavaFX TableView筛选与搜索结果动态获取教程

本教程详细讲解如何在javafx应用中实现tableview的数据筛选功能,并通过文本输入框和按钮交互,动态获取筛选后的数据。文章将涵盖filteredlist和sortedlist的使用、文本监听器实现实时筛选,以及在按钮点击事件中准确获取当前tableview中显示的数据项,并探讨如何将这些数据传递给其他fxml视图进行进一步处理。

在JavaFX应用程序中,TableView 是一个功能强大的组件,常用于展示大量结构化数据。当数据量较大时,提供搜索和筛选功能可以极大地提升用户体验。本教程将指导您如何结合 TextField 和 Button,实现对 TableView 数据的动态筛选,并在用户点击搜索按钮后,获取并处理筛选后的结果。

核心概念:JavaFX TableView的筛选机制

JavaFX提供了一套灵活的机制来管理和筛选 TableView 的数据。主要涉及到以下几个关键类:

  1. ObservableList: 存储 TableView 的原始数据。任何对该列表的修改都会自动反映在 TableView 上。
  2. FilteredList: 包装一个 ObservableList,并根据一个 Predicate 对象来过滤数据。当 Predicate 发生变化时,FilteredList 会自动更新其内容。
  3. SortedList: 包装一个 FilteredList (或任何 ObservableList),并根据 TableView 的排序规则来排序数据。它允许用户通过点击列头进行排序。

通过将 FilteredList 绑定到 TextField 的文本变化监听器上,我们可以实现实时搜索功能。

准备工作:FXML布局与控制器骨架

首先,我们需要一个包含 TableView、TextField 和 Button 的FXML布局文件。

立即学习Java免费学习笔记(深入)”;







    
        
    
    
        
        
    
    
        
        

接下来,是对应的控制器骨架和数据模型。

package com.example;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;

import java.net.URL;
import java.util.ResourceBundle;
import java.util.function.Predicate;

public class TableController implements Initializable {

    @FXML
    private TableView mTableView;
    @FXML
    private TableColumn idColumn;
    @FXML
    private TableColumn nameColumn;
    @FXML
    private TableColumn salColumn; // 假设Salary是Double类型
    @FXML
    private TextField mTextField;
    @FXML
    private Button searchBtn;

    private ObservableList mList = FXCollections.observableArrayList();
    private FilteredList filteredList;
    private SortedList sortedList;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        // 初始化列的单元格值工厂
        idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
        salColumn.setCellValueFactory(new PropertyValueFactory<>("salary"));

        // 模拟加载数据
        loadRecords();

        // 初始化FilteredList和SortedList
        filteredList = new FilteredList<>(mList, b -> true); // 初始显示所有数据
        sortedList = new SortedList<>(filteredList);
        sortedList.comparatorProperty().bind(mTableView.comparatorProperty()); // 绑定排序属性
        mTableView.setItems(sortedList); // 将排序列表设置给TableView

        // 添加TextField的文本变化监听器,实现实时筛选
        mTextField.textProperty().addListener((observable, oldValue, newValue) -> {
            filteredList.setPredicate(createSearchPredicate(newValue));
        });
    }

    /**
     * 模拟从数据库或其他源加载数据
     */
    private void loadRecords() {
        mList.add(new Employee(101, "Alice", 5000.0));
        mList.add(new Employee(102, "Bob", 6000.0));
        mList.add(new Employee(103, "Charlie", 7500.0));
        mList.add(new Employee(104, "David", 4500.0));
        mList.add(new Employee(201, "Eve", 8000.0));
        mList.add(new Employee(202, "Frank", 9000.0));
    }

    /**
     * 根据搜索关键字创建Predicate
     * @param searchText 搜索文本
     * @return Predicate
     */
    private Predicate createSearchPredicate(String searchText) {
        return employee -> {
            // 如果搜索文本为空,显示所有数据
            if (searchText == null || searchText.isEmpty() || searchText.isBlank()) {
                return true;
            }

            String lowerCaseSearchText = searchText.toLowerCase();

            // 检查员工ID是否包含搜索关键字
            if (String.valueOf(employee.getId()).toLowerCase().contains(lowerCaseSearchText)) {
                return true;
            }
            // 检查员工姓名是否包含搜索关键字
            if (employee.getName().toLowerCase().contains(lowerCaseSearchText)) {
                return true;
            }
            // 可以添加更多字段的检查,例如薪水
            // if (String.valueOf(employee.getSalary()).toLowerCase().contains(lowerCaseSearchText)) {
            //     return true;
            // }

            return false; // 不匹配
        };
    }

    @FXML
    public void handleSearch(ActionEvent event) {
        // 此方法将在下面详细实现
    }
}

Employee数据模型:

package com.example;

import javafx.beans.property.*;

public class Employee {
    private final IntegerProperty id;
    private final StringProperty name;
    private final DoubleProperty salary;

    public Employee(int id, String name, double salary) {
        this.id = new SimpleIntegerProperty(id);
        this.name = new SimpleStringProperty(name);
        this.salary = new SimpleDoubleProperty(salary);
    }

    public int getId() {
        return id.get();
    }

    public IntegerProperty idProperty() {
        return id;
    }

    public void setId(int id) {
        this.id.set(id);
    }

    public String getName() {
        return name.get();
    }

    public StringProperty nameProperty() {
        return name;
    }

    public void setName(String name) {
        this.name.set(name);
    }

    public double getSalary() {
        return salary.get();
    }

    public DoubleProperty salaryProperty() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary.set(salary);
    }
}

获取筛选后的数据:按钮点击事件处理

当用户在 TextField 中输入搜索词并点击“搜索”按钮时,我们通常希望获取当前 TableView 中显示(即已经过筛选和排序)的数据。

超会AI
超会AI

AI驱动的爆款内容制造机

下载

关键在于 mTableView.getItems() 方法。无论 TableView 绑定的是原始 ObservableList、FilteredList 还是 SortedList,mTableView.getItems() 总是返回当前 TableView 实际显示的数据列表。因此,如果您的 TableView 已经绑定了 SortedList(它又包装了 FilteredList),那么 getItems() 返回的就是经过筛选和排序后的数据。

在 handleSearch 方法中,您可以这样获取数据:

    @FXML
    public void handleSearch(ActionEvent event) {
        // 获取当前TableView中显示的所有数据项
        ObservableList currentDisplayedEmployees = mTableView.getItems();

        if (currentDisplayedEmployees.isEmpty()) {
            System.out.println("没有找到匹配的员工。");
            // 可以显示一个提示信息给用户
            // Alert alert = new Alert(Alert.AlertType.INFORMATION, "没有找到匹配的员工!");
            // alert.showAndWait();
        } else {
            // 假设我们只关心第一个匹配项
            Employee firstResult = currentDisplayedEmployees.get(0);
            System.out.println("搜索结果的第一个员工ID: " + firstResult.getId() + ", 姓名: " + firstResult.getName());

            // 如果需要,您可以遍历所有结果
            // for (Employee emp : currentDisplayedEmployees) {
            //     System.out.println("匹配员工: " + emp.getName());
            // }

            // 进一步处理:例如,加载另一个FXML并传递这个员工对象
            // loadAnotherFxml(firstResult);
        }
    }

数据传递与多FXML场景

在实际应用中,您可能需要将筛选出的数据(例如 firstResult)传递给另一个FXML视图的控制器。这通常通过 FXMLLoader 来实现。

import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;

// ... 在TableController中 ...

private void loadAnotherFxml(Employee employeeToPass) {
    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/example/detailView.fxml"));
        Parent root = loader.load();

        // 获取目标控制器的实例
        DetailController detailController = loader.getController();
        // 调用目标控制器的方法来设置数据
        detailController.initData(employeeToPass);

        Stage stage = new Stage();
        stage.setScene(new Scene(root));
        stage.setTitle("员工详情");
        stage.show();

        // 如果需要关闭当前窗口
        // ((Stage) mTableView.getScene().getWindow()).close();

    } catch (IOException e) {
        e.printStackTrace();
        // 错误处理,例如显示一个警告框
        // Alert alert = new Alert(Alert.AlertType.ERROR, "无法加载详情视图:" + e.getMessage());
        // alert.showAndWait();
    }
}

对应的 DetailController 示例:

package com.example;

import javafx.fxml.FXML;
import javafx.scene.control.Label;

public class DetailController {

    @FXML
    private Label idLabel;
    @FXML
    private Label nameLabel;
    @FXML
    private Label salaryLabel;

    public void initData(Employee employee) {
        if (employee != null) {
            idLabel.setText("ID: " + employee.getId());
            nameLabel.setText("姓名: " + employee.getName());
            salaryLabel.setText("薪水: " + employee.getSalary());
        }
    }
}

以及 detailView.fxml 示例:







    

注意事项与最佳实践

  1. 处理空结果集: 在 handleSearch 方法中,务必检查 currentDisplayedEmployees 是否为空。如果为空,应向用户提供适当的反馈(例如,弹出一个提示框)。
  2. 处理多结果集: 如果筛选后有多个结果,您需要决定如何处理。
    • 选择第一个: 如示例所示,直接获取 get(0)。
    • 全部处理: 遍历整个 currentDisplayedEmployees 列表。
    • 用户选择: 如果希望用户从多个结果中手动选择,可以考虑在 TableView 中添加一个选择列,或者弹出一个新的 Dialog 让用户进行选择。
  3. 性能优化: 对于非常大的数据集(数万甚至数十万条记录),实时筛选可能会有性能问题。可以考虑:
    • 延迟搜索: 使用 Platform.runLater 或 Timeline 在用户停止输入一段时间后才执行筛选。
    • 后端搜索: 将搜索逻辑移到后端服务,只加载匹配的数据。
  4. 错误处理: 在加载新的FXML文件时,FXMLLoader.load() 可能会抛出 IOException。务必捕获并处理这些异常,向用户提供友好的错误信息。
  5. Predicate逻辑: createSearchPredicate 方法中的逻辑可以根据您的需求进行扩展。例如,可以支持多个字段的组合搜索,或者更复杂的匹配规则(如正则表达式)。

总结

通过本教程,您应该已经掌握了如何在JavaFX中实现 TableView 的动态筛选功能。核心在于利用 FilteredList 和 SortedList 来管理数据视图,并通过 TextField 的文本监听器实时更新筛选条件。在按钮点击事件中,mTableView.getItems() 方法是获取当前筛选后数据集合的关键。结合 FXMLLoader,您可以轻松地将这些数据传递到其他视图,构建更加复杂和交互性强的JavaFX应用程序。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

505

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

245

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

722

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

209

2023.08.11

正则表达式空格
正则表达式空格

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。本专题为大家提供正则表达式相关的文章、下载、课程内容,供大家免费下载体验。

343

2023.08.31

Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

293

2023.11.13

正则表达式空格如何表示
正则表达式空格如何表示

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。想了解更多正则表达式空格怎么表示的内容,可以访问下面的文章。

228

2023.11.17

正则表达式中如何匹配数字
正则表达式中如何匹配数字

正则表达式中可以通过匹配单个数字、匹配多个数字、匹配固定长度的数字、匹配整数和小数、匹配负数和匹配科学计数法表示的数字的方法匹配数字。更多关于正则表达式的相关知识详情请看本专题下面的文章。php中文网欢迎大家前来学习。

524

2023.12.06

笔记本电脑卡反应很慢处理方法汇总
笔记本电脑卡反应很慢处理方法汇总

本专题整合了笔记本电脑卡反应慢解决方法,阅读专题下面的文章了解更多详细内容。

1

2025.12.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2万人学习

C# 教程
C# 教程

共94课时 | 5.3万人学习

Java 教程
Java 教程

共578课时 | 37.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号