获取JavaFX中tableview单元的位置

时间:2017-09-11 14:23:06

标签: java javafx javafx-8

JavaFX的新手,并试图通过row,col索引获取TableView单元格的位置。寻找像Swing的JTable.getCellRect;

之类的东西

我已经看到了需要特定单元格值的情况的解决方案, (JavaFX Simplest way to get cell data using table index

我还认为只需获取相应行和列的TableCell,然后获取边界并使用localToScreen等,但无法找到获取特定方法的方法table-cell也是如此。

会喜欢任何帮助。 提前致谢

1 个答案:

答案 0 :(得分:2)

根据设计,在JavaFX中没有直接的方法可以做到这一点。由于单元格仅为当前可见的数据创建,并且可以重复使用(例如,当用户在表格中滚动时),因此不存在任何给定单元格与&之间的关系,甚至是一致的关系。 #34;位置"在表格的支持数据中。因此,您甚至不应该尝试为给定的数据项找到一个单元格,并且应该尝试找到您尝试执行的任何操作的另一种方法。

(从MVC设计方法来看,这也是有道理的:你要求从模型(数据)中找到 view (单元格);模型应该完全不知道视图。)

如果你真的想尝试这个(并且,如果它不清楚,我认为你应该找到另一种方法),你可以尝试使用某些东西跟踪每个位置的细胞。如下:

TableView<SomeDataType> table = new TableView<>();

Map<TableColumn<SomeDataType, ?>, Map<Number, TableCell<SomeDataType, ?>>> cells = new HashMap<>();

TableColumn<SomeDataType, SomeColumnDataType> column = new TableColumn<>(...);
cells.put(column, new HashMap<>();

column.setCellValueFactory(...);

column.setCellFactory(tc -> {
    TableCell<SomeDataType, SomeColumnDataType> cell = new TableCell<SomeDataType, SomeColumnDataType>() {
        @Override
        protected void updateItem(SomeColumnDataType item, boolean empty) {
            super.updateItem(item, empty) ;
            if (empty) {
                setText(null);
            } else {
                setText(item.toString());
            }
        }
    };

    cell.indexProperty().addListener((obs, oldIndex, newIndex) -> {
        if (oldIndex != null) {
            cells.get(column).remove(oldIndex);
        }
        if (newIndex != null && newIndex.intValue() != -1) {
            cells.get(column).put(newIndex, cell);
        }
    });

    return cell ;
});

// repeat for other columns...

然后你可以做

TableCell<SomeDataType, ?> cell = cells.get(someColumn).get(someIndex);

获取特定列和行索引的单元格。请注意,您需要检查null(如果该数据当前没有单元格)。

这可能需要非常仔细的调试,但这种方法应该有效。

更新:我使用这种技术制作了一个SSCCE here

你也可以通过查找来尝试。查找不是很强大,并且在CSS应用到场景图之前根本不起作用,但你可以尝试这样的事情:

TableColumn<...> columnOfInterest = ... ;
int rowIndexOfInterest = ... ;

TableCell<?, ?> cell = null ;
for (Node n : table.lookupAll(".table-cell")) {
    TableCell<?,?> c = (TableCell<?,?>) n ;
    if (c.getTableColumn() == columnOfInterest 
            && c.getIndex() == rowIndexOfInterest) {
        cell = c ;
        break ;
    }
}

if (cell != null) {
    // ...
}

或更多Java 8方法:

table.lookupAll(".table-cell").stream()
    .map(TableCell.class::cast)
    .filter(c -> c.getTableColumn() == columnOfInterest && c.getIndex() == rowIndexOfInterest)
    .findAny()
    .ifPresent(cell -> {
        // do whatever you need with the cell....
    });