如何在Java GUI中设置JTextArea的自动滚动?


67

我已经在JScrollPane上嵌入了JTextArea,并且正在使用该JTextArea进行输出。

我希望每当输出超出JTextArea的大小时,JTextArea都会自动滚动,以便用户不必手动向下滚动即可查看最新输出。

我怎样才能做到这一点?

我已经将JTextArea和JScrollPane的autoscroll属性都设置为true。

Answers:


148

当使用JDK1.4.2(或更早版本)时,在论坛上会发现最常见的建议是使用如下代码:

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

但是,我刚刚注意到,在JDK5中,此问题实际上已通过API更改得以解决。现在,您可以通过在文本区域的DefaultCaret上设置属性来控制此行为。使用这种方法的代码将是:

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

注意:

上述设置插入符号更新策略的建议不起作用。

相反,您可能想查看智能滚动,该功能使用户能够确定何时应该自动进行滚动。

在文本区域中自动滚动的更详细说明可以在这里找到:文本区域滚动


@camickr,我无法访问链接,我坐在公司防火墙后面。您能从该链接中发布重要内容吗?我将投票给您:)谢谢。
Suraj Chandran

1
有什么想法为什么可能不起作用(使用Netbeans构建器创建表单的价值)?
网络僧侣

@ cyber-monk,否。创建一个SSCCE。如果仍然无法使用,则可以创建一个问题并发布SSCCE。
camickr

1
我从您的答案中删除了您的旁注-如果仍然存在问题,请在Meta Stack Overflow上发布内容
Duncan Jones

1
根据答案中引用的有关文本区域滚动的文章,设置插入符号更新策略不再起作用。最好坚持明确设置插入标记的位置。
jstricker

2
    JScrollBar vbar = scrollPane.getVerticalScrollBar();

    for (int i = 0; i < 20; i++) {

        myJTxt.append("This is text " + i + "\n");
        vbar.setValue(vbar.getMaximum());
        vbar.paint(vbar.getGraphics());
        myJTxt.scrollRectToVisible(myJTxt.getVisibleRect());
        myJTxt.paint(myJTxt.getGraphics());
        try {
            Thread.sleep(250);
        } catch (InterruptedException ex) {
            Logger.getLogger(ScrollTextView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

2

当您单击JTextArea上的任何位置时,都可以停止自动滚动。因为插入符号的位置曾经改变,所以视点也改变了。此时,您应该在添加或添加一些文本时设置插入符号的位置。在途中,我创建了包括设置插入符位置在内的方法,然后在要添加或附加任何内容时使用它。


2
    JTextArea jTextArea = new JTextArea();
    DefaultCaret caret = (DefaultCaret)jTextArea.getCaret();
    caret.setUpdatePolicy(DefaultCaret.OUT_BOTTOM);

1

我尝试了大多数建议,但是当JTextArea的内容变大(几个MB)时遇到了问题。最后,以下显示最佳性能:

myTextArea.append( someText );
myTextArea.getCaret().setDot( Integer.MAX_VALUE );

当然,用户所做的任何选择都会丢失。因此,它仅可用于文本区域的“仅显示”用法。

尽管如此,在我的安装中,如果JTextArea的内容超过9MB,它就变得无法使用(非常缓慢甚至几乎冻结的GUI)。

当文本包含以UTF-16编码的两个字符(两个16位单元)表示的字符(所谓的代理对,例如:🌹)时,会发生类似的现象。我有一个过滤解决方案,但也许是另外一个话题。


0

最好和最简单的方法,请尝试以下操作:

  import javax.swing.text.DefaultCaret;
  DefaultCaret caret = (DefaultCaret) textArea.getCaret();
  caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

-2

改用这个

JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
scrollPane = new JScrollPane();
scrollPane.add(textArea);
scrollPane.setViewportView(textArea);

-3

尝试这个:

JTextArea jTextArea = new JTextArea();
JScrollPane jScrollPane = new JScrollPane();
jScrollPane.setViewport(jTextArea);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.