0

0

JavaFX TableView 动态过滤与选中项获取及跨视图数据传递教程

霞舞

霞舞

发布时间:2025-11-07 13:46:12

|

412人浏览过

|

来源于php中文网

原创

JavaFX TableView 动态过滤与选中项获取及跨视图数据传递教程

本教程详细阐述了如何在 javafx 中实现 tableview 的动态数据过滤功能,通过 textfield 实时更新显示内容。重点讲解了如何在用户点击按钮时,从已过滤的 tableview 中准确获取当前显示的数据(特别是第一个匹配项),并演示了如何将这些获取到的数据安全地传递给另一个 fxml 视图及其控制器,以实现复杂的应用交互逻辑。

JavaFX TableView 高级用法:实现动态过滤与选中项获取

在 JavaFX 应用开发中,TableView 是一个常用的组件,用于展示结构化数据。当数据量较大时,用户往往需要通过搜索或过滤功能来快速定位所需信息。本教程将指导您如何实现一个带有动态过滤功能的 TableView,并在用户点击按钮时,获取当前过滤结果中的数据,并将其传递给另一个 FXML 视图。

1. 核心组件概览

为了实现动态过滤和数据获取,我们将使用以下 JavaFX 组件和集合类:

  • TableView: 显示数据的表格。
  • TableColumn: TableView 中的列定义。
  • TextField: 用户输入过滤关键词的文本框。
  • Button: 触发数据获取和视图切换的按钮。
  • ObservableList: 存储原始数据,支持数据变更通知。
  • FilteredList: 基于 ObservableList 创建,通过 Predicate 实现数据过滤。
  • SortedList: 基于 FilteredList 创建,支持数据排序,并最终绑定到 TableView。

2. 构建数据模型

首先,我们需要一个简单的数据模型来表示表格中的每一行。以 Employee 为例:

// Employee.java
public class Employee {
    private final SimpleIntegerProperty id;
    private final SimpleStringProperty name;
    private final SimpleStringProperty salary;

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

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

    public SimpleIntegerProperty idProperty() {
        return id;
    }

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

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

    public SimpleStringProperty nameProperty() {
        return name;
    }

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

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

    public SimpleStringProperty salaryProperty() {
        return salary;
    }

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

3. FXML 布局配置

在 FXML 文件中,我们需要定义 TableView、TextField 和 Button。确保为它们设置 fx:id 和 onAction 属性,以便在控制器中引用和处理事件。

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

Otter.ai
Otter.ai

一个自动的会议记录和笔记工具,会议内容生成和实时转录

下载











   
      
        
          
        
        
          
          
        
         
            
               
                  
                  
                  
               
               
                  
               
            
            
               
                  
                  

4. 控制器逻辑实现

控制器是实现所有业务逻辑的地方。我们将在这里初始化 TableView、绑定数据、实现过滤逻辑以及处理按钮点击事件

// YourController.java
package yourpackage;

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.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

public class YourController implements Initializable {

    @FXML
    private TableView mTableView;
    @FXML
    private TableColumn idColumn;
    @FXML
    private TableColumn nameColumn;
    @FXML
    private TableColumn salColumn;
    @FXML
    private TextField mTextField;
    @FXML
    private Button searchBtn;

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

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

        // 2. 加载数据 (这里使用模拟数据,实际应用中可能从数据库加载)
        loadRecords();

        // 3. 创建 FilteredList 并绑定到原始数据
        filteredList = new FilteredList<>(mList, b -> true); // b->true 表示默认显示所有数据

        // 4. 为 TextField 添加监听器,实现动态过滤
        mTextField.textProperty().addListener((observable, oldValue, newValue) -> {
            filteredList.setPredicate(employee -> {
                // 如果搜索框为空或空白,则显示所有数据
                if (newValue == null || newValue.isEmpty() || newValue.isBlank()) {
                    return true;
                }

                String searchKeyword = newValue.toLowerCase();

                // 根据 ID 进行过滤 (这里只过滤ID,您可以扩展到其他字段)
                return String.valueOf(employee.getId()).toLowerCase().contains(searchKeyword);
            });
        });

        // 5. 将 FilteredList 包装成 SortedList
        SortedList sortedList = new SortedList<>(filteredList);

        // 6. 将 SortedList 的比较器属性绑定到 TableView 的比较器属性
        // 这样 TableView 的排序操作会影响 SortedList
        sortedList.comparatorProperty().bind(mTableView.comparatorProperty());

        // 7. 将 SortedList 设置为 TableView 的数据源
        mTableView.setItems(sortedList);
    }

    /**
     * 模拟加载数据到 ObservableList
     * 实际应用中会从数据库或其他数据源获取
     */
    private void loadRecords() {
        mList.add(new Employee(101, "Alice", "50000"));
        mList.add(new Employee(102, "Bob", "60000"));
        mList.add(new Employee(103, "Charlie", "75000"));
        mList.add(new Employee(201, "David", "55000"));
        mList.add(new Employee(202, "Eve", "62000"));
        mList.add(new Employee(301, "Frank", "80000"));
    }

    /**
     * 处理搜索按钮点击事件
     * 获取当前 TableView 中过滤后的数据,并传递给另一个 FXML 视图
     */
    @FXML
    public void handleSearch(ActionEvent event) {
        // 获取 TableView 当前显示的所有项 (这些项已经是经过过滤和排序的)
        ObservableList currentDisplayedItems = mTableView.getItems();

        if (!currentDisplayedItems.isEmpty()) {
            // 获取第一个匹配的员工对象
            Employee selectedEmployee = currentDisplayedItems.get(0);
            System.out.println("Selected Employee (first filtered): " + selectedEmployee.getName() + " (ID: " + selectedEmployee.getId() + ")");

            // 示例:加载另一个 FXML 视图并传递数据
            try {
                // 假设您有一个名为 "DetailView.fxml" 的新视图
                FXMLLoader loader = new FXMLLoader(getClass().getResource("/yourpackage/DetailView.fxml"));
                Parent root = loader.load();

                // 获取新视图的控制器
                DetailController detailController = loader.getController();
                // 调用新控制器的方法来传递数据
                detailController.setEmployeeDetails(selectedEmployee);

                // 创建并显示新场景
                Stage stage = new Stage();
                stage.setTitle("Employee Details");
                stage.setScene(new Scene(root));
                stage.show();

                // 可选:关闭当前窗口
                // ((Stage) searchBtn.getScene().getWindow()).close();

            } catch (IOException e) {
                e.printStackTrace();
                // 处理加载 FXML 失败的错误
            }
        } else {
            System.out.println("No employee found matching the filter criteria.");
            // 可以在此处显示一个警告框通知用户
        }
    }
}

5. 创建目标 FXML 视图及控制器

为了演示数据传递,我们需要一个接收数据的目标 FXML 视图和其对应的控制器。









   
      
      
// DetailController.java
package yourpackage;

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

public class DetailController {

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

    /**
     * 设置员工详细信息到 UI 控件
     * @param employee 接收到的员工对象
     */
    public void setEmployeeDetails(Employee employee) {
        if (employee != null) {
            idLabel.setText("ID: " + employee.getId());
            nameLabel.setText("Name: " + employee.getName());
            salaryLabel.setText("Salary: " + employee.getSalary());
        }
    }
}

6. 注意事项与最佳实践

  • 获取过滤后的数据: 关键在于 mTableView.getItems() 方法。它返回的是 TableView 当前实际显示的数据(已经过 FilteredList 和 SortedList 处理)。直接访问 mList 或 filteredList 将无法反映 TableView 当前的显示状态。
  • 处理空结果集: 在 handleSearch 方法中,务必检查 currentDisplayedItems.isEmpty()。如果 TableView 中没有匹配项,尝试 get(0) 会导致 IndexOutOfBoundsException。
  • 处理多结果集: 当前示例只获取了第一个匹配项 (get(0))。如果需要处理所有匹配项,您可以遍历 currentDisplayedItems 列表。如果业务逻辑要求用户从多个匹配项中选择一个,您可能需要提供一个选择界面,或者修改 TableView 的选择模型。
  • 性能优化: 对于非常大的数据集,过滤操作可能会影响性能。考虑使用更高效的数据结构或在后台线程中执行复杂的过滤逻辑。
  • 错误处理: 在加载 FXML 文件时,务必捕获 IOException,并提供友好的错误提示。
  • 代码模块化: 将数据加载、过滤逻辑等拆分成独立的私有方法,提高代码的可读性和可维护性。
  • PropertyValueFactory 参数: PropertyValueFactory 构造函数中的字符串参数必须与数据模型 (Employee 类) 中属性的 getter 方法名匹配(例如,"id" 对应 getId() 和 idProperty())。

总结

通过本教程,您应该已经掌握了在 JavaFX 中实现 TableView 动态过滤的核心技术,包括使用 FilteredList 和 SortedList,以及如何监听 TextField 的输入变化。更重要的是,您学会了如何在按钮点击事件中准确获取 TableView 当前显示的数据,并将其作为参数传递给另一个 FXML 视图的控制器,从而实现复杂的界面交互和数据流转。这些技术是构建功能丰富的 JavaFX 应用的基础。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

258

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

209

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1468

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

620

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

550

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

545

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

165

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

81

2025.08.07

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

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

精品课程

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

共23课时 | 2.7万人学习

C# 教程
C# 教程

共94课时 | 7.1万人学习

Java 教程
Java 教程

共578课时 | 48.1万人学习

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

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