
本教程详细讲解如何在javafx应用中实现tableview的数据筛选功能,并通过文本输入框和按钮交互,动态获取筛选后的数据。文章将涵盖filteredlist和sortedlist的使用、文本监听器实现实时筛选,以及在按钮点击事件中准确获取当前tableview中显示的数据项,并探讨如何将这些数据传递给其他fxml视图进行进一步处理。
在JavaFX应用程序中,TableView 是一个功能强大的组件,常用于展示大量结构化数据。当数据量较大时,提供搜索和筛选功能可以极大地提升用户体验。本教程将指导您如何结合 TextField 和 Button,实现对 TableView 数据的动态筛选,并在用户点击搜索按钮后,获取并处理筛选后的结果。
JavaFX提供了一套灵活的机制来管理和筛选 TableView 的数据。主要涉及到以下几个关键类:
通过将 FilteredList 绑定到 TextField 的文本变化监听器上,我们可以实现实时搜索功能。
首先,我们需要一个包含 TableView、TextField 和 Button 的FXML布局文件。
立即学习“Java免费学习笔记(深入)”;
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<GridPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.TableController">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" spacing="10.0">
<TextField fx:id="mTextField" prefHeight="28.0" prefWidth="366.0" promptText="输入ID搜索" />
<Button fx:id="searchBtn" mnemonicParsing="false" onAction="#handleSearch" prefHeight="26.0" prefWidth="166.0" text="搜索" />
</HBox>
<TableView fx:id="mTableView" prefHeight="451.0" prefWidth="929.0" GridPane.rowIndex="1">
<columns>
<TableColumn fx:id="idColumn" prefWidth="75.0" text="ID" />
<TableColumn fx:id="nameColumn" prefWidth="75.0" text="Name" />
<TableColumn fx:id="salColumn" prefWidth="75.0" text="Salary" />
</columns>
</TableView>
</GridPane>接下来,是对应的控制器骨架和数据模型。
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<Employee> mTableView;
@FXML
private TableColumn<Employee, Integer> idColumn;
@FXML
private TableColumn<Employee, String> nameColumn;
@FXML
private TableColumn<Employee, Double> salColumn; // 假设Salary是Double类型
@FXML
private TextField mTextField;
@FXML
private Button searchBtn;
private ObservableList<Employee> mList = FXCollections.observableArrayList();
private FilteredList<Employee> filteredList;
private SortedList<Employee> 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<Employee>
*/
private Predicate<Employee> 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 中显示(即已经过筛选和排序)的数据。
关键在于 mTableView.getItems() 方法。无论 TableView 绑定的是原始 ObservableList、FilteredList 还是 SortedList,mTableView.getItems() 总是返回当前 TableView 实际显示的数据列表。因此,如果您的 TableView 已经绑定了 SortedList(它又包装了 FilteredList),那么 getItems() 返回的就是经过筛选和排序后的数据。
在 handleSearch 方法中,您可以这样获取数据:
@FXML
public void handleSearch(ActionEvent event) {
// 获取当前TableView中显示的所有数据项
ObservableList<Employee> 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);
}
}在实际应用中,您可能需要将筛选出的数据(例如 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 示例:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox alignment="CENTER" spacing="10.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.DetailController">
<Label fx:id="idLabel" text="ID:" />
<Label fx:id="nameLabel" text="姓名:" />
<Label fx:id="salaryLabel" text="薪水:" />
</VBox>通过本教程,您应该已经掌握了如何在JavaFX中实现 TableView 的动态筛选功能。核心在于利用 FilteredList 和 SortedList 来管理数据视图,并通过 TextField 的文本监听器实时更新筛选条件。在按钮点击事件中,mTableView.getItems() 方法是获取当前筛选后数据集合的关键。结合 FXMLLoader,您可以轻松地将这些数据传递到其他视图,构建更加复杂和交互性强的JavaFX应用程序。
以上就是JavaFX TableView筛选与搜索结果动态获取教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号