javaswingjscrollpane

How to scroll to a specific location in a JScrollPane


I have a JScrollPane which contains a JPanel which has large height, This large JPanel contain more Jpanels in it as in the image. Some of those panels contains a JLabel which I used to show titles. At the top, there are JLabels which have numbers matching the title numbers in the title labels. What I need to do is when I click a label from the top label list the JScrollBar should scroll to the position where that label is placed.

I don't know whether this is possible or not, but if anyone know how to scroll to a specific position in a JScrollPane please assist me.

enter image description here


Solution

  • Assuming you want the whole panel that contains the label as title to be visible:

    Container parent = titleLabel.getParent();
    parent.scrollRectToVisible(parent.getBounds());
    

    There's no need to access the containing viewport/scrollPane except (there's always an except, isn't it :-)

    Edit

    a code snippet for @MadProgrammer :-) - but too lazy to remove every trace of SwingX, so here we go:

    final JLabel last = new JLabel("I'm the last");
    
    int maxRow = 20;
    int maxColumn = 10;
    
    JComponent content = new JPanel(new GridLayout(maxRow, maxColumn));
    for (int row = 0; row < maxRow; row++) {
        for (int column = 0; column < maxColumn; column++) {
            JComponent parent = new JPanel();
            JLabel label = new JLabel("i'm in " + row + "/" + column);
            if (row == (maxRow - 1) && column == (maxColumn - 1)) {
                label = last;
                last.setBorder(BorderFactory.createLineBorder(Color.RED));
            }
            parent.add(label);
            content.add(parent);
        }
    }
    JXFrame frame = wrapWithScrollingInFrame(content, "scroll");
    Action action = new AbstractAction("scrollLastVisible") {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            last.scrollRectToVisible(last.getBounds());
        }
    };
    addAction(frame, action);
    show(frame, frame.getPreferredSize().width / 2, frame.getPreferredSize().height / 2);