Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java scroll JScrollPane with JPanel within to bottom

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!

like image 685
arik Avatar asked May 25 '11 22:05

arik


2 Answers

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);
            }
        });
    }
}
like image 193
Andrew Thompson Avatar answered Oct 18 '22 09:10

Andrew Thompson


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().

like image 2
camickr Avatar answered Oct 18 '22 09:10

camickr