Как установить AUTO-SCROLLING для JTextArea в Java GUI? - PullRequest
65 голосов
/ 26 октября 2009

Я встроил JTextArea в JScrollPane и использую эту JTextArea для вывода.

Я хочу, чтобы всякий раз, когда выходной поток превышал размер JTextArea, JTextArea автоматически прокручивался, чтобы пользователю не приходилось выполнять ручную прокрутку вниз, чтобы увидеть недавний вывод.

Как я могу это сделать?

Я уже установил для свойства autoscroll как JTextArea, так и JScrollPane значение true.

Ответы [ 7 ]

144 голосов
/ 26 октября 2009

При использовании JDK1.4.2 (или более ранней версии) наиболее распространенное предложение, которое вы найдете на форумах, это использовать код, подобный следующему:

textArea.append(...);
textArea.setCaretPosition(textArea.getDocument().getLength());

Однако я только что заметил, что в JDK5 эта проблема фактически была решена путем изменения API. Теперь вы можете контролировать это поведение, установив свойство в DefaultCaret текстовой области. При таком подходе код будет:

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

Примечание:

Приведенное выше предложение установить политику обновления каретки не работает.

Вместо этого вы можете проверить Умная прокрутка , которая дает пользователю возможность определять, должна ли прокрутка быть автоматической или нет.

Более подробное описание автоматической прокрутки в текстовой области можно найти здесь: Прокрутка текстовой области

2 голосов
/ 21 декабря 2013

Когда вы щелкаете в любом месте JTextArea, автоматическую прокрутку можно остановить. Поскольку позиция каретки однажды изменилась, изменилась и точка зрения. В это время вы должны установить позицию каретки при добавлении или добавлении текста. По пути я создал метод, включающий установку позиции каретки, а затем использую его, когда что-либо добавляется или добавляется.

2 голосов
/ 15 ноября 2009
    JScrollBar vbar = scrollPane.getVerticalScrollBar();

    for (int i = 0; i < 20; i++) {

        myJTxt.append("This is text " + i + "\n");
        vbar.setValue(vbar.getMaximum());
        vbar.paint(vbar.getGraphics());
        myJTxt.scrollRectToVisible(myJTxt.getVisibleRect());
        myJTxt.paint(myJTxt.getGraphics());
        try {
            Thread.sleep(250);
        } catch (InterruptedException ex) {
            Logger.getLogger(ScrollTextView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
1 голос
/ 17 декабря 2014
    JTextArea jTextArea = new JTextArea();
    DefaultCaret caret = (DefaultCaret)jTextArea.getCaret();
    caret.setUpdatePolicy(DefaultCaret.OUT_BOTTOM);
0 голосов
/ 27 января 2019

Я попробовал большинство предложений, но столкнулся с проблемами, когда содержимое JTextArea становится большим (несколько МБ). Наконец, следующие показали лучшую производительность:

myTextArea.append( someText );
myTextArea.getCaret().setDot( Integer.MAX_VALUE );

Конечно, любой выбор, сделанный пользователем, теряется. Следовательно, его можно использовать только для использования только для отображения текстовой области.

Тем не менее, в моей установке, если содержимое JTextArea превышает около 9 МБ, оно становится непригодным для использования (от очень медленного до почти замороженного GUI).

Подобное явление возникает, когда текст содержит символы, которые представлены двумя символами (двумя 16-битными единицами) в кодировке UTF-16 (так называемые суррогатные пары, например: ?). У меня есть решение для фильтрации, но, возможно, другая тема.

0 голосов
/ 17 декабря 2014

Используйте это вместо

JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
scrollPane = new JScrollPane();
scrollPane.add(textArea);
scrollPane.setViewportView(textArea);
0 голосов
/ 14 ноября 2013

Попробуйте это:

JTextArea jTextArea = new JTextArea();
JScrollPane jScrollPane = new JScrollPane();
jScrollPane.setViewport(jTextArea);
...