这是一段可运行的代码,显示了我的“问题”。
我有一个JTextArea
包裹在JScrollPane
中。当我更改JTextArea
的文本时,JScrollPane
会自动滚动到文本的末尾,我不希望这样。
以下是我的要求:
(因此,即使文本比水平方式更多,应用程序和用户都不应该能够水平滚动。垂直方向,只有用户才能滚动。)
我不知道如何“修复”此问题:是否应使用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();
}
}
答案 0 :(得分:23)
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);
这可以防止插入符号自动使文档滚动到底部。
答案 1 :(得分:1)
回答我自己的问题:我不确定这是解决我的问题的最佳方法,但使用JTextArea's
设置setCaretPosition(0)
插入符号似乎工作正常:
jta.setText( sb.toString() );
jta.jta.setCaretPosition( 0 );
答案 2 :(得分:1)
你在Document类的实现中遇到了一个非常奇怪的行为。我在JScrollPane中的JTextPane中使用DefaultStyledDocument。
现在,这是一件奇怪的事情。如果我在EventQueue上更新文档(就像通过安排runnable稍后运行一样),滚动窗格会自动滚动到最后。
但是,文档类声称是线程安全的,并且实际上可以从另一个线程更新。如果我确保更新另一个线程而不是EventQueue,一切正常,但滚动窗格不会滚动到最后。
我没有解释为什么会这样,我没有看过Swing来源。自2006年以来,我一直在利用这个“功能”,到目前为止一直保持一致: - )