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

JavaFX中如何将TableView选中行数据传递至修改场景文本框

JavaFX场景间传递选中Part实例解决空指针问题

问题根源

你之前尝试让修改零件控制器继承主控制器,想在initialize()里通过partTableView.getSelectionModel()拿选中项,但这完全行不通——不同场景的控制器是独立的实例,继承并不能共享主控制器的UI组件引用,所以修改控制器里的partTableView必然是null,触发空指针异常。本质问题是没把主页面选中的Part实例直接传递到修改场景,反而试图跨场景获取UI元素。


解决方案

1. 重构控制器结构,取消继承关系

修改零件控制器和主控制器是平级的,各自管各自的UI,没必要继承。修改控制器可以实现Initializable,但初始化逻辑里别碰主控制器的元素。

2. 在修改控制器里加接收Part的方法

给修改控制器加一个方法,专门接收从主控制器传过来的选中Part,然后把数据填充到文本框里:

public class ModifyPartController implements Initializable {
    @FXML
    private TextField nameField;
    @FXML
    private TextField costField;
    @FXML
    private TextField stockField;
    @FXML
    private TextField minField;
    @FXML
    private TextField maxField;

    private Part selectedPart;

    // 接收主页面传递的选中零件
    public void setSelectedPart(Part part) {
        this.selectedPart = part;
        // 把零件数据填充到对应文本框
        nameField.setText(part.getName());
        costField.setText(String.valueOf(part.getCost()));
        stockField.setText(String.valueOf(part.getStock()));
        minField.setText(String.valueOf(part.getMin()));
        maxField.setText(String.valueOf(part.getMax()));
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        // 这里搞点通用初始化,比如文本框输入校验,别碰主控制器的东西
    }
}

3. 主控制器处理修改按钮点击,传递选中Part

在主控制器的修改按钮事件里,先拿到选中的Part,再加载修改场景,获取修改控制器实例,调用刚才的方法把Part传过去:

public class MainController {
    @FXML
    private TableView<Part> partTableView;
    @FXML
    private ObservableList<Part> partsList; // 绑定TableView的数据源

    @FXML
    private void onModifyPartClicked(ActionEvent event) {
        Part selectedPart = partTableView.getSelectionModel().getSelectedItem();
        if (selectedPart == null) {
            // 提示用户先选零件
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setTitle("提示");
            alert.setHeaderText(null);
            alert.setContentText("请先选择要修改的零件");
            alert.showAndWait();
            return;
        }

        try {
            // 加载修改场景的FXML
            FXMLLoader loader = new FXMLLoader(getClass().getResource("modify-part.fxml"));
            Parent root = loader.load();
            // 获取修改控制器实例
            ModifyPartController modifyController = loader.getController();
            // 传递选中的零件
            modifyController.setSelectedPart(selectedPart);

            // 切换到修改场景
            Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
            stage.setScene(new Scene(root));
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4. 修改完成后更新数据源

在修改控制器的保存按钮事件里,把文本框的新值更新到selectedPart上。如果你的Part类用了JavaFX的可观察属性(比如SimpleStringProperty、SimpleDoubleProperty),那ObservableList绑定的TableView会自动刷新;如果Part是普通POJO,就手动找到它在列表里的位置替换:

@FXML
private void onSaveModifyClicked(ActionEvent event) {
    // 从文本框取新值
    String name = nameField.getText();
    double cost = Double.parseDouble(costField.getText());
    int stock = Integer.parseInt(stockField.getText());
    int min = Integer.parseInt(minField.getText());
    int max = Integer.parseInt(maxField.getText());

    // 更新选中零件的属性
    selectedPart.setName(name);
    selectedPart.setCost(cost);
    selectedPart.setStock(stock);
    selectedPart.setMin(min);
    selectedPart.setMax(max);

    // 要是Part是普通POJO,就手动刷新列表:
    // int index = partsList.indexOf(selectedPart);
    // partsList.set(index, selectedPart);

    // 返回主页面
    Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
    stage.close();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:32:47