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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:08:21