我想为tableview实现自定义滚动功能。因此,需要访问可见的行和单元格。
如何检测JavaFX tableview中的可见单元格和行?我还没有在tableview的API描述中找到任何相关信息。
由于
答案 0 :(得分:6)
在TableView中尝试此操作以滚动到所需的行。我已尝试使用table.scrollTo(index),但它没有正确滚动,因为它将所需行设置为第一个可见行。
我已经在我的控制器上编写了下一个代码。
您还可以在此处查看如何获取可见行。
/**
* Used to manually scroll the Table
*/
private TableViewSkin<?> tableSkin;
private VirtualFlow<?> virtualFlow;
@Override
public void initialize(URL location, ResourceBundle resources) {
...
...
Platform.runLater( ()-> { loadVirtualFlow(); });
}
/**
* Loads the actual VirtualFlow
*/
private void loadVirtualFlow(){
tableSkin = (TableViewSkin<?>) tableContent.getSkin();
virtualFlow = (VirtualFlow<?>) tableSkin.getChildren().get(1);
}
/**
* Scrolls the table until the given index is visible
* @param index to be shown
*/
private void scrollTo(int index){
int first = virtualFlow.getFirstVisibleCell().getIndex();
int last = virtualFlow.getLastVisibleCell().getIndex();
if (index <= first){
while (index <= first && virtualFlow.adjustPixels(-1) < 0){
first = virtualFlow.getFirstVisibleCell().getIndex();
}
} else {
while (index >= last && virtualFlow.adjustPixels(1) > 0){
last = virtualFlow.getLastVisibleCell().getIndex();
}
}
}
使用此代码,您可以轻松滚动到所需的索引:
scrollTo(index);
在向列表中添加元素后,请记得在调用scrollTo之前调用 loadVirtualFlow ,这样VirtualFlow就会更新并且不会抛出异常。
答案 1 :(得分:2)
我知道这是一个老问题......无论如何,如果有人需要它:
你可以在没有VirtualFlow的情况下实现它(这是一个私人API,因为&#34;吹嘘鸽子&#34;提及)。只需使用您自己的RowFactory并在创建TableRow对象时将其存储(这里的一些断点或System.out.println()调用可以帮助您快速了解TableView的工作原理。)
在您的控制器类中,创建以下两个字段:
private ArrayList<TableRow<Person>> tblViewPersonsTableRows = new ArrayList<>();
private boolean headerTableRowCreated = false;
...在TableRowFactory中,存储引用...
final TableRow<Person> tableRow = new TableRow<Person>() {
...
}
if (!headerTableRowCreated) {
headerTableRowCreated = true; //the first TableRow corresponds to TableView's header so ignore it
} else {
int myIdx = tblViewPersonsTableRows.size();
tblViewPersonsTableRows.add(tableRow);
}
...现在在需要的地方拨打电话......
double tblViewHeight = fxTblViewPersons.getHeight();
double headerHeight = fxTblViewPersons.lookup(".column-header-background").getBoundsInLocal().getHeight();
double viewPortHeight = tblViewHeight - headerHeight;
for (TableRow tableRow : tblViewPersonsTableRows) {
double minY = tableRow.getBoundsInParent().getMinY();
double maxY = tableRow.getBoundsInParent().getMaxY();
if ((maxY < 0) || (minY > viewPortHeight)) {
//row invisible
} else if ((maxY <= viewPortHeight) && (minY >= 0)) {
tableRow.getStyleClass().add("fullyVisibleRow");
} else {
tableRow.getStyleClass().add("partiallyVisibleRow");
}
}
...... !!!小心 !!!如果您在某个事件处理程序中调用它,数据或排序顺序会发生变化,请检查数据更改前的旧坐标或更改后的新坐标。
如果您使用这样的CSS样式......
.fullyVisibleRow {
-fx-control-inner-background: palegreen;
-fx-accent: derive(-fx-control-inner-background, -40%);
-fx-cell-hover-color: derive(-fx-control-inner-background, -20%);
}
.partiallyVisibleRow {
-fx-control-inner-background: orange;
-fx-accent: derive(-fx-control-inner-background, -40%);
-fx-cell-hover-color: derive(-fx-control-inner-background, -20%);
}
...完全可见的行应为绿色,部分可见的行(在TableView的顶部和底部)应为橙色。我希望这有助于某人。