Java / Swing:JScrollPane中的JTextArea,如何防止自动滚动?
Posted
技术标签:
【中文标题】Java / Swing:JScrollPane中的JTextArea,如何防止自动滚动?【英文标题】:Java / Swing : JTextArea in a JScrollPane, how to prevent auto-scroll? 【发布时间】:2011-04-27 16:55:27 【问题描述】:这是一段可运行的代码,它显示了我的“问题”是什么。
我有一个 JTextArea
包裹在一个 JScrollPane
中。当我更改 JTextArea
的文本时,JScrollPane
会自动滚动到文本的末尾,我不希望这样。
这是我的要求:
应用程序不应自动垂直滚动,但... 用户应该能够垂直滚动 用户不应该能够水平滚动 应用程序不应水平滚动 JTextArea 不能编辑(因此,即使文本多于水平方向,应用程序和用户都不能水平滚动。垂直方向时,只有用户可以滚动。)
我不知道如何“解决”这个问题:应该使用JTextArea
或JScrollPane
方法解决这个问题吗?
请注意,AFAICT 这不是重复的:JTextPane prevents scrolling in the parent 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();
【问题讨论】:
大家注意:关于空的catch块和final的用法的cmets可以发送到/dev/null i>,这真的不是这个问题的意思;) 【参考方案1】:您在 Document 类的实现中遇到了一个非常奇怪的行为。我在 JScrollPane 内的 JTextPane 中使用 DefaultStyledDocument。
现在,奇怪的事情来了。如果我更新 EventQueue 上的文档(就像您通过安排稍后运行的可运行文件所做的那样),滚动窗格会自动滚动到末尾。
但是,文档类声称是线程安全的,并且实际上可以从另一个线程更新。如果我确保在 EventQueue 之外的 another 线程上进行更新,一切正常,但滚动窗格不会滚动到末尾。
我没有解释为什么会这样,我没有查看 Swing 源代码。自 2006 年以来,我一直在利用这个“功能”,到目前为止它一直是一致的 :-)
【讨论】:
【参考方案2】:How to set AUTO-SCROLLING of JTextArea in Java GUI?
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);
这应该防止插入符号自动使文档滚动到底部。
【讨论】:
I82Much:哦,我喜欢那个更新策略!它也可以完美运行,并且比我的 hack-answer 更好(我总是将插入符号位置重置为零)。【参考方案3】:回答我自己的问题:我不确定这是解决我的问题的最佳方法,但使用 setCaretPosition(0)
设置 JTextArea's
插入符号似乎可以正常工作:
jta.setText( sb.toString() );
jta.jta.setCaretPosition( 0 );
【讨论】:
以上是关于Java / Swing:JScrollPane中的JTextArea,如何防止自动滚动?的主要内容,如果未能解决你的问题,请参考以下文章
Java Swing - 使用 JScrollPane 并让它滚动回顶部
java swing JPanel添加在JScrollPane上,有垂直的滚动条,可是滚动条拉到底,只显示了JPanel的一部分。