I have a FlowPane wrapped in a ScrollPane. FlowPane orientation is Vertical, so it will wrap the controls. But I want to set the FlowPane to resize vertically if the columns size is greater than the width of ScrollPane. I've tried a lot of settings, both on ScrollPane and FlowPane but none of them helped me with my wish.
As an image of how I want to do is something like this:
(red contur is ScrollPane, green is FlowPane)
Containers, after the flow pane is populated, with ScrollPane's width more than two columns of controls:

How it works right now, after resizing:
How I want to do after resizing the ScrollPane:
Can this be achieved? What settings I must do to both ScrollPane and FlowPane?
Edit:
Minimal reproduction code:
hello-view.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="424.0" prefWidth="457.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.demo.HelloController">
<children>
<AnchorPane layoutX="14.0" layoutY="14.0" prefHeight="399.0" prefWidth="430.0" style="-fx-border-color: #555555;" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
<children>
<ScrollPane fitToHeight="true" fitToWidth="true" focusTraversable="false" hbarPolicy="NEVER" layoutX="14.0" layoutY="13.0" maxWidth="1.7976931348623157E308" prefHeight="377.0" prefWidth="404.0" style="-fx-border-color: red; -fx-border-width: 2;" AnchorPane.bottomAnchor="7.0" AnchorPane.leftAnchor="13.0" AnchorPane.rightAnchor="12.0" AnchorPane.topAnchor="12.0">
<content>
<FlowPane maxWidth="1.7976931348623157E308" orientation="VERTICAL" prefHeight="363.0" prefWidth="397.0" rowValignment="TOP" style="-fx-border-color: green; -fx-border-width: 2;">
<children>
<Button mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="1">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
<Button layoutX="12.0" layoutY="12.0" mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="2">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
<Button layoutX="10.0" layoutY="135.0" mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="3">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
<Button layoutX="154.0" layoutY="10.0" mnemonicParsing="false" prefHeight="121.0" prefWidth="140.0" text="4">
<FlowPane.margin>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</FlowPane.margin>
<font>
<Font name="System Bold" size="24.0" />
</font>
</Button>
</children>
</FlowPane>
</content>
</ScrollPane>
</children>
</AnchorPane>
</children>
</AnchorPane>
HelloController.java:
package com.example.demo;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class HelloController {
@FXML
private Label welcomeText;
@FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to JavaFX Application!");
}
}
HelloApplication.java
package com.example.demo;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
HelloApplication.java and HelloController.java are default demo files from starting project in JavaFX.
Conclusion:
Is there a combination of properties for ScrollPane and FlowPane to be able to resize the FlowPane vertically and stop resizing in the right when the control inside tries to move to create a new column (this happens when ScrollPane resize vertically)? I don't want to create those invisible columns in the right, instead grows the FlowPane vertically!
Mention: this could happens in two way
- when resize form from the bottom, and the controls from the bottom of the
FlowPanewill move to the top, and theFlowPanewill resize automatically to the right and put the controls in the hidden area ofFlowPane, (and) - When you resize form horizontally and there is no more space to move the controls from the right column to the next row, so the
FlowPanewill not stay anchored to right and to try to create an "invisible" row (or as many as it takes to move needed controls down).
I hope I make it clear as possible.


This answer I found it myself and it works only for
FlowPanecontaining controls with the same size.Purpose: Allow user to populate a
FlowPaneinVerticalorientation, with parentScrollPane's scrollbars set only to vertical scrollbar visible (when needed) and theFlowPanewidth to fitScrollPane's width always.Starting from a demo project in JavaFX, this is the fxml file which contains definition for the main-view (hello-view.fxml in this case).
hello-view.fxmlfile:HelloController.javafile:HelloApplication.javafile:The approach was to wrap the
FlowPanein aAnchorPane.FlowPaneis anchored inAnchorPaneto all bounds. TheAnchorPaneis wrapped inScrollPane.In controller I've created a public method in which I added listners to
widthProperty()andheightProperty()ofScrollPaneto be able to calculate the rows needed for resizing theAnchorPane, based on how many items are inFlowPaneand how many columns could be made with theScrollPane's width. This method was added because size of controls must be read after the scene is displayed, which I've done it inHelloApplication.javamain class. In this way listners are added after all items are displayed, and it will be calculated correctly.Demo: