10

这是一段可运行的代码,它显示了我的“问题”是什么。

我有一个JTextArea包裹在一个JScrollPane. 当我更改 的文本时JTextArea,会JScrollPane自动滚动到文本的末尾,我不希望这样。

以下是我的要求:

  • 应用程序不应自动垂直滚动,但...
  • 用户应该能够垂直滚动
  • 用户应该能够水平滚动
  • 应用程序不应该水平滚动
  • JTextArea 不能编辑

(因此,即使文本多于水平,应用程序和用户都不应该能够水平滚动。垂直时,只有用户应该能够滚动。)

我不知道如何“解决”这个问题:应该使用JTextAreaorJScrollPane方法解决这个问题吗?

请注意,AFAICT 这根本不是重复的:JTextPane 防止在父 JScrollPane 中滚动

这是一个有趣的例子,每 200 毫秒它会在其中添加新文本,JTextArea您可以看到JScrollPane总是自动滚动到文本的末尾。

import javax.swing.*;
import java.awt.*;
import java.util.Random;

public final class TextInScrollPane extends JFrame {

    private static final Random r = new Random( 42 );

    public static void main( final String[] args ) {
        final JFrame f = new JFrame();
        f.setDefaultCloseOperation( EXIT_ON_CLOSE );
        f.setLayout(new BorderLayout());
        final JTextArea jta = new JTextArea( "Some text", 30, 30 );
        jta.setEditable( false );   // This must not be editable
        final JScrollPane jsp = new JScrollPane( jta );
        jsp.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );
        jsp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );
        f.add( jsp, BorderLayout.CENTER );
        f.pack();
        f.setLocationRelativeTo( null );
        f.setVisible(true);

        final Thread t = new Thread( new Runnable() {
            public void run() {
                while ( true ) { 
                    try {Thread.sleep( 200 );} catch ( InterruptedException e ) {}
                    final StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < 50 + r.nextInt( 75 ); i++) {
                        for (int j = 0; j < r.nextInt(120); j++) {
                            sb.append( (char) 'a' + r.nextInt(26) );
                        }
                        sb.append( '\n' );
                    }
                    SwingUtilities.invokeLater( new Runnable() {
                        public void run() {
                            jta.setText( sb.toString() );
                        }
                    } );
                }
            }
        });
        t.start();
    }

}
4

3 回答 3

26

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

http://download.oracle.com/javase/1.5.0/docs/api/javax/swing/text/DefaultCaret.html#NEVER_UPDATE

尝试:

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

这应该防止插入符号自动使文档滚动到底部。

于 2010-10-19T21:53:52.587 回答
1

回答我自己的问题:我不确定这是解决我的问题的最佳方法,但JTextArea's使用插入符号setCaretPosition(0)似乎可以正常工作:

jta.setText( sb.toString() );
jta.jta.setCaretPosition( 0 );
于 2010-10-19T20:25:51.967 回答
1

您在 Document 类的实现中遇到了一个非常奇怪的行为。我在 JScrollPane 内的 JTextPane 中使用 DefaultStyledDocument。

现在,这是奇怪的事情。如果我更新 EventQueue 上的文档(就像您通过安排稍后运行的可运行文件所做的那样),滚动窗格会自动滚动到末尾。

但是,文档类声称是线程安全的,并且实际上可以从另一个线程更新。如果我确保在 EventQueue 之外的另一个线程上进行更新,一切正常,但滚动窗格不会滚动到最后。

我没有解释为什么会这样,我没有查看 Swing 源代码。自 2006 年以来,我一直在利用这个“功能”,到目前为止它一直是一致的 :-)

于 2011-03-08T09:18:50.583 回答