如何从TreeTableView单元格内获取所在行(JFXComboBox场景)
解决TreeTableView中JFXComboBox访问行数据及触发父行选中的问题
首先,你的代码里存在泛型不匹配的问题(比如Callback定义用了Obj但实现里用了Task,TreeTableCell的泛型也不一致),这是导致你无法正确关联行数据的第一个障碍。下面是完整的修正方案,同时满足你访问行数据、触发父行选中的需求,且不需要依赖全局的选中模型:
修正后的完整代码
thisColumn.setCellFactory(new Callback<TreeTableColumn<Task, String>, TreeTableCell<Task, String>>() { @Override public TreeTableCell<Task, String> call(final TreeTableColumn<Task, String> param) { JFXComboBox<String> jfxComboBox = new JFXComboBox<>(); jfxComboBox.setMinWidth(100.0); jfxComboBox.setPrefWidth(100.0); jfxComboBox.setItems(Class.profiles); // 最终返回的TreeTableCell,泛型和列保持一致 final TreeTableCell<Task, String> cell = new TreeTableCell<Task, String>() { private final HBox hBox = new HBox(jfxComboBox); @Override public void updateItem(String item, boolean empty) { super.updateItem(item, empty); if (empty) { setGraphic(null); } else { setGraphic(hBox); // 在这里获取当前行对应的Task对象 Task currentTask = getTreeTableRow().getItem(); // 可以根据currentTask初始化ComboBox的选中值 if (currentTask != null && currentTask.getProfile() != null) { jfxComboBox.getSelectionModel().select(currentTask.getProfile()); } } } }; // 给ComboBox添加监听,触发父行选中(比如当下拉框获得焦点时) jfxComboBox.focusedProperty().addListener((obs, oldVal, newVal) -> { if (newVal) { // 获取当前Cell所在的TreeTableRow,设置为选中状态 TreeTableRow<Task> row = cell.getTreeTableRow(); if (row != null && row.getItem() != null) { row.setSelected(true); } } }); // ComboBox选中值变化时,更新当前行的Task数据 jfxComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { Task currentTask = cell.getTreeTableRow().getItem(); if (currentTask != null && newValue != null) { // 这里可以更新Task的对应属性 currentTask.setProfile(newValue); } }); return cell; } });
关键要点说明
- 泛型一致性:确保
Callback、TreeTableColumn、TreeTableCell的泛型都统一为<Task, String>,这样整个CellFactory的类型匹配,不会出现类型转换问题。 - 获取当前行数据:通过
TreeTableCell.getTreeTableRow().getItem()直接获取当前Cell所在行的Task对象,不需要依赖全局的选中模型,完全基于当前Cell的上下文。 - 触发父行选中:通过监听ComboBox的
focusedProperty(或者showingProperty,当下拉框展开时),调用TreeTableRow.setSelected(true)来选中当前行,这样用户操作下拉框时,对应的行会自动被选中。 - 初始化ComboBox选中值:在
updateItem方法里,根据当前行的Task数据来设置ComboBox的默认选中项,保证数据和视图同步。
如果你希望在下拉框展开时就触发行选中,可以把focusedProperty换成showingProperty:
jfxComboBox.showingProperty().addListener((obs, oldVal, newVal) -> { if (newVal) { TreeTableRow<Task> row = cell.getTreeTableRow(); if (row != null && row.getItem() != null) { row.setSelected(true); } } });
内容的提问来源于stack exchange,提问作者Zera42
相关产品推荐
相关产品推荐

