Swing: Прокрутите к нижней части JScrollPane, условного выражения на текущем местоположении области просмотра

Я пытаюсь подражать функциональности Adium и большинства других клиентов чата, которые я видел, где полосы прокрутки совершенствуются к нижней части, когда новые сообщения входят, но только если Вы уже там. Другими словами, если Вы прокрутили, некоторые выстраиваются в линию и читают, когда новое сообщение появляется в него, не перейдет Ваше положение в нижнюю часть экрана; это было бы раздражающим. Но если Вы прокручиваетесь до нижней части, программа справедливо предполагает, что Вы хотите видеть новые сообщения в любом случае, и таким образом, автопрокрутки соответственно.

У меня был перенос времени, пытаясь подражать этому; платформа, кажется, борется с этим поведением любой ценой. Лучшее, которое я могу сделать, следующие:

В конструкторе:

JTextArea chatArea = new JTextArea();
JScrollPane chatAreaScrollPane = new JScrollPane(chatArea);

// We will manually handle advancing chat window
DefaultCaret caret = (DefaultCaret) chatArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);

В методе, который обрабатывает новый входящий текст:

boolean atBottom = isViewAtBottom();

// Append the text using styles etc to the chatArea

if (atBottom) {
    scrollViewportToBottom();
} 


public boolean isAtBottom() {
    // Is the last line of text the last line of text visible?
    Adjustable sb = chatAreaScrollPane.getVerticalScrollBar();

    int val = sb.getValue();
    int lowest = val + sb.getVisibleAmount();
    int maxVal = sb.getMaximum();

    boolean atBottom = maxVal == lowest;
    return atBottom;
}


private void scrollToBottom() {
    chatArea.setCaretPosition(chatArea.getDocument().getLength());
}

Теперь, это работает, но это - janky и не идеальное по двум причинам.

  1. Путем установки позиции курсора, независимо от того, что стирается выбор, который пользователь может иметь в области чата. Я могу предположить, что это было бы очень раздражающим, если он пытается скопировать/вставить.
  2. Так как продвижение области прокрутки происходит после того, как текст вставляется, существует доля секунды, где полоса прокрутки находится в неправильном положении, и затем это визуально переходит к концу. Это не идеально.

Перед выяснением да я считал это сообщение в блоге на Прокрутке Текстовой области, но прокрутка по умолчанию для насыщения поведения не то, что я хочу.

Другое связанное (но по моему мнению, не абсолютно полезный в этом отношении) вопросы: Установка полосы прокрутки на jscrollpane Создание JScrollPane автоматически прокрутить полностью вниз.

Любая справка в этом отношении очень ценилась бы.

Править:

Согласно совету Devon_C_Miller, у меня есть улучшенный способ прокрутить к нижней части, решая выпуск № 1.

private void scrollToBottom() {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
       public void run() {
           try {
               int endPosition = chatArea.getDocument().getLength();
               Rectangle bottom = chatArea.modelToView(endPosition);
               chatArea.scrollRectToVisible(bottom);
           }
           catch (BadLocationException e) {
               System.err.println("Could not scroll to " + e);
           }
       }
    });
}

У меня все еще есть проблема № 2.

10
задан Community 23 May 2017 в 12:16
поделиться

2 ответа

Взгляните на scrollRectToVisible (Rectangle r) и modelToView (int pos)

Это должно дать вам то, что вы ищете, не мешая выбору пользователя.

Что касается полосы прокрутки, попробуйте принудительно выполнить прокрутку и добавление при разных событиях. Например:

if (atBottom) {
    // append new line & do scroll
    SwingUtilities.invokerLater(new Runnable(){
        public void run() {
            // append text
        }});
} else {
    // append newline
    // append text
}
6
ответ дан 3 December 2019 в 23:49
поделиться

Посмотрите этот пример .

Хотя я бы изменил код, чтобы использовать следующий, который будет более эффективным:

caret.setDot(textArea.getDocument().getLength());
1
ответ дан 3 December 2019 в 23:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: