Java / Swing:JScrollPane中的JTextArea,如何防止自动滚动?

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

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

这是我的要求:

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

(因此,即使文本多于水平放置的文本,应用程序和用户都不应该能够水平滚动。在垂直方向上,只有用户应该能够滚动。)

我不知道如何“修复”这个:是否应该使用JTextAreaJScrollPane方法修复?

请注意,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(); } } 

如何在Java GUI中设置JTextArea的AUTO-SCROLLING?

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

这样可以防止插入符自动使文档滚动到底部。

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

 jta.setText( sb.toString() ); jta.jta.setCaretPosition( 0 ); 

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

现在,这是奇怪的事情。 如果我在EventQueue上更新文档(就像通过安排runnable稍后运行一样),滚动窗格会自动滚动到最后。

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

我没有解释为什么会这样,我没有看过Swing源代码。 自2006年以来,我一直在利用这个“function”,到目前为止一直保持一致:-)