JavaFX表格选择单元格时高亮所在行功能实现

本文介绍了如何在JavaFX中实现在表格选择单元格时高亮显示所在行的功能。通过自定义TableCell,监听RowIndex变化及表格选择事件,判断并设置单元格背景色,解决点击单元格无法立即更新高亮的问题。此外,提供的MapTable类还支持拖动选择和CTRL+C复制单元格内容。
摘要由CSDN通过智能技术生成

使用JavaFX表格进行数据展示时,想要将当前所选择的单元格所在的行进行高亮,经过研究,实现方案见下文。
主要的思路:为Table定制TableCell,在TableCell中的RowIndex发生变更后,检查Cell所在行是否被选中,根据是否选中来设置单元格的背景色。
但按这种方式有一个问题,TableCell的RowIndex时,一般只有表格的数据发生变化的时候才会变更,如果直接在监听RowIndex的变更事件,并在其中进行处理,实际上点击某个单元格的时候是不会触发这部分处理逻辑的。很自然的,又想到监听表格的选择事件发生后去进行检查并处理,但矛盾的是,在表格的点击事件中又没法修改所选择的TableCell的背景色。
最终采取了一种折中的方式:在RowIndex变更事件中,对表格的选择事件进行监听,判断选择行中是否包含有当前Cell所在的行,根据检查结果设置单元格背景色。
关键代码如下(其中MapTable是继承自TableView的一个子类):

public class DragSelectionCell extends TextFieldTableCell<Map<String, Object>, String> {
   
        public DragSelectionCell() {
   
            super(new DefaultStringConverter());

            setOnDragDetected(e -> {
   
                startFullDrag();
                startRow.setValue(getIndex());
                startCol.setValue(getTableColumn());
            });
            setOnMouseDragEntered(event -> {
   
                endRow.setValue(getIndex());
                endCol.setValue(getTableColumn());

                getTableView().getSelectionModel().clearSelection();
                getTableView().getSelectionModel().selectRange(startRow.getValue(), startCol.getValue(), endRow.getValue(), endCol.getValue());
            });

            // 对行的index进行监听,如果index发生变更,则监听表格的选择事件,当选择的行发生变化时,修改当前行的背景色
            this.tableRowProperty().addListener((observable, oldValue, newValue) ->
                    MapTable.this.getSelectionModel().getSelectedCells().addListener((ListChangeListener<? super TablePosition>) l -> {
   
                        ObservableList<? extends TablePosition> list = l.getList();
                        List<Integer> rowList = list.stream().map(TablePosition::getRow).collect(Collectors.toList());
                        if (rowList.contains(newValue.getIndex())) {
   
                            if (this.isSelected()) {
   
                                this.setBackground(new Background(new BackgroundFill(Color.valueOf("#0C739F"), null, null)));
                            } else {
   
                                this.setBackground(new Background(new BackgroundFill(Color.LIGHTGRAY, null, null)));
                            }
                        } else {
   
                            this.setBackground(null);
                        }
                    }));
        }
    }

然后在MapTable中,创建列的时候指定新列的TableCell:

private TableColumn<Map<String, Object>, String> createColumn(String title, double prefWidth, double maxWidth) {
   
        TableColumn<Map<String, Object>, String> tableColumn = new TableColumn<>(title);
        tableColumn.setCellValueFactory
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值