4

I'm having an issue with nested JScrollPanes. Basically I want to have one outer JScrollPane that scrolls vertically but not horizontally (Think the Netflix web interface). Inside this outer JScrollPane I want to have multiple JScrollPanes that scroll horizontally. My problem is that horizontal scrollbars for the inner JScrollPanes never show up as it looks like they take up the entire preferred size of their JPanels. Here is an image to describe what I am talking about:

enter image description here

EDIT: This code based on camickr's answer is now working:

import java.awt.BorderLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class NestedScrollPane extends JFrame {

    public NestedScrollPane() {
        ScrollablePanel outerPanel = new ScrollablePanel();
        outerPanel.setScrollableWidth(ScrollablePanel.ScrollableSizeHint.FIT);
        outerPanel.setLayout(new BoxLayout(outerPanel, BoxLayout.Y_AXIS));
        for (int j = 0; j < 20; j++) {
            ScrollablePanel innerPanel = new ScrollablePanel();
            innerPanel.setScrollableHeight(ScrollablePanel.ScrollableSizeHint.NONE);
            innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.X_AXIS));
            JScrollPane innerScrollPane = new JScrollPane(innerPanel);
            innerScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
            for (int i = 0; i < 10; i++) {
                JLabel longLabel = new JLabel("asefaesfesfesfgesgersgrsgdrsgdrsgderg ");
                innerPanel.add(longLabel);
            }
            outerPanel.add(innerScrollPane);
        }
        JScrollPane outerPane = new JScrollPane(outerPanel);
        outerPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        this.setContentPane(outerPane);
        this.setSize(400, 400);
        outerPane.setSize(400, 400);
        this.setVisible(true);
    }

    public static void main (String[] args) {
        NestedScrollPane pane = new NestedScrollPane();
        pane.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

I took a look at How to get JScrollPanes within a JScrollPane to follow parent's resizing but using BoxLayout or BorderLayout on the outer panel doesn't seem to fix anything.

Community
  • 1
  • 1
Kevin Qiu
  • 1,616
  • 1
  • 13
  • 15
  • Just a guess, but this looks relevant: `JScrollPane.HORIZONTAL_SCROLLBAR_NEVER` – Clark Kent Jul 12 '13 at 15:00
  • Well I put that in there because I don't want the outer JScrollPane to scroll horizontally. I want it to be a fixed width and for the inner scrollpanes to be able to be scrolled horizontally. – Kevin Qiu Jul 12 '13 at 15:01
  • Ahh, okay. You want the inner ones. I misread the question. – Clark Kent Jul 12 '13 at 15:02
  • I edited the question to be a little more clear. Sorry about that. – Kevin Qiu Jul 12 '13 at 15:04
  • I am uncertain. I rearranged the code, and managed to incorporate the Horizontal scrollbars, but in turn, I eliminated the outer Vertical scroll bar. I can get either one or the other, but not both. Good question. – Clark Kent Jul 12 '13 at 15:27
  • how did you get the horizontal ones to show up out of curiosity? – Kevin Qiu Jul 12 '13 at 15:27
  • This is the code I used: http://pastebin.com/guggHG6W It's a little rough, but I was using it to help me get a better understanding of how the components were interacting with each other. One of the major things was setting the content pane to a JPanel instead of a JScrollPane. (outerPane VS outerPanel) This will surely eliminate the Vertical Scrollbar, but in turn, enables the Horizontal Scrollbars. – Clark Kent Jul 12 '13 at 15:31
  • Yeah it seems that the horizontal bars show up when you add the JPanel and not the JScrollPane to the JFrame. I'm guessing there's some issue with the JScrollPane not being able to resize to the JFrame's size. – Kevin Qiu Jul 12 '13 at 15:36
  • `I'm guessing there's some issue with the JScrollPane not being able to resize to the JFrame's size`. The issue is the implementation of the Scrollable interface. – camickr Jul 12 '13 at 15:38

1 Answers1

6

You need to implement the Scrollable interface of the outer panel added to the viewport to force the panel to fill the width of the viewport.

An easy way to do this is to use the Scrollable Panel. You should be able to use:

// JPanel outerPanel = new JPanel();
ScrollablePanel outerPanel = new ScrollablePanel();
outerPanel.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
camickr
  • 321,443
  • 19
  • 166
  • 288
  • I just tried this and it doesn't seem to change anything. Maybe I am misunderstanding which panel to use this method on. I tried doing it on just the inner panels, on just the outer panel, and on both. – Kevin Qiu Jul 12 '13 at 15:32
  • Just the outer. Works fine for me, although all you see is the scrollbar since there is no vertical space to actually paint the label. – camickr Jul 12 '13 at 15:35
  • Hmm that seemed to get the horizontal scrollbars to show up. Do you happen to know why the vertical space disappeared? – Kevin Qiu Jul 12 '13 at 15:38
  • A label only has a preferred height equal to the height of the text. If you want to see the text and scrollbar, then you need to set the horizontal scrollbar poperty to `always`, then the preferred size will include the text and the scrollbar. – camickr Jul 12 '13 at 15:40