JavaFX实现TableView单元格点击监听并获取行列信息
解决JavaFX TableView点击单个单元格获取行/列号及数据的问题
我帮你搞定这个问题——要精准获取点击的单个单元格信息,你当前的鼠标事件监听没拿到正确的TableCell(因为event.getSource()返回的是整个TableView,不是被点击的单元格)。下面给你两种靠谱的实现方案,结合你的代码一步步说明:
方案一:给每个TableCell单独绑定点击监听器(推荐)
这种方式更直接,在创建TableColumn时通过cellFactory给每个单元格添加点击事件,能精准拿到当前单元格的所有信息。修改你initTable方法中创建列的代码:
// 以时间列为例,房间列同理 TableColumn<Object, String> timesCol = new TableColumn<>(time); timesCol.setCellValueFactory(createCellValueCallback(i + 1)); timesCol.setSortable(false); // 新增cellFactory,给每个单元格设置点击事件 timesCol.setCellFactory(col -> { TableCell<Object, String> cell = new TableCell<>() { @Override protected void updateItem(String item, boolean empty) { super.updateItem(item, empty); setText(empty || item == null ? null : item); } }; cell.setOnMouseClicked(event -> { // 排除空单元格和非左键点击的情况 if (!cell.isEmpty() && event.getButton() == MouseButton.PRIMARY) { // 获取行号(和你的ArrayList索引直接对应) int rowIndex = cell.getIndex(); // 获取列号(列在TableView中的显示顺序索引) int colIndex = tableView.getColumns().indexOf(col); // 获取单元格数据 String cellData = cell.getItem(); // 映射到你的本地ArrayList集合(假设Runner里的二维集合是Runner.cellDataList) if (rowIndex < Runner.cellDataList.size() && colIndex < Runner.cellDataList.get(rowIndex).size()) { String mappedData = Runner.cellDataList.get(rowIndex).get(colIndex); System.out.println("点击单元格:行" + rowIndex + " 列" + colIndex + " 数据:" + mappedData); // 这里添加你对单元格数据的操作逻辑 } } }); return cell; }); tableView.getColumns().add(timesCol);
方案二:在TableView的全局鼠标事件中定位TableCell
如果你不想给每个列单独设置cellFactory,也可以通过TableView的鼠标事件向上查找被点击的单元格:
修改你现有的tableView.setOnMouseReleased代码:
tableView.setOnMouseClicked(event -> { if (event.getButton() == MouseButton.PRIMARY) { // 从点击目标向上查找,找到对应的TableCell Node target = event.getTarget(); while (target != null && !(target instanceof TableCell)) { target = target.getParent(); } if (target instanceof TableCell<?, ?> cell && !cell.isEmpty()) { // 获取行号 int rowIndex = cell.getIndex(); // 获取列号:先找到单元格所属的列,再取其在TableView中的索引 TableColumn<?, ?> column = cell.getTableColumn(); int colIndex = tableView.getColumns().indexOf(column); // 获取单元格数据 Object cellData = cell.getItem(); // 映射到你的ArrayList集合,逻辑同上 System.out.println("点击单元格:行" + rowIndex + " 列" + colIndex + " 数据:" + cellData); // 执行你的操作逻辑 } } });
关键注意点
- 一定要判断
cell.isEmpty(),避免点击空单元格触发无效事件 - 行索引
cell.getIndex()和你填充TableView的tableView.getItems()索引完全一致,直接对应到你的ArrayList索引即可 - 列索引要和你创建列的顺序对应(比如第一个房间列索引为0,后续时间列从1开始递增)
这样你就能精准拿到被点击单元格的行号、列号和数据,完美映射到本地ArrayList进行操作啦!
内容的提问来源于stack exchange,提问作者Special K
相关产品推荐
相关产品推荐

