【问题标题】:JavaFX auto-scroll down scrollpaneJavaFX 自动向下滚动滚动窗格
【发布时间】:2012-10-20 20:22:57
【问题描述】:

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

【问题讨论】:

    标签: java javafx-2


    【解决方案1】:

    您可以通过结合使用 titledPane.localToScene()scrollPane.setVvalue() 来实现该行为

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

    【讨论】:

    • 我也有类似的问题。我需要向上/向下移动标题窗格。我能怎么做?主要是实现 IntelliJ 输出窗口功能。该窗口可以用鼠标上下移动。
    【解决方案2】:

    我是通过使用 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();
    }
    

    【讨论】:

      【解决方案3】:

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

      这段代码对我来说很好用:

      // 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 ); 
      

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

      如果滚动窗格的内部节点改变了它的高度,给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 ); 
          }
      );
      

      就是这样!

      【讨论】:

        【解决方案4】:

        您可以将bindScrollPanevvalue 属性与内部容器的heightProperty 结合使用。例如,如果您的ScrollPane 中有VBox

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

        【讨论】:

        • 哇...这个解决方案对我有用。但是,你能解释更多吗?
        • 它将隐藏顶部的标题窗格。
        • 这应该被认为是不好的做法,原因如下:vvalue(用于垂直值,这意味着滚动条的垂直位置以百分比为单位(如其他 cmets 中所述)范围从 0 ( double) VBoxheight (也是 double) 将大于 1,因为您很可能没有高度小于像素的 Container 这会导致将较大的值设置为滚动条位置我认为这是可行的,因为如果 vvalue 大于 1,则将其视为 1
        【解决方案5】:

        您可以像这样向 TitledPane 的高度属性添加一个侦听器:

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

        【讨论】:

          【解决方案6】:

          Donno,如果它仍然相关,我遇到了类似的问题,这个解决方案对我有用。我需要滚动条以 MVVM 模式自动滚动。我所做的是将视图中 textarea 的 scrollTopProperty 与 ViewModel 中的 SimpleDoubleProperty 绑定。唯一的问题是 scrollTopProperty,基本上是基于像素滚动的,所以我根据车道数 * 100 增加了它;

          查看

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

          视图模型

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

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

          【讨论】:

            【解决方案7】:

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

            如果您尝试通过监听 innerPane 子列表的更改来更改滚动条位置,则不起作用,因为此时尚未使用 innerPane 布局计算此更改。因此,您必须注意属性的宽度或高度!

            【讨论】:

              【解决方案8】:

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

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-02-12
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多