Search code examples
javajavafxalignmentfxmlscrollpane

centering content of ScrollPane with fitToWidth=false using JavaFX


Hi I have following situation:

<ScrollPane xmlns:fx="http://javafx.com/fxml" fx:controller="MenuController" fx:id="menuPane" stylesheets="/fxml/styles/menu_style.css" fitToWidth="true" fitToHeight="true" hbarPolicy="ALWAYS" vbarPolicy="ALWAYS">
  <VBox alignment="CENTER">
    <HBox alignment="CENTER">
      <VBox fx:id="menuView">
        <elements></elements>
      </VBox>
    </HBox>
  </VBox>
</ScrollPane>

It looks like this:

Full Screen with alignment

Full Screen with alignment

However when you make it smaller on width scrollpane is not working.

Resized with alignment

Resized with alignment

When I changed value of fitToWidth from true to false I get:

Full screen with scrolling

Full screen with scrolling

so there is no horizontal alignment to center. However scrolling is working:

Resized with scrolling

Resized with scrolling

Is there a possibility to have alignment and scrolling working at the same time?

It is strange that height scrolling and vertical alignment are working properly.

Cannot add more than 2 picture, sorry for that.


Solution

  • When the viewport width is smaller than the content width, then of course the position of the content is determined by the position of the horizontal scroll bar, which is presumably what you want.

    When the viewport width is bigger than the content width, then the position of child node of the content is determined by the layout of the content, and any alignment you set on it. The position of the content itself in the viewport is a function of the viewport's layout, and you have limited control over that (as far as I can see).

    So one option is just to bind the minimum width of the content to the actual width of the viewport, forcing the content to be at least as big as the viewport. You can do this in FXML:

    <ScrollPane xmlns:fx="http://javafx.com/fxml" fx:controller="MenuController" fx:id="menuPane" stylesheets="/fxml/styles/menu_style.css" fitToWidth="true" fitToHeight="true" hbarPolicy="ALWAYS" vbarPolicy="ALWAYS">
      <VBox alignment="CENTER" minWidth="${menuPane.viewportBounds.width}">
        <HBox alignment="CENTER">
          <VBox fx:id="menuView">
            <elements></elements>
          </VBox>
        </HBox>
      </VBox>
    </ScrollPane>