JavaFX自动向下滚动滚动窗格

时间:2012-10-31 11:30:11

标签: java javafx-2

当内容的高度增加时,是否有任何方法可以自动向下滚动ScrollPane控件? 例如,我在屏幕底部(ScrollPane内部)有一个TitledPane,当我展开它时,我希望ScrollPane向下滚动,这样我就能看到TitledPane的全部内容。

8 个答案:

答案 0 :(得分:14)

您可以使用内部容器的bind ScrollPane vvalue heightProperty属性。例如,如果VBox中有ScrollPane

scrollPane.vvalueProperty().bind(vBox.heightProperty());

答案 1 :(得分:3)

您可以结合使用titledPane.localToScene()scrollPane.setVvalue()

来实现这种行为

第一个是获得titledPane的坐标,而第二个是设置scrollPane的垂直条位置。请注意,它的范围介于0 - 1之间。

答案 2 :(得分:2)

在将值传递给垂直或水平条之前,您必须告诉scrollpane当前坐标在哪里。

这段代码对我来说非常好:

// the owner's node of your scrollPane;
titledPane.layout(); 
// the maxValue for scrollPane bar ( 1.0 it's the default value )
scrollPane.setVvalue( 1.0d ); 

您必须在滚动窗口增长的地方对此进行编码。例如,如果将节点添加到滚动窗格内部节点,则将它们添加到其子项列表中。

如果scrollpane的内部节点改变了它的高度,则向heightProperty添加一个监听器。

例如,您的scrollPane的内部节点是一个AnchorPane,您将节点添加到此窗格,所以这样做:

anchorPane.getChildren().addListener( 
    ( ListChangeListener.Change<? extends Node> c ) -> {
        titledPane.layout();
        scrollPane.setVvalue( 1.0d ); 
    }
);

如果它是增长的高度......

heightProperty().addListener(
    (observable, oldValue, newValue) -> {
        titledPane.layout();
        scrollPane.setVvalue( 1.0d ); 
    }
);

就是这样!

答案 3 :(得分:1)

我遇到了同样的问题,我在答案中尝试了不止一种方法。 我的问题是使用 ScrollPane 从其他线程更新 Platform.runLater() 内容,如果更新速度非常快,所有以前的方法都不够好。 对于所有面临此类问题的人,您可以简单地使用它:

ScrollPane scrollPane = new ScrollPane();
scrollPane.needsLayoutProperty().addListener((observable, oldValue, newValue) -> {
    if (!newValue) {
        scrollPane.setVvalue(1.0);
    }
});

答案 4 :(得分:0)

您可以像以下一样为TitledPane的高度属性添加一个监听器:

titledPane.heightProperty().addListener((observable, oldValue, newValue) -> 
       vvalueProperty().set(newValue.doubleValue()));

答案 5 :(得分:0)

Donno(如果仍然有用),我遇到了类似的问题,并且此解决方案对我有用。我需要滚动条以MVVM模式自动滚动。我所做的是将View中的textarea的scrollTopProperty与ViewModel中的SimpleDoubleProperty绑定在一起。唯一的问题是,scrollTopProperty基本上是根据像素滚动的,因此我根据通道数* 100增加了它;

查看

textArea.textProperty().bindBidirectional(viewModel.SimpleStringProperty());
textArea.scrollTopProperty().bindBidirectional(viewModel.SimpleDoubleProperty());

ViewModel

SimpleDoubleProperty.setValue(SimpleStringProperty.getValue().split("\n").length * 100);

我知道代码并不真正具有代表性,但是如果有人需要更多实现细节,我可以详细说明...

答案 6 :(得分:0)

innerPane.widthProperty().addListener((observable, oldValue, newValue) -> { scrollPane.setHvalue(1.0d); });

如果您尝试通过监听innerPane 的子列表的更改来更改滚动条的位置是行不通的,因为此时尚未使用innerPane 布局计算此更改。所以一定要注意属性width或者height!

答案 7 :(得分:-1)

我是通过使用AnimationTimer完成的。我不得不等待100000000纳秒才能确保ScrollPane对扩展的Titlepane做出反应。

public void scrollNodeInTopScrollPane(Node n, ScrollPane s) {
    final Node node = n;
    final ScrollPane clientTopScrollPane = s;
    AnimationTimer timer = new AnimationTimer() {
        long lng = 0;
        @Override
        public void handle(long l) {
            if (lng == 0) {
                lng = l;                   
            }                
            if (l > lng + 100000000) {                   
                if (node.getLocalToSceneTransform().getTy() > 20) {                      
                    clientTopScrollPane.setVvalue(clientTopScrollPane.getVvalue() + 0.05);                        
                    if (clientTopScrollPane.getVvalue() == 1) {
                        this.stop();                          
                    }
                } else {
                    this.stop();
                }
            }                
        }
    };
    timer.start();
}