Как получить доступ к полосам прокрутки области прокрутки
Вопрос
Я пытаюсь получить кое-какую информацию о ScrollBar
компоненты, которые по стандарту входят в состав ScrollPane
.Особенно мне интересно почитать height
из горизонтального Scrollbar
.Как я могу сослаться на это?
Решение
Поскольку упомянутые методы работали не у всех (включая меня), я исследовал это немного подробнее и нашел источник проблемы.
В общем, оба метода работают, но только до тех пор, пока ScrollPane
'с skin
свойство было установлено.В моем случае, skin
был все еще null
после загрузки моего представления с помощью FXMLLoader
.
Путем задержки вызова в случае, если skin
свойство не было инициализировано (использование одноразового прослушивателя) решает проблему.
Код рабочей плиты котла:
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
}
}
}
}
Другие советы
Я думаю, вы можете использовать метод lookupAll() класса Node для поиска полос прокрутки.http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html#lookupAll (java.lang.Строка)
Например:
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());
}
}
}
}
}
Это не самая лучшая практика, но работает,
private boolean determineVerticalSBVisible(final ScrollPane scrollPane) {
try {
final ScrollPaneSkin skin = (ScrollPaneSkin) scrollPane.getSkin();
final Field field = skin.getClass().getDeclaredField("vsb");
field.setAccessible(true);
final ScrollBar scrollBar = (ScrollBar) field.get(skin);
field.setAccessible(false);
return scrollBar.isVisible();
} catch (final Exception e) {
e.printStackTrace();
}
return false;
}
Используйте "hsb" для горизонтальной полосы прокрутки.
С наилучшими пожеланиями, Энрике Гуэдес.