I know this is an old question... anyway, should someone need it:
You can achieve it without VirtualFlow (which is a private API as "purring pigeon" mentions). Just use your own RowFactory and store the references to the TableRow objects as they're being created (some breakpoints or System.out.println() calls here can help quickly understand, how TableView works).
In your controller class, create these two fields:
private ArrayList<TableRow<Person>> tblViewPersonsTableRows = new ArrayList<>();
private boolean headerTableRowCreated = false;
... in the TableRowFactory, store the references...
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);
}
... now call this where you need it ...
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");
}
}
... !!! BE CAREFUL !!! if you're calling it in some event handler, where the data or the sort order changes, check whether you get the old coordinates before the data changes or the new ones after the change.
If you use css styles like this...
.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%);
}
... the fully visible rows should be green and the partially visible ones (at the top and bottom of the TableView) orange. I hope this helps someone.