Brent Allard
Brent Allard

Reputation: 396

JavaFX ScrollPane [ setPrefSize, setMinSize, setMaxSize ] not working

I'm writing a GUI application with a ScrollPane, but had some issues with resizing. I extracted the essential code in the following example:

import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import javafx.scene.layout.VBox;
import javafx.scene.control.ScrollPane;

public class JavaFXExample extends Application {

    final int width = 300;
    final int height = 300;

    @Override
    public void start(Stage primaryStage) {

        Button b = new Button("This should be at the bottom!");

        //this vbox goes inside the scrollpane
        VBox boxInScrollPane = new VBox(10);
        boxInScrollPane.setAlignment(Pos.BOTTOM_CENTER);
        boxInScrollPane.getChildren().add(b);

        //main content
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setContent(boxInScrollPane);
        scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);

        //Doesn't do anything!
        scrollPane.setPrefSize(100, 100);
        scrollPane.setMaxSize(100, 100);
        scrollPane.setMinSize(100, 100);

        Scene scene = new Scene(scrollPane, width, height);

        primaryStage.setScene(scene);
        primaryStage.show();


        //set size of boxInScrollPane to be equal to the viewport
        Bounds viewportBounds = scrollPane.getViewportBounds();
        double innerWidth = viewportBounds.getMaxX() - viewportBounds.getMinX();
        double innerHeight = viewportBounds.getMaxY() - viewportBounds.getMinY();
        System.out.println(innerWidth + " " + innerHeight);
        boxInScrollPane.setPrefSize(innerWidth, innerHeight);

    }

    public static void main(String[] args) {
        launch(args);
    }

}

So I have a window, which contains a ScrollPane, which contains a VBox, which contains a button. The example here, where I resize the scrollpane to be 100x100px in a 300x300px window, is arbitrary. What's important is that when I run this code, I get a scrollpane that fills the entire window! Here's my output:

What's going on here?

Upvotes: 0

Views: 1238

Answers (2)

James_D
James_D

Reputation: 209235

The root of the scene is sized to fill the entire scene, irrespective of its min/pref/max size. If you want the ScrollPane to remain 100 pixels wide and 100 pixels high, wrap it in another container (pretty much any container will do); the container will then be resized, but the ScrollPane will respect its layout sizes:

Scene scene = new Scene(new StackPane(scrollPane), width, height);

By default a StackPane centers its content, so this results in

enter image description here

Upvotes: 1

pr0gramista
pr0gramista

Reputation: 9008

Solution:

Pane pane = new Pane(scrollPane);
Scene scene = new Scene(pane, width, height);

primaryStage.setScene(scene);

primaryStage.show();

From Scene constuctor doc:

Creates a Scene for a specific root Node with a specific size.

Setting ScrollPane as root node will make it resize to given size in constructor so the previous settings will not work.

Solution will be to make a simple pane that will be resized so ScrollPane will be on his own rules.

Upvotes: 1

Related Questions