Прокрутите JScrollPane вниз
Мне нужно прокрутить JScrollPane вниз. JScrollPane содержит JPanel, который содержит несколько JLabel's.
Чтобы прокрутить вверх, я просто делаю:
scrollPane.getViewport().setViewPosition(new Point(0,0));
но как мне прокрутить точно до самого дна? (Слишком далеко, и это дрожит)
10 ответов
JScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue( vertical.getMaximum() );
После многих часов попыток найти ответ, отличный от ответа с помощью метода scrollRectToVisible(), мне это удалось. Я обнаружил, что если вы используете следующий код после вывода текста в текстовую область на панели прокрутки, он автоматически сфокусируется на нижней части текстовой области.
textArea.setCaretPosition(textArea.getDocument().getLength());
Так что, по крайней мере для меня, мой метод печати выглядит так
public void printMessage(String message)
{
textArea.append(message + endL);
textArea.setCaretPosition(textArea.getDocument().getLength());
}
scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
}
});
Я адаптировал код Питера Сайца. Эта версия оставляет полосу прокрутки работающей после завершения прокрутки вниз.
private void scrollToBottom(JScrollPane scrollPane) {
JScrollBar verticalBar = scrollPane.getVerticalScrollBar();
AdjustmentListener downScroller = new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
Adjustable adjustable = e.getAdjustable();
adjustable.setValue(adjustable.getMaximum());
verticalBar.removeAdjustmentListener(this);
}
};
verticalBar.addAdjustmentListener(downScroller);
}
Вместо setViewPosition()
Я обычно использую scrollRectToVisible()
, описанный в разделе Как использовать панели прокрутки. Вы можете использовать результат соответствующего ярлыка getBounds()
для требуемого Rectangle
,
Приложение: @Matt отмечает в другом ответе: "Если вы используете следующий код после вывода текста в текстовую область на панели прокрутки, он автоматически сфокусируется на нижней части текстовой области".
В частном случае JTextComponent
также рассмотрите возможность использования setUpdatePolicy()
метод DefaultCaret
в ALWAYS_UPDATE
, проиллюстрировано здесь.
Ни один из ответов не сработал для меня. Почему-то мой JScrollPane
не прокручивал до самого дна, даже если я все переоценил.
Вот что сработало для меня:
SwingUtilities.invokeLater(() -> {
JScrollBar bar = scroll.getVerticalScrollBar();
bar.setValue(bar.getMaximum());
});
Если ваша JScrollPane содержит только JTextArea, то:
JScrollPane.getViewport().setViewPosition(new Point(0,JTextArea.getDocument().getLength()));
ScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue( vertical.getMaximum() - 1 );
просто установите значение: vertical.getMaximum() - 1
// Scroll to bottom of a JScrollPane containing a list of Strings.
JScrollPane scrollPane;
DefaultListModel listModel;
JList list;
listModel = new DefaultListModel();
list = new JList(listModel);
list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
list.setLayoutOrientation(JList.VERTICAL);
list.setVisibleRowCount(-1); // -1 = display max items in space available
scrollPane = new JScrollPane(list);
scrollPane.setPreferredSize(new Dimension(200, 50));
// Append text entries onto the text scroll pane.
listModel.addElement("text entry one");
listModel.addElement("text entry two");
listModel.addElement("text entry three");
listModel.addElement("text entry four");
// Get the index of the last entry appended onto the list, then
// select it, and scroll to ensure it is visible in the vewiport.
int lastNdx = listModel.getSize() - 1;
list.setSelectedIndex(lastNdx);
list.ensureIndexIsVisible(lastNdx);
JPanel panel = new JPanel();
panel.add(scrollPane);
Я хотел поделиться своими выводами по этому вопросу, так как мне нужен был ответ на него сегодня, и ни одно из решений здесь не сработало для меня, но я наконец нашел то, что сработало. У меня был объект JList, завернутый в JScrollPane, который я хотел прокрутить до последнего элемента после того, как все элементы были добавлены в DefaultListModel. По сути, это работает так:
JList list = new JList();
DefaultListModel listModel = new DefaultListModel();
JScrollPane listScroller = new JScrollPane(list);
public void populateList()
{
//populate the JList with desired items...
list.ensureIndexIsVisible(listModel.indexOf(listModel.lastElement()));
}
Я перепробовал все решения, перечисленные здесь, но ни одно из них не дало никаких результатов. Я нашел это во время экспериментов, и он отлично работает. Думаю, я оставлю это здесь, на случай, если это поможет кому-то еще.
Я попробовал несколько методов. Некоторые используют bar.setValue(bar.getMaximum())
, но максимум всегда равен 100, в то время как диапазон полосы будет намного больше 100. Некоторые используют textArea, но это не подходит для этого, поскольку в JScrollPane есть только JTable. И я думаю о методе, возможно, глупом, но эффективном.
JScrollBar bar=jsp.getVerticalScrollBar();
int x=bar.getValue();
for(int i=100;i<2000000000;i+=100)
{
bar.setValue(i);
if(x==bar.getValue())
break;
x=bar.getValue();
}
Если вы посмотрите на документацию JTextArea
public void select(int selectionStart, int selectionEnd)
Выбирает текст между указанными начальными и конечными позициями. Этот метод устанавливает начальную и конечную позиции выделенного текста, применяя ограничение, согласно которому начальная позиция должна быть больше или равна нулю. Конечная позиция должна быть больше или равна начальной позиции и меньше или равна длине текста текстового компонента.
Если вызывающая сторона предоставляет значения, которые являются несовместимыми или выходят за пределы, метод принудительно применяет эти ограничения без каких-либо сбоев. В частности, если начальная позиция или конечная позиция больше длины текста, она сбрасывается, чтобы равняться длине текста. Если начальная позиция меньше нуля, она сбрасывается в ноль, а если конечная позиция меньше начальной позиции, она сбрасывается в начальную позицию.
Таким образом, простое решение - это jTextArea.select(Integer.MAX_VALUE, 0); и пусть Java разберется!