java 如何访问 ScrollPane 的滚动条

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12678317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 09:48:41  来源:igfitidea点击:

How to access the Scrollbars of a ScrollPane

javajavafxjavafx-8javafx-2

提问by dajood

I'm trying to get some information about the ScrollBarcomponents that are by standard included in a ScrollPane. Especially i'm interested in reading the heightof the horizontal Scrollbar. How can i reference it?

我正在尝试获取有关ScrollBar包含在ScrollPane. 尤其是我对阅读height水平的感兴趣Scrollbar。我怎样才能参考它?

采纳答案by Markus Weninger

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 skinproperty has been set. In my case, skinwas still nullafter loading my view using FXMLLoader.

通常,这两种方法都有效,但只有在设置了ScrollPaneskin属性后才有效。就我而言,skinnull使用FXMLLoader.

By delaying the call in case the skinproperty has not been initialized (using a one-shot listener) solves the problem.

通过在skin属性尚未初始化的情况下延迟调用(使用一次性侦听器)解决了问题。

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
            }

        }
    }
}

回答by ytw

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)

我认为您可以使用 Node 类的 lookupAll() 方法来查找滚动条。 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());
                }
            }
        }
    }
}

回答by Guedolino

This not is the best pratice, but works,

这不是最好的做法,但有效,

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;
}

Use "hsb" for Horizontal ScrollBar.

使用“hsb”作为水平滚动条。

Best Regards, Henrique Guedes.

最好的问候, Henrique Guedes。