Reputation: 107
How can you change the width of a ScrollBar
from a ScrollPane
to a certain value of px? I looked at JavaFX 2.1 Change ScrollPane Scrollbar size but simply setting the font size to X px doesn't seem to work properly. I did some tests with big values and the width wasn't what I set it to be (ex: for a value of 50px the ScrollBar had width of 56px, for a value of 88px it had width of 96px, for a value of 40px it had width of 44px, for a value of 30px it had width of 33px, so no relation between then).
I need a solution that works from java code and not from a CSS
file as I need to be able to dynamically set the value.
There were other suggestions to use .lookupAll
but from what I understand you should avoid using that.
Code for setting width and colors:
scrollPane.setStyle("colorScrollBar: rgba(" + A function that returns RBGA + ");"
+ " colorScrollBarButton: rgba(" + A function that returns RBGA + ");"
+ " -fx-font-size: " + 30 + "px;");
Here is the CSS
file I used to change the ScrollBar (to make it transparent, to change the colors and remove some margins):
.scroll-bar {
-fx-background-color: colorScrollBar;
-fx-background-insets: 0;
-fx-padding: 0;
}
.scroll-bar .thumb {
-fx-background-color: colorScrollBarButton;
}
.scroll-bar > .increment-button > .increment-arrow,
.scroll-bar > .decrement-button > .decrement-arrow {
-fx-background-color: colorScrollBarButton;
}
.scroll-bar > .increment-button:hover,
.scroll-bar > .decrement-button:hover {
-fx-background-color: colorScrollBar;
}
.scroll-pane > .viewport {
-fx-background-color: transparent;
}
.scroll-pane {
-fx-background-color: transparent;
-fx-background-insets: 0;
-fx-padding: 0;
}
.scroll-pane:focused {
-fx-background-insets: 0;
-fx-padding: 0;
}
.scroll-pane .corner {
-fx-background-insets: 0;
-fx-padding: 0;
}
Upvotes: 0
Views: 914
Reputation: 67
Been struggling with this problem for some time, found an answer
You can add listener to your scrollPane's children, and set the widths to your scrollBars as they appear:
ScrollPane scrollPane = new ScrollPane(pane);
scrollPane.getChildrenUnmodifiable().addListener(new ListChangeListener<Node>() {
@Override
public void onChanged(Change<? extends Node> c) {
while (c.next()) {
if (c.wasAdded()) {
c.getAddedSubList().forEach(n -> {
if (n instanceof ScrollBar) {
ScrollBar bar = (ScrollBar) n;
bar.setPrefWidth(30); //set what you need
}
});
}
}
}
});
PS Sorry for necroposting
Upvotes: 0
Reputation: 2723
Once in the Scene
, you can query the ScrollBar
s using:
ScrollBar vsb = (ScrollBar) scrollPane.queryAccessibleAttribute(
AccessibleAttribute.VERTICAL_SCROLLBAR);
ScrollBar hsb = (ScrollBar) scrollPane.queryAccessibleAttribute(
AccessibleAttribute.HORIZONTAL_SCROLLBAR);
vsb.setPrefWidth(40);
hsb.setPrefHeight(40);
Upvotes: 0
Reputation: 4390
This works for me.
private ScrollPane scrollPane;
@Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Circle content = new Circle(2000);
scrollPane = new ScrollPane(content);
Slider sizeSldr = new Slider(8, 80, 14);
root.setTop(sizeSldr);
root.setCenter(scrollPane);
sizeSldr.valueProperty().addListener((observable, oldValue, newValue) -> {
setScrollBarWidth(newValue.doubleValue());
});
Scene scene = new Scene(root, 800, 600);
primaryStage.setTitle("ScrollBar Width");
primaryStage.setScene(scene);
primaryStage.show();
}
void setScrollBarWidth(double width) {
scrollPane.setStyle("-fx-font-size: %3.3fpx".formatted(width));
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 2
Reputation: 107
The solution I came with is to create a custom ScrollBar
and use that to scroll the ScrollPane
. Here is an example how to create one and bind it to the ScrollPane
:
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(paneElements); //The pane that will have the nodes
scrollPane.setLayoutX(20);
scrollPane.setLayoutY(20);
scrollPane.setPrefWidth(stage.getWidth() - 40); //This was my use case, do what you need here
scrollPane.setPrefHeight(stage.getHeight() - 66); //This was my use case, do what you need here
scrollPane.setHbarPolicy(ScrollBarPolicy.NEVER);
scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER);
scrollPane.setStyle("colorScrollBar: rgba(" + I am using a function that returns RGBA + ");"
+ " colorScrollBarButton: rgba(" + I am using a function that returns RGBA + ");");
pane.getChildren().add(scrollPane);
ScrollBar scrollBarVertical = new ScrollBar();
scrollBarVertical.setLayoutX(stage.getWidth() - 20)); //Use what you need
scrollBarVertical.setLayoutY(20); //Use what you need
scrollBarVertical.setPrefHeight(stage.getHeight() - 66); //Use what you need
scrollBarVertical.setMinWidth(0); //I set it to 0 because if you need to use low values, it wasn't using values lower then 16 in prefWidth in my case
scrollBarVertical.setPrefWidth(prefWidth * 0.75)); //Use what you need
scrollBarVertical.setOrientation(Orientation.VERTICAL);
scrollBarVertical.setMin(scrollPane.getVmin());
scrollBarVertical.setMax(scrollPane.getVmax());
scrollBarVertical.valueProperty().bindBidirectional(scrollPane.vvalueProperty());
scrollBarVertical.setStyle("colorScrollBar: rgba(" + I am using a function that returns RGBA + ");"
+ " colorScrollBarButton: rgba(" + I am using a function that returns RGBA + ");");
pane.getChildren().add(scrollBarVertical);
Upvotes: 0