I'm trying to get some information about the ScrollBar
components that are by standard included in a ScrollPane
. Especially i'm interested in reading the height
of the horizontal Scrollbar
. How can i reference it?
Click Start > Settings. Under Windows Settings, scroll down, and then click Ease of Access > Display. Scroll down, and then set Automatically hide scroll bars in Windows to Off.
A standard scroll bar is located in the nonclient area of a window. It is created with the window and displayed when the window is displayed. The sole purpose of a standard scroll bar is to enable the user to generate scrolling requests for viewing the entire content of the client area.
By setting to 100vw we eliminate the width of the scrollbar on any platform.
I think you can use the lookupAll() method of the Node class for find the scroll bars. http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html#lookupAll(java.lang.String)
For example:
package com.test;
import java.util.Set;
import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPaneBuilder;
import javafx.scene.text.Text;
import javafx.scene.text.TextBuilder;
import javafx.stage.Stage;
public class JavaFxScrollPaneTest extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
String longString = "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.";
Text longText = TextBuilder.create().text(longString).build();
ScrollPane scrollPane = ScrollPaneBuilder.create().content(longText).build();
primaryStage.setScene(new Scene(scrollPane, 400, 100));
primaryStage.show();
Set<Node> nodes = scrollPane.lookupAll(".scroll-bar");
for (final Node node : nodes) {
if (node instanceof ScrollBar) {
ScrollBar sb = (ScrollBar) node;
if (sb.getOrientation() == Orientation.HORIZONTAL) {
System.out.println("horizontal scrollbar visible = " + sb.isVisible());
System.out.println("width = " + sb.getWidth());
System.out.println("height = " + sb.getHeight());
}
}
}
}
}
Since the mentioned methods did not work for everybody (including me), I investigated it a bit more and found the source of the problem.
In general, both methods work, but only as soon as the ScrollPane
's skin
property has been set. In my case, skin
was still null
after loading my view using FXMLLoader
.
By delaying the call in case the skin
property has not been initialized (using a one-shot listener) solves the problem.
Working boiler-plate code:
ScrollPane scrollPane;
// ...
if (scrollPane.getSkin() == null) {
// Skin is not yet attached, wait until skin is attached to access the scroll bars
ChangeListener<Skin<?>> skinChangeListener = new ChangeListener<Skin<?>>() {
@Override
public void changed(ObservableValue<? extends Skin<?>> observable, Skin<?> oldValue, Skin<?> newValue) {
scrollPane.skinProperty().removeListener(this);
accessScrollBar(scrollPane);
}
};
scrollPane.skinProperty().addListener(skinChangeListener);
} else {
// Skin is already attached, just access the scroll bars
accessScrollBar(scrollPane);
}
private void accessScrollBar(ScrollPane scrollPane) {
for (Node node : scrollPane.lookupAll(".scroll-bar")) {
if (node instanceof ScrollBar) {
ScrollBar scrollBar = (ScrollBar) node;
if (scrollBar.getOrientation() == Orientation.HORIZONTAL) {
// Do something with the horizontal scroll bar
// Example 1: Print scrollbar height
// System.out.println(scrollBar.heightProperty().get());
// Example 2: Listen to visibility changes
// scrollBar.visibleProperty().addListener((observable, oldValue, newValue) -> {
// if(newValue) {
// // Do something when scrollbar gets visible
// } else {
// // Do something when scrollbar gets hidden
// }
// });
}
if (scrollBar.getOrientation() == Orientation.VERTICAL) {
// Do something with the vertical scroll bar
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With