Как установить AUTO-SCROLLING для JTextArea в Java GUI?
-
06-07-2019 - |
Вопрос
Я встроил JTextArea в JScrollPane и использую эту JTextArea для вывода.
Я хочу, чтобы всякий раз, когда выходной поток превышал размер JTextArea, JTextArea автоматически прокручивался, чтобы пользователю не приходилось выполнять ручную прокрутку вниз, чтобы увидеть недавний вывод.
Как я могу это сделать?
Я уже установил для свойства автопрокрутки JTextArea и JScrollPane значение true.
Решение
При использовании 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);
Примечание:
Приведенное выше предложение по настройке политики обновления каретки не работает. Р>
Вместо этого вы можете проверить умную прокрутку , которая дает пользователю возможность определять, когда прокрутка должна быть автоматической или нет.
Более подробное описание автоматической прокрутки в текстовой области можно найти здесь: Прокрутка текстовой области
Другие советы
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);
}
}
Когда вы щелкаете в любом месте JTextArea, автоматическую прокрутку можно остановить. Поскольку позиция каретки однажды изменилась, изменилась и точка зрения. В это время вы должны установить позицию каретки при добавлении или добавлении текста. По пути я создал метод, включающий установку положения каретки, а затем использую его, когда что-либо будет добавлено или добавлено.
JTextArea jTextArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)jTextArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.OUT_BOTTOM);
Я попробовал большинство предложений, но столкнулся с проблемами, когда содержимое JTextArea стало большим (несколько МБ). Наконец, следующие показали лучшую производительность:
myTextArea.append( someText );
myTextArea.getCaret().setDot( Integer.MAX_VALUE );
Конечно, любой выбор, сделанный пользователем, теряется. Следовательно, его можно использовать только для «только для отображения» использование текстовой области.
Тем не менее, в моей установке, если содержимое JTextArea превышает 9 МБ, оно становится непригодным для использования (от очень медленного до почти замороженного графического интерфейса).
Подобное явление возникает, когда текст содержит символы, которые представлены двумя символами (двумя 16-разрядными единицами) в кодировке UTF-16 (так называемые суррогатные пары, например: & # 127801;). У меня есть решение для фильтрации, но, возможно, другая тема.
Используйте это вместо
JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
scrollPane = new JScrollPane();
scrollPane.add(textArea);
scrollPane.setViewportView(textArea);
Попробуйте это:
JTextArea jTextArea = new JTextArea();
JScrollPane jScrollPane = new JScrollPane();
jScrollPane.setViewport(jTextArea);