Reputation: 490
The main scene of my application uses a VBox layout and contains a scrollpane. The scrollpane within the VBox layout won't visually change width despite the value being changed using the setPrefViewportWidth method:
VBox mainLayout = new VBox(50);
ScrollPane activityPane = new ScrollPane(new Label("TEST"));
activityPane.setPrefViewportWidth(100); //Width stays the same visually
activityPane.setPrefViewportHeight(50); //Height changes fine
As you can see the width of the scrollpane is equivalent to that of the window which is much greater than what it should be. What can I do to force the scrollpane to take on a specific width?
Upvotes: 1
Views: 1083
Reputation: 159546
Most JavaFX elements are resizable by default.
If you don't want the scroll pane to grow beyond its preferred size, then tell it not to do that.
scrollPane.setMaxWidth(ScrollPane.USE_PREF_SIZE);
Further explanation, if required
Note this is setting a constraint on the maximum width of the entire scroll pane control (including decorations like borders and scrollbars), not just the viewport inside the scroll pane.
JavaFX layout implementations will compute and use the preferred size of the entire scroll pane based on the preferred size of the scroll pane viewport which have you set. When computing the preferred size, the default layout for ScrollPane will also include the additional space for rendering the decorations.
By limiting the max size to the preferred size, then the scroll pane can shrink as needed, but will never grow beyond the preferred size. If you wanted to stop it shrinking, then you could also set the min size to use the preferred size. You can do the same for the height too, in case you place it in a layout pane other than a VBox.
By default, VBox only resizes children vertically if you tell it that it may do so, e.g. by setting Vgrow priority: VBox.setVgrow(scrollPane, Priority.ALWAYS);
(try the example with this line uncommented to see the difference it makes). But it will always try to resize elements horizontally to fill available space. This is why in your example you were seeing the scroll pane get resized horizontally, but not vertically.
If you want an exact width that won't resize (e.g. it is always 200 pixels wide no matter what), then you can do something like:
scrollPane.setPrefWidth(200);
scrollPane.setMaxWidth(ScrollPane.USE_PREF_SIZE);
scrollPane.setMinWidth(ScrollPane.USE_PREF_SIZE);
Similarly for height.
This info on resizing applies across most JavaFX controls (buttons are a little different because by default they don't resize beyond their preferred size unless you set the maximum width and height to something like Double.MAX_VALUE
);
Executable example
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class RestrictedWidthScrollPaneDemo extends Application {
@Override
public void start(Stage stage) {
ScrollPane scrollPane = new ScrollPane(new Label("TEST"));
scrollPane.setPrefViewportWidth(100);
scrollPane.setPrefViewportHeight(50);
scrollPane.setMaxWidth(ScrollPane.USE_PREF_SIZE);
VBox layout = new VBox(scrollPane);
// VBox.setVgrow(scrollPane, Priority.ALWAYS);
stage.setScene(new Scene(layout, 200, 100));
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Upvotes: 3