How to know if a scroll bar is visible on a JavaFx TableView


Question

Is there a way to know if a scroll bar is present on a table view? (Other than what I did in my code below) My goal is to position 2 arrow images (to close/open a side panel) on the right side of a table (over the table.). But I don't want to put them over the scroll bar. The table content is a result of a search, so sometime the scroll bar is visible and other time it is not. If there is not enough items. I want the position of my arrows to change every time the tableview items change.

I already try the following solution, but the result is that the arrows are moved the second time I do the search. Looks like a concurrency problem. Like if my listener code is executed before the table is rendered.

Is there a way to solve that?

tableView.getItems().addListener( (ListChangeListener<LogData>) c -> {    
// Check if scroll bar is visible on the table
// And if yes, move the arrow images to not be over the scroll bar
Double lScrollBarWidth = null;
Set<Node> nodes = tableView.lookupAll( ".scroll-bar" );
for ( final Node node : nodes )
{
    if ( node instanceof ScrollBar )
    {
        ScrollBar sb = (ScrollBar) node;
        if ( sb.getOrientation() == Orientation.VERTICAL )
        {
            LOGGER.debug( "Scroll bar visible : {}", sb.isVisible() );
            if ( sb.isVisible() )
            {
                lScrollBarWidth = sb.getWidth();
            }
        }
    }
}

if ( lLogDataList.size() > 0 && lScrollBarWidth != null )
{
    LOGGER.debug( "Must move the arrows images" );
    tableViewController.setArrowsDistanceFromRightTo( lScrollBarWidth );
}
else
{
    tableViewController.setArrowsDistanceFromRightTo( 0d );
}} );
1
4
7/17/2014 5:46:09 PM

I assume you know that it is not a good idea to rely on the internal implementation of TableView. Having said that, you're code looks mostly good (I did a similar thing for an infinite scrolling example).

However you should also consider the case that the scrollbar may appear due to the main window changing its size.

I would therefore suggest you listen to changes in the visibilty-property of the scrollbar.

private ScrollBar getVerticalScrollbar() {
    ScrollBar result = null;
    for (Node n : table.lookupAll(".scroll-bar")) {
        if (n instanceof ScrollBar) {
            ScrollBar bar = (ScrollBar) n;
            if (bar.getOrientation().equals(Orientation.VERTICAL)) {
                result = bar;
            }
        }
    }       
    return result;
}
...
bar.visibleProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {  
      // tableViewController.setArrowsDistanceFromRightTo(...)
    }
);
2
2/24/2016 6:31:14 AM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon