Автопрокрутка JScrollPane и JList
У меня есть следующий код:
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());
}
});
Он автоматически прокручивается вниз. Но, если я попытаюсь прокрутить назад, чтобы перечитать сообщение, он запустит прокрутку вниз.
Как я могу это исправить?
Ответы
Ответ 1
При добавлении нового сообщения вызовите scrollRectToVisible()
на JList
, используя Rectangle
с теми же размерами, что и ваш размер панели сообщений. Учитывая вертикальную ориентацию, может быть удобно сделать предпочтительный размер JScrollPane
JViewport
интеграл, кратный высоте панели сообщений. См. Также: Как использовать панели прокрутки.
Приложение: Это убедительное обсуждение Прокрутка текстовой области также может быть полезна.
Ответ 2
Я нашел это действительно полезным:
http://forums.sun.com/thread.jspa?threadID=623669 (сообщение от 'inopia')
Он отлично работает
Как он говорит:
"Проблема здесь в том, что может быть немного сложно найти событие, которое срабатывает после обновления списков ListModel, JList и JScrollPane".
Ответ 3
@question enquirer. Измените свой код с
messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
}
});
to
messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
e.getAdjustable().setValue(e.getAdjustable().getValue());
}
});
Это изменение getMaximum()
to getValue()
Затем оно работает по мере необходимости. getMaximum()
максимально скроллинг; в то время как getValue()
принимает его везде, где происходит событие.
Вы можете вообще не использовать этот фрагмент кода, если поставить одну строку
messageScrollList.setViewportView(messageList);
Это работает как add(component)
для jList и получает свое неотъемлемое поведение.
Ответ 4
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());
Ответ 5
Для автоматической прокрутки я использую очень простую концепцию статической переменной и 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++);
/*
*
*/
}
Ответ 6
Я думаю, что вы хотите, чтобы он прокручивался вниз, когда вы добавляете материал в свой список сообщений, а не на настройку. Таким образом, ваш код может выглядеть так:
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 в своем анонимном внутренний класс.
Еще одна вещь, которую вы могли бы попробовать, заключалась бы в том, чтобы где-то имело значение boolean, которое устанавливается, когда вы добавляете что-то в список. Затем в вашем обработчике вы проверяете, установлена ли переменная. Если это так, вы выполняете настройку (и отключите переменную) в противном случае, вы игнорируете ее. Таким образом, в список будет добавлен только один прокручиваемый элемент.