Issue
Edit: I now accept that the method TreeTableView.getExpandedItemCount()
in fact appears to count all the TreeItem
s currently displayed. This makes this method one of the most egregiously badly named methods I have ever had the misfortune to come across, for incontrovertible reasons stated in my original question, and reiterated in several comments.
A simple tree iterator can be devised to count all the items (regardless of whether showing, or concealed due to one or more ancestors being collapsed) in a TreeTableView
's column0 (the tree column).
But I can't find a way of counting the rows which are "displayed". I say "displayed" rather than "visible" because a tree row can be displayed without necessarily being visible.
I note that there is a method TreeTableView.getExpandedItemCount()
. This doesn't tell you quite what I want to know: you can have a set of leaves, each taking up one row, none of which is expanded. Equally it's possible that these expanded items might include TreeItem
s one or more of whose ancestors is in fact collapsed: just because a TreeItem
is expanded doesn't mean it is displayed.
I also had a look at TreeTableColumn
. I couldn't see anything very obvious there.
The only solution I can think of is supremely inelegant:
// NB TreeIterator is a simple depth-first stack-based iterator
TreeIterator iterator = new TreeIterator(treeTableView.getRoot());
int nRows = 0;
while (iterator.hasNext()) {
TreeItem ti = iterator.next();
int row = treeTableView.getRow( ti );
if( row > nRows ) nRows = row;
}
log.debug( "displayed rows " + nRows );
... there MUST, surely, be something better than that.
Solution
The method TreeTableView.getExpandedItemCount()
gives the number of rows displayed. Before it was realized that this simple solution was on offer, alternative solutions for getting the same thing were found as follows:
private static int getVisibleCellCount(TreeTableView<?> treeTableView) {
TreeTableViewSkin<?> skin = (TreeTableViewSkin<?>) treeTableView.getSkin();
Optional<VirtualFlow> vf = skin.getChildren().stream()
.filter(child -> child instanceof VirtualFlow)
.map(VirtualFlow.class::cast)
.findFirst();
if (vf.isPresent()) {
VirtualFlow<?> virtualFlow = vf.get();
IndexedCell first = virtualFlow.getFirstVisibleCell();
if (first != null) {
return virtualFlow.getCellCount();
}
}
return 0;
}
NOTE: Again, this is not a solution to the real problem. The solution only shows how to get the first cell and last cell in the viewport.
Answered By - Miss Chanandler Bong