ScrollPane is not displayed if necessary, the contents of FlowPane

I'm having difficulty with ScrollPane in JavaFX 8, showing the scroll bar as needed. What I'm doing now is just to create a FlowPane with the number of elements x and set this as the contents of the ScrollPane.

The problem occurs when I compress perpendicular to the orientation of the FlowPane. When items begin to flow around and go out of bounds, the scroll bar does not appear. This does not happen when I cut parallel to the orientation. I have a small Java program to illustrate the problem.

Start

Contraction reduction

Perpendicular contraction

Reduction of perpendicularity Reducing Parallel Exaggeration

import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.ScrollPane; import javafx.scene.layout.FlowPane; import javafx.scene.layout.StackPane; import javafx.stage.Stage; public class Main extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) throws Exception { FlowPane flow = new FlowPane(); flow.setStyle("-fx-border-color: red"); addPanes(flow, 16); ScrollPane scroll = new ScrollPane(flow); scroll.setStyle("-fx-border-color: green"); scroll.setFitToHeight(true); scroll.setFitToWidth(true); Scene scene = new Scene(scroll, 450, 450); primaryStage.setScene(scene); primaryStage.show(); } public void addPanes(FlowPane root, int panes) { for(int i = 0; i < panes; i++) { StackPane filler = new StackPane(); filler.setStyle("-fx-border-color: black"); filler.setPrefSize(100, 100); root.getChildren().add(filler); } } } 
+6
source share
3 answers

Take a look at the code below and tell me what you want to achieve. I'm still not sure what the problem is, I will have to look at the ScrollPane documentation to find out. My suspicion is in the setFitToWidth and setFitToHeight . Although I still believe that this is not a mistake.

 import javafx.application.Application; import javafx.beans.binding.Bindings; import javafx.scene.Scene; import javafx.scene.control.ScrollPane; import javafx.scene.layout.FlowPane; import javafx.scene.layout.HBox; import javafx.stage.Stage; public class Main extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) throws Exception { FlowPane flow = new FlowPane(); flow.setStyle("-fx-border-color: red"); addPanes(flow, 16); ScrollPane scroll = new ScrollPane(flow); scroll.setStyle("-fx-border-color: green"); // Apparently this cause the issue here. // scroll.setFitToHeight(true); // scroll.setFitToWidth(true); // Instead just make the flow pane take the dimensions of the ScrollPane // the -5 is to not show the Bars when both of panes have the same dimensions flow.prefWidthProperty().bind(Bindings.add(-5, scroll.widthProperty())); flow.prefHeightProperty().bind(Bindings.add(-5, scroll.heightProperty())); Scene scene = new Scene(scroll, 450, 450); primaryStage.setScene(scene); primaryStage.show(); } public void addPanes(FlowPane root, int panes) { for (int i = 0; i < panes; i++) { HBox filler = new HBox(); filler.setStyle("-fx-border-color: black"); filler.setPrefSize(100, 100); root.getChildren().add(filler); } } } 

Looking at the ScrollPane documentation, and in particular setFitToHeight you will find that:

Object Description: If true and if the contained node is resized, then the size of the node will be resized to match the height of the ScrollPane viewport. If the contained node is not Resizable, this value is ignored.

And since the node inside the ScrollPane will be resized to fit the width and height of the ScrollPane viewport, so the Vertical ScrollBar will never appear.

+2
source

You can add the code below to always show your vertical scrollbar.

 scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS); 
+1
source

When the required FlowPane height inside the ScrollPane is calculated, a width value of -1 is passed. Then the flow panel will report the required height when all its contents fit on one line.

As a workaround, you can pass the width from the last layout calculation in this case.

 import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.ScrollPane; import javafx.scene.layout.FlowPane; import javafx.scene.layout.StackPane; import javafx.stage.Stage; public class Main extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) throws Exception { FlowPane flow = new FlowPane() { @Override protected double computeMinHeight(double width) { double minHeight = super.computeMinHeight(width != -1 ? width : /* When no width is specified, use the current contol size*/ getWidth()); return minHeight; } }; flow.setStyle("-fx-border-color: red"); addPanes(flow, 16); ScrollPane scroll = new ScrollPane(flow); flow.maxWidthProperty().bind(scroll.widthProperty()); scroll.widthProperty().addListener((observable, oldValue, newValue)->{ /* clearSizeCache */ flow.requestLayout(); }); scroll.setStyle("-fx-border-color: green"); scroll.setFitToHeight(true); scroll.setFitToWidth(true); Scene scene = new Scene(scroll, 450, 450); primaryStage.setScene(scene); primaryStage.show(); } public void addPanes(FlowPane root, int panes) { for(int i = 0; i < panes; i++) { StackPane filler = new StackPane(); filler.setStyle("-fx-border-color: black"); filler.setPrefSize(100, 100); root.getChildren().add(filler); } } } 
0
source

Source: https://habr.com/ru/post/1273094/


All Articles