2010-10-19 84 views
8

这是一段可运行的代码,显示了我的“问题”。我有一个JTextArea包裹在JScrollPane。当我更改JTextArea的文本时,JScrollPane会自动滚动到文本的末尾,我不希望这样。Java/Swing:一个JScrollPane中的JTextArea,如何防止自动滚动?

这里是我的要求:

  • 应用不应该滚动自动垂直但是...
  • 用户应该能够垂直滚动
  • 用户不应该能够水平滚动
  • 应用程序绝不应该水平滚动
  • 的JTextArea中一定不能编辑

(所以即使有比可水平适合,无论是应用还是用户应该可以水平滚动更多的文字。虽然垂直,只有用户应该能够滚动。)

我不知道如何“解决”这个:这应该使用JTextAreaJScrollPane方法固定?

注意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

note to all:有关空* catch *块和* final *的用法的注释可以发送到*/dev /空*,这真的不是这个问题是关于;) – SyntaxT3rr0r 2010-10-19 20:16:51

回答

22

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

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

+0

I82Much:哦,我喜欢这个更新政策!它也可以完美地工作,它比我的黑客答案(我始终将插入位置重置为零)更好。 – SyntaxT3rr0r 2010-10-19 23:17:11

1

回答我的问题:我不能完全肯定这是解决我的问题的最佳途径,但设置使用setCaretPosition(0)似乎做工精细的JTextArea's插入符号:

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

您在执行Document类时遇到了非常奇怪的行为。我在JScrollPane中的JTextPane中使用了DefaultStyledDocument。

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

但是,文档类声称是线程安全的,实际上可以从另一个线程更新。如果我确定在上更新了另一个线程,那么EventQueue的一切正常,但滚动窗格不会滚动到结尾。

我没有解释为什么这样,我没有看过Swing源代码。自2006年以来,我一直在利用这个“功能”,至今一直保持一致:-)

相关问题