Вопрос

У меня есть следующий код:

    listModel = new DefaultListModel();
    listModel.addElement(dateFormat.format(new Date()) + ": Msg1");
    messageList = new JList(listModel);
    messageList.setLayoutOrientation(JList.VERTICAL);

    messageScrollList = new JScrollPane(messageList);
    messageScrollList.setPreferredSize(new Dimension(500, 200));

    messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {  
        public void adjustmentValueChanged(AdjustmentEvent e) {  
            e.getAdjustable().setValue(e.getAdjustable().getMaximum());  
        }
    }); 

Он автоматически прокручивается вниз.Но если я попытаюсь прокрутить назад, чтобы перечитать сообщение, это приведет к прокрутке вниз.Как я могу это исправить?

Это было полезно?

Решение

При добавлении нового сообщения, вызвать scrollRectToVisible() на JList используя Rectangle Наличие тех же размеров, что и предпочтительный размер вашей панели. Учитывая вертикальную ориентацию, может быть удобно сделать предпочтительный размер JScrollPaneS. JViewport Встрельная кратная высота панели сообщений. Смотрите также: Как использовать панели свитков.

Приложение: это убедительное обсуждение Текстовая область прокрутка может быть и полезен.

Другие советы

Я нашел это действительно полезным:http://forums.sun.com/thread.jspa?threadid=623669 (Пост по «Инопии»)
Это работает отлично

Как он говорит: «Проблема здесь в том, что может стать немного сложно найти событие, которое стреляет после того, как ListModel, JList и JScrollPane были обновлены».

this.list = blah blah... 
this.list.setSelectedValue(whatever);   
final JScrollPane sp = new JScrollPane(this.list); // needs to be after the parent is the sp 
this.list.ensureIndexIsVisible(this.list.getSelectedIndex());

@question enquirer. Пожалуйста, измените свой код с

messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {  
        public void adjustmentValueChanged(AdjustmentEvent e) {  
            e.getAdjustable().setValue(e.getAdjustable().getMaximum());  
        }
    });

к

messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {  
        public void adjustmentValueChanged(AdjustmentEvent e) {  
            e.getAdjustable().setValue(e.getAdjustable().getValue());  
        }
    }); 

Это изменение getMaximum() к getValue() Тогда это работает по мере необходимости. getMaximum() берет скручитель до своего максимума; пока getValue() берет это везде, где происходит событие.

Вы можете не использовать этот кусок кода вообще, если вы положите одну строку

messageScrollList.setViewportView(messageList);

Это работает как add(component) для JList и получает свое присущее поведению.

Для автоматической прокрутки я использую очень простую концепцию статической переменной и list.makevisible (int index)

    public class autoScrollExample
    {
     static int index=0;
     private void someFunction()
     /*   
     * 
     */
     list1.add("element1");
     list1.makeVisible(index++);
     /*
     *
     */

     private void someOtherFunction()
     /*   
     * 
     */
     list1.add("element2");
     list1.makeVisible(index++);
     /*
     *
     */


    }

я использовал JScrollPane с JTextArea. Анкет Я избегал прокрутки силы вниз, прокручивая только тогда, когда JScrollBar max значение изменилось:

        JScrollPane scrollPane = new JScrollPane(jTextArea);

        verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
        scrollPane.getVerticalScrollBar().addAdjustmentListener(
                e -> {
                    if ((verticalScrollBarMaximumValue - e.getAdjustable().getMaximum()) == 0)
                        return;
                    e.getAdjustable().setValue(e.getAdjustable().getMaximum());
                    verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
                });

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

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

Adjustable sb = messageScrollList.getVerticalScrollBar()
boolean onBottom = sb.getValue() == sb.getMaximum();
//
// add your message to the JList.
//
if(onBottom)  sb.setValue(sb.getMaximum());

В противном случае вам нужно будет указать, была ли корректировка вызвана изменением модели или мышью, и просматривая документацию API, я не уверен, есть ли способ сделать это легко.Хотя вы могли видеть, если AdjustmentEvent.getAdjustmentType() в этих случаях возвращает разные значения. Если это правда, то вы можете просто использовать оператор if в своем анонимном внутреннем классе.

Еще одна вещь, которую вы могли бы попробовать, — это иметь где-нибудь логическую переменную, которая будет установлена, когда вы добавляете что-то в список.Затем в обработчике вы проверяете, установлена ​​ли переменная.Если да, вы выполняете настройку (и сбрасываете переменную), в противном случае вы ее игнорируете.Таким образом, для каждого элемента, добавляемого в список, будет только одна прокрутка вниз.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top