Java scroll JScrollPane with JPanel within to bottom

16,298

Solution 1

JComponent.scrollRectToVisible(Rectangle). Call that on the JPanel instance.

E.G.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class ScrollToNewLabel {

    public static void main(String[] args) {
        SwingUtilities.invokeLater( new Runnable() {
            public void run() {
                JPanel gui = new JPanel(new BorderLayout(3,3));
                final JPanel panel = new JPanel(new GridLayout(0,1));
                JScrollPane scroll = new JScrollPane(panel);
                scroll.setPreferredSize(new Dimension(80,100));
                gui.add(scroll, BorderLayout.CENTER);
                JButton addLabel = new JButton("Add Label");
                gui.add(addLabel, BorderLayout.NORTH);
                ActionListener listener = new ActionListener() {
                    int counter = 0;
                    public void actionPerformed(ActionEvent ae) {
                        panel.add(new JLabel("Label " + ++counter));
                        panel.revalidate();
                        int height = (int)panel.getPreferredSize().getHeight();
                        Rectangle rect = new Rectangle(0,height,10,10);
                        panel.scrollRectToVisible(rect);
                    }
                };
                addLabel.addActionListener(listener);
                JOptionPane.showMessageDialog(null, gui);
            }
        });
    }
}

Screen shot

enter image description here

E.G. 2

This e.g. is based on Vincent's answer, to use JScrollPane.getVerticalScrollBar().setValue(height). Where height is the preferred height of the panel in pixels.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class ScrollToNewLabel {

    public static void main(String[] args) {
        SwingUtilities.invokeLater( new Runnable() {
            public void run() {
                JPanel gui = new JPanel(new BorderLayout(3,3));
                final JPanel panel = new JPanel(new GridLayout(0,1));
                final JScrollPane scroll = new JScrollPane(panel);
                scroll.setPreferredSize(new Dimension(80,100));
                gui.add(scroll, BorderLayout.CENTER);
                JButton addLabel = new JButton("Add Label");
                gui.add(addLabel, BorderLayout.NORTH);
                ActionListener listener = new ActionListener() {
                    int counter = 0;
                    public void actionPerformed(ActionEvent ae) {
                        panel.add(new JLabel("Label " + ++counter));
                        panel.revalidate();
                        int height = (int)panel.getPreferredSize().getHeight();
                        scroll.getVerticalScrollBar().setValue(height);
                    }
                };
                addLabel.addActionListener(listener);
                JOptionPane.showMessageDialog(null, gui);
            }
        });
    }
}

Solution 2

scrollRectToVisible(...) and scrollBar.setValue(...) are the general solutions.

You may be interested in Scrolling a Form which ensures that when you tab to a component the form will scroll automatically to make sure the the component will be visible in the scrollpane. Behind the scenes it uses scrollRectToVisible().

Share:
16,298
arik
Author by

arik

Working on bitcoin.

Updated on June 07, 2022

Comments

  • arik
    arik almost 2 years

    I have a JScrollPane with a very high JPanel inside, that is changed dynamically, items being appended at its end. What I want, is to scroll to the bottom of aforementioned JScrollPane in order for the newly appended items to be visible instantly on addition (they are not appended to the scroll pane directly, but to its JPanel, and are private objects, so cannot be referenced.

    How can I simply have that scroll pane scroll to the very bottom? Thanks in advance!

  • camickr
    camickr almost 13 years
    The setValue(...) method is an absolute value, not a relative value so it stops scrolling at 100. +1, for the scrollRectToVisible(...) based on the height of the panel.
  • camickr
    camickr almost 13 years
    -1, setValue(...) is an absolute number not a relative number or a percentage. So "100" won't always work. You can however use the getMaximum() method of the scrollbar.
  • Andrew Thompson
    Andrew Thompson almost 13 years
    @camickr: When I replaced setValue(100) with setValue(height) it scrolled as per expectation. Thanks, you explained the nature of the value better than the JavaDocs do. Even after re-reading the docs., I can not see anything that specifically rules out that it might be referring to a percentage. (Though Occam's razor might have suggested an absolute value.)
  • arik
    arik almost 13 years
    Thanks, scrollRectToVisible(0, preferredHeight, 10, 10) has done the trick!
  • Robin
    Robin about 12 years
    An old answer, but this probably allowed me to start my weekend 30minutes earlier. A +1 well deserved
  • Andrew Thompson
    Andrew Thompson about 12 years
    @Robin Glad I could add 30 mins to your weekend. :) Interesting that I was just warning someone of code that could tie up a compiler for the same amount of time. ;)
  • Nitin Chhajer
    Nitin Chhajer over 11 years
    Dont know why, but the setValue method was not working with JTable it ended up showing second last row. But scrollRectToVisible worked fine.