JavaFX的新手,并试图通过row,col索引获取TableView单元格的位置。寻找像Swing的JTable.getCellRect;
我已经看到了需要特定单元格值的情况的解决方案, (JavaFX Simplest way to get cell data using table index)
我还认为只需获取相应行和列的TableCell
,然后获取边界并使用localToScreen
等,但无法找到获取特定方法的方法table-cell
也是如此。
会喜欢任何帮助。 提前致谢
答案 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....
});