Scroll JScrollPane to bottom

JavaSwing

Java Problem Overview


I need to scroll a JScrollPane to the bottom. The JScrollPane contains a JPanel, which contains a number of JLabel's.

To scroll to the top, I just do:

scrollPane.getViewport().setViewPosition(new Point(0,0));

but how do I scroll exactly to the very bottom? (Too far and it jitters)

Java Solutions


Solution 1 - Java

JScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue( vertical.getMaximum() );

Solution 2 - Java

After many hours of attempting to find an answer other than one using the scrollRectToVisible() method, I've succeeded. I've found that if you use the following code after you output text to the text area in the scrollpane, it will automatically focus on the bottom of the text area.

textArea.setCaretPosition(textArea.getDocument().getLength());

So, at least for me, my print method looks like this

public void printMessage(String message)
{
	textArea.append(message + endL);
	textArea.setCaretPosition(textArea.getDocument().getLength());
}

Solution 3 - Java

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

Solution 4 - Java

Instead of setViewPosition(), I usually use scrollRectToVisible(), described in How to Use Scroll Panes. You could use the result of an appropriate label's getBounds() for the required Rectangle.

Addendum: @Matt notes in another answer, "If you use the following code after you output text to the text area in the scrollpane, it will automatically focus on the bottom of the text area."

In the particular case of a JTextComponent, also consider using the setUpdatePolicy() method of DefaultCaret to ALWAYS_UPDATE, illustrated here.

Solution 5 - Java

I adapted the code of Peter Saitz. This version leaves the scrollbar working after it has finished scrolling down.

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);
}

Solution 6 - Java

None of the answers worked for me. For some reason my JScrollPane was not scrolling to the very bottom, even if I revalidated everything.

This is what worked for me:

SwingUtilities.invokeLater(() -> {
        JScrollBar bar = scroll.getVerticalScrollBar();
        bar.setValue(bar.getMaximum());
});

Solution 7 - Java

If your JScrollPane only contains a JTextArea then:

JScrollPane.getViewport().setViewPosition(new Point(0,JTextArea.getDocument().getLength()));

Solution 8 - Java

// 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);

Solution 9 - Java

I wanted to contribute my findings to this question, since I needed an answer for it today, and none of the solutions here worked for me, but I did finally find one that did. I had a JList object wrapped in a JScrollPane which I wanted to scroll to the last item after all elements had been added to a DefaultListModel. It essentially works like this:

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()));
}

I tried all of the solutions listed here but none seemed to have any effect. I found this one while experimenting, and it works perfectly. Thought I'd leave it here in the case it might help someone else.

Solution 10 - Java

ScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue( vertical.getMaximum() - 1 );

just set value to: vertical.getMaximum() - 1

Solution 11 - Java

I have tried several method. Some use bar.setValue(bar.getMaximum()), but the maximum is always 100 while the range of bar will be much more than 100. Some use textArea, but it is not suitable for that there is only a JTable in the JScrollPane. And I thing about a method, maybe stupid but effective.

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();
}

Solution 12 - Java

If you look at the JTextArea documentation

public void select(int selectionStart, int selectionEnd)

Selects the text between the specified start and end positions. This method sets the start and end positions of the selected text, enforcing the restriction that the start position must be greater than or equal to zero. The end position must be greater than or equal to the start position, and less than or equal to the length of the text component's text.

If the caller supplies values that are inconsistent or out of bounds, the method enforces these constraints silently, and without failure. Specifically, if the start position or end position is greater than the length of the text, it is reset to equal the text length. If the start position is less than zero, it is reset to zero, and if the end position is less than the start position, it is reset to the start position.

So the simple solution is jTextArea.select(Integer.MAX_VALUE, 0); and let Java sort it out!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMattView Question on Stackoverflow
Solution 1 - JavacamickrView Answer on Stackoverflow
Solution 2 - JavaDecesusView Answer on Stackoverflow
Solution 3 - JavaPeter SaitzView Answer on Stackoverflow
Solution 4 - JavatrashgodView Answer on Stackoverflow
Solution 5 - JavaMatthias BraunView Answer on Stackoverflow
Solution 6 - JavaDavid RochinView Answer on Stackoverflow
Solution 7 - JavaGonzaloView Answer on Stackoverflow
Solution 8 - JavagghptgView Answer on Stackoverflow
Solution 9 - Javauser8954859View Answer on Stackoverflow
Solution 10 - JavaperecaView Answer on Stackoverflow
Solution 11 - JavaGAOLE LIView Answer on Stackoverflow
Solution 12 - JavaIan PowellView Answer on Stackoverflow