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

JavaFX:点击按钮时如何从TableView获取筛选后的值

JavaFX筛选TableView后获取值并跳转FXML问题

我是JavaFX新手,正在尝试用TextField实现带筛选功能的TableView。设置了TextField和搜索按钮,需求是在TextField输入搜索值后点击搜索按钮,若该值存在于表格中,需加载另一个FXML(将选中值作为参数传递给该FXML及其控制器),但无法在handleSearch()方法中获取筛选后的值。

FXML代码

<TableView fx:id="mTableView" layoutY="71.0" 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>
....
....

<TextField fx:id="mTextField" prefHeight="28.0" prefWidth="366.0" />
<Button fx:id="searchBtn" mnemonicParsing="false" onAction="#handleSearch" prefHeight="26.0" prefWidth="166.0"  text="Search" />

控制器代码

@FXML
private TableView<Employee> mTableView;

@FXML
private TableColumn<Employee, Integer> idColumn;
@FXML
private TableColumn<Employee, String> nameColumn;
@FXML
private TableColumn<Employee, String> salColumn;

ObservableList<Employee>  mList = FXCollections.observableArrayList();

@FXML
public void handleSearch(ActionEvent event) {
 // 需要在这里获取筛选后的值以加载另一个fxml
}


public void loadRecords(){
// 此方法用于从数据库加载数据填充TableView(从控制器的initialize()方法调用)
...
...
 idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("Name"));
        salColumn.setCellValueFactory(new PropertyValueFactory<>("salary"));
        mTableView.setItems(mList);
        FilteredList<Employee> filteredList = new FilteredList<>(mList,b->true);
        mTextField.textProperty().addListener(((observableValue, oldValue, newValue) -> {
            key = null;
            filteredList.setPredicate(cinema -> {
                if(newValue.isEmpty() || newValue.isBlank() || newValue == null){
                    return true;
                }
                String searchKeyword = newValue.toLowerCase();
              
                if(isContain(cinema.getId().toString().toLowerCase(),searchKeyword)){
                    return true;
                }
                else {
                    return false;
                }
            });
        }));
        SortedList<Employee> sortedList = new SortedList<>(filteredList);
        key = filteredList.get(0).getId().toString();
        sortedList.comparatorProperty().bind(mTableView.comparatorProperty());
        mTableView.setItems(sortedList);
}

解决方案

1. 将FilteredList改为成员变量

目前FilteredList是loadRecords()方法的局部变量,handleSearch()无法访问。把它提升为控制器的成员变量,并补充TextField的FXML注入:

@FXML
private TextField mTextField;
private FilteredList<Employee> filteredList; // 成员变量

然后在loadRecords()里初始化:

filteredList = new FilteredList<>(mList, b->true);

2. 在handleSearch()中获取筛选结果

有两种实用方式:

  • 方式一:获取用户选中的项(支持多结果场景下用户自主选择)
@FXML
public void handleSearch(ActionEvent event) {
    Employee selectedEmployee = mTableView.getSelectionModel().getSelectedItem();
    if(selectedEmployee != null){
        // 加载另一个FXML并传递参数
        loadAnotherFXML(selectedEmployee);
    } else {
        // 提示用户先选择项
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("提示");
        alert.setHeaderText(null);
        alert.setContentText("请先选择表格中的员工");
        alert.showAndWait();
    }
}
  • 方式二:直接获取筛选后的第一个匹配项(适合确定唯一匹配的场景)
@FXML
public void handleSearch(ActionEvent event) {
    if(!filteredList.isEmpty()){
        Employee matchedEmployee = filteredList.get(0);
        loadAnotherFXML(matchedEmployee);
    } else {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("提示");
        alert.setHeaderText(null);
        alert.setContentText("没有找到匹配的员工");
        alert.showAndWait();
    }
}

3. 实现加载另一个FXML并传递参数

private void loadAnotherFXML(Employee employee) {
    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("目标FXML文件路径.fxml"));
        Parent root = loader.load();
        
        // 获取目标控制器并传递参数
        AnotherController controller = loader.getController();
        controller.setEmployee(employee); // 假设目标控制器有对应的参数接收方法
        
        // 切换场景(也可改为弹出新窗口)
        Stage stage = (Stage) mTableView.getScene().getWindow();
        stage.setScene(new Scene(root));
        stage.show();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

4. 额外优化提示

  • 确保Employee类的属性名与PropertyValueFactory参数对应(比如nameColumn用的"Name"要对应Employee类的getName()方法,或使用JavaFX属性)
  • 避免在loadRecords()中直接调用filteredList.get(0),若初始列表为空会报错,建议添加非空判断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 06:26:28