How do I get the indices of the visible rows in a TableView in JavaFX 9? In JavaFX 8, I can do the following:
// --- The offending imports in Java 9
// import com.sun.javafx.scene.control.skin.TableViewSkin;
// import com.sun.javafx.scene.control.skin.VirtualFlow;
/**
* This is a total hack. We need it as scrollTo jumps the selected
* row to the top of the table. Jarring if the row is already
* visible. As a workaround, we only scroll if the row isn't already
* visible
*
* @return A 2 element ray with the start and end index of visible rows
*/
public int[] getVisibleRows() {
TableView<?> tableView = getTableView();
TableViewSkin<?> skin = (TableViewSkin<?>) tableView.getSkin();
if (skin == null) return new int[] {0, 0};
VirtualFlow<?> flow = (VirtualFlow<?>) skin.getChildren().get(1);
int idxFirst;
int idxLast;
if (flow != null &&
flow.getFirstVisibleCellWithinViewPort() != null &&
flow.getLastVisibleCellWithinViewPort() != null) {
idxFirst = flow.getFirstVisibleCellWithinViewPort().getIndex();
if (idxFirst > tableView.getItems().size()) {
idxFirst = tableView.getItems().size() - 1;
}
idxLast = flow.getLastVisibleCellWithinViewPort().getIndex();
if (idxLast > tableView.getItems().size()) {
idxLast = tableView.getItems().size() - 1;
}
}
else {
idxFirst = 0;
idxLast = 0;
}
return new int[]{idxFirst, idxLast};
}
In Java 9, as part of the modularization, the JDK team is hiding the API's that weren't meant to be public (e.g. all packages that start with 'com.sun') If I try to compile this in Java 9, I get errors of:
[...] cannot find symbol
[ERROR] symbol: class TableViewSkin
[ERROR] location: package com.sun.javafx.scene.control.skin
[...] cannot find symbol
[ERROR] symbol: class VirtualFlow
[ERROR] location: package com.sun.javafx.scene.control.skin
Is there any official way to get the visible rows in a TableView? Any ideas on another, better workaround for this?
UPDATED: Solution based on @user4712734's solution
TableViewExt<?> tableViewExt = new TableViewExt<>(tableView);
public int[] getVisibleRows() {
return new int[]{ tableViewExt.getFirstVisibleIndex(),
tableViewExt.getLastVisibleIndex()};
}
I had same issue as I was also using the JavaFX 8 specific TableViewSkin/VirtualFlow code, but now use this workaround which wraps up some of the suggestions in another post on this issue - see Tableview visible rows
This workaround runs and compiles in Java8/9 and does not use reference package com.sun.javafx. To use the class you need to create a TableViewExtra between constructing your TableView and adding rows to it:
Then you can call:
You can see the old com.sun.javafx dependencies I once used in comments:
You shall probably migrate to using the module
javafx.controls
which has been introduced since Java9:-which exports the
javafx.scene.control
andjavafx.scene.control.skin
packages as required by the classes in use in your code.