Issue
I have a ScrollPane as below:
ScrollPane scroller = new ScrollPane();
scroller.getStyleClass().add("scroller");
scroller.setPrefWidth(width);
scroller.setFocusTraversable(Boolean.FALSE);
scroller.setPannable(Boolean.TRUE);
scroller.setFitToWidth(Boolean.TRUE);
scroller.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scroller.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
this.setCenter(scroller);
scroller.contentProperty().addListener((observableValue, last, now) ->
{
ScrollBar scrollBar = (ScrollBar) scroller.lookup(".scroll-bar:vertical");
if (scrollBar != null)
{
if (scrollBar.isVisible())
{
log.info("Scrollbar visible, setting lower card width..");
}
else
{
log.info("Scrollbar not visible, setting default card width..");
}
}
});
As you can see I've attached a listener to the content property to know when the content is set. I am trying to see if the scrollbar is visible when the content is updated. Even though I can see the scroll bar on the UI, it always goes to else part - "Scrollbar not visible".
Not sure if there is any other way to do this? Checked a lot on StackOverflow and Oracle docs - nothing solid found to suggest otherwise.
-- Adding context to the problem to better understand:
Just trying to explain what the problem is not sure if I should put it as a reply comment or edit the question, please advise and will change it:
So I have this view that brings up records from Firebase that need to be loaded on the TilePane that is hosted in ScrollPane which goes into the Center of the BorderPane.
The time by which I get the response from the Firebase is unpredictable as its async. So the UI gets loaded up with the empty TilePane and then the async call goes to fetch data. When the data is available, I need to prepare Cards (which is HBox) but the number of columns is fixed. So have to adjust the width of the cards to keep the gap (16px) and padding (16px) consistent on the TilePane at the same time maintain 5 columns. The width of each card needs to be recalculated based on the fact that whether or not there is a scrollbar on the display. Because if the scrollbar is displayed it takes some space and the TilePane will down it to 4 columns leaving a lot of empty space. Happy to explain further if this is not clear.
Solution
As @James_D said, used GridPane and it worked without any listeners:
GridPane cards = new GridPane();
cards.setVgap(16);
cards.setHgap(16);
cards.setAlignment(Pos.CENTER);
cards.setPadding(new Insets(16));
ColumnConstraints constraints = new ColumnConstraints();
constraints.setPercentWidth(20);
constraints.setHgrow(Priority.ALWAYS);
constraints.setFillWidth(Boolean.TRUE);
cards.getColumnConstraints().addAll(constraints, constraints, constraints, constraints, constraints);
I have 5 columns, so 5 times constraints. Worked just fine.
Answered By - arun
Answer Checked By - Robin (JavaFixing Admin)