【问题标题】:Making a JScrollPane automatically scroll all the way down使 JScrollPane 自动向下滚动
【发布时间】:2011-01-29 19:50:25
【问题描述】:

我正在尝试使用 JTextArea 实现 JScrollPane。 JTextArea 被附加到,我希望 JScrollPane 在添加更多文本时继续向下滚动。如何实现?

【问题讨论】:

    标签: java swing awt jscrollpane jtextarea


    【解决方案1】:

    我在这里找到了答案: JScrollPane and JList auto scroll

    scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {  
            public void adjustmentValueChanged(AdjustmentEvent e) {  
                e.getAdjustable().setValue(e.getAdjustable().getMaximum());  
            }
        });
    

    【讨论】:

    • 你的“解决方案”其实是linked-to问题的问题:如果你手动尝试移动垂直滚动手柄,这段代码会再次滚动到底部!
    • @jackrabbit Here 是在用户手动移动垂直滚动条时使其停止滚动的代码。如果用户滚动到底部,它会继续滚动。
    【解决方案2】:

    对于(我认为是)更简单的答案,请查看:Text Area Scrolling

    在 JDK5 之前,您必须在每次追加后手动更改插入符号的位置。您现在可以像这样将此行为作为默认行为:

     JTextArea textArea = new JTextArea();
     DefaultCaret caret = (DefaultCaret)textArea.getCaret();
     caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
    

    这样做的好处是你不需要在你的代码中多次使用这个sn-p!

    【讨论】:

    • +1 setUpdatePolicy() API 解释了很多。我已经相应地更新了对引用问题的回答。
    • 是的,API 一直在变化,很难跟上变化。
    • 这会有所帮助,但如果用户点击最后一行末尾以外的任何地方,自动滚动就会停止。这不直观。如果通常的行为有效,那就太好了,只需滚动到底部即可重新激活自动滚动。
    • @jcalfee314,查看Smart Scrolling 以获取另一个可能的解决方案。
    • @jcalfee314 为了解决这个问题,我添加了一个按钮,当点击该按钮时,它会再次启用自动滚动。按钮的代码只需要这个:textArea.setCaretPosition(textArea.getDocument().getLength());
    【解决方案3】:

    一种解决方法是可能的:您可以将该侦听器声明为一个类,然后在需要它的事件上实例化它。之后,您可以在强制重新绘制屏幕后删除该类。像魅力一样工作。

    【讨论】:

      【解决方案4】:

      如果您不断向其写入数据,您可以使用:

      textArea.setCaretPosition(textArea.getDocument().getLength());
      

      就在您添加新数据之后。

      这会自动滚动到 JScorllPane。

      【讨论】:

      • 虽然可能,但这不是最好的解决方案 - 这是@camickr 的回答:-)
      【解决方案5】:

      这是解决方案。

      JTextArea textArea = new JTextArea();
      DefaultCaret caret = (DefaultCaret)textArea.getCaret();
      caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);` 
      

      【讨论】:

      • +1 表示正确答案 - 即使它与 Rob 接受的答案相同 :-)
      【解决方案6】:

      接受的解决方案效果很好,但仅当文本区域可编辑时,即没有 jTextArea.setEditable(false)Krigath 建议的解决方案更通用,但这里有问题JScrollPane and JList auto scroll。使用该问题的答案,您可以获得一般解决方案,例如:

              JScrollPane scrollPane = new JScrollPane(jTextArea);
      
          verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
          scrollPane.getVerticalScrollBar().addAdjustmentListener(
                  e -> {
                      if ((verticalScrollBarMaximumValue - e.getAdjustable().getMaximum()) == 0)
                          return;
                      e.getAdjustable().setValue(e.getAdjustable().getMaximum());
                      verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
                  });
      

      只有在垂直滚动条展开时,窗格才会向下滚动,以响应附加的文本行。

      我承认可以找到一种无需额外变量即可过滤事件的方法,如果有人发布它,我将不胜感激。

      【讨论】:

      • 我编辑了您的代码,它运行良好。 +1
      【解决方案7】:

      我查看了答案,发现@user9999 answer 对于那些希望滚动条连续滚动的人来说是一个很好的解决方案。我编辑了代码,摆脱了变量。它使滚动停止 - 当用户手动滚动时。如果用户滚动到 textarea 或 scrollarea 的末尾,则自动滚动继续。

      (也正如@user9999 建议的那样,我删除了变量并添加了jScrollPane1.getHeight() 作为度量值,以在当前滚动条值低于最大值时停止滚动)

      解决方法如下:

      jScrollPane1.getVerticalScrollBar().addAdjustmentListener(
      e -> {
          if ((e.getAdjustable().getValue() - e.getAdjustable().getMaximum()) > -jScrollPane1.getHeight() - 20){
              e.getAdjustable().setValue(e.getAdjustable().getMaximum());
          }   
      });
      

      编辑:

      -jScrollPane1.getHeight() - 20 中添加了-20,因为有时没有它就无法滚动,我猜-20 可以根据TextArea 的字体大小进行更改。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-03
        • 2011-01-09
        • 1970-01-01
        • 1970-01-01
        • 2016-09-30
        • 1970-01-01
        • 2012-01-18
        相关资源
        最近更新 更多