在ListView中收听ScrollBar更改

时间:2013-06-05 10:25:21

标签: java listview javafx javafx-2

我正在尝试收听列表视图的滚动条更改。我的第一次尝试就是这样做

listView.setOnScroll(new EventHandler<ScrollEvent>()
{ // Code ommited }

然而它似乎没有用。我尝试使用调试器,发现没有调用EventHandler中的handle方法。

我已经搜索了其他解决方案并找到了这个(https://gist.github.com/jewelsea/1684622),但是如果我将每个循环移动到primaryStage.show()之前的位置,它就不起作用。所以这个不是我的用例的理想解决方案,因为我将我的UI代码拆分成许多子组件,我需要在调用primaryStage.show()之前设置监听器(我不会暴露listview实例)到主要的Application类)。

我认为问题是因为只有节点已经在舞台上显示时,lookUpAll方法才有效。我想到了一些解决方法,例如在一个方法中执行foreach循环,该方法将在节点完全附加到场景图之后执行并显示在屏幕上,但我仍然不知道如何实现此

谢谢。

1 个答案:

答案 0 :(得分:3)

假设您将Stage传递给创建ListView的方法,您可以使用onShown事件来执行将侦听器附加到滚动条的代码。基本上使用监听器来设置其他监听器。例如:

    ObservableList<String> names = FXCollections.observableArrayList("1","2","3","4","5","6","7");
    final ListView<String> listView = new ListView<String>(names);

    stage.setOnShown(new EventHandler<WindowEvent>(){
        boolean hasRun = false;
        @Override
        public void handle(WindowEvent arg0) {
            if(!hasRun){
                for (Node node: listView.lookupAll(".scroll-bar")) {
                    if (node instanceof ScrollBar) {
                        final ScrollBar bar = (ScrollBar) node;
                        bar.valueProperty().addListener(new ChangeListener<Number>() {
                            @Override public void changed(ObservableValue<? extends Number> value, Number oldValue, Number newValue) {
                                System.out.println(bar.getOrientation() + " " + newValue);
                            }
                        });
                    }
                }
                hasRun = true;
            }
        }});