ossobuko
ossobuko

Reputation: 871

Java Swing - Scrollable Panel

I am trying to create a scrollable panel using swing. But as I am new to swing, I am failing to do so. In my code nothing shows up inside the jScrollablePane.

I have created a jframe and put a jScrollablePane inside it. And I created a class called UIElement that extends jPanel which includes a components section, and child section. Child sections consist of other UIElements.

Here is some picture example, don't forget: width is dynamic.

enter image description here

And here is the code:

public static void scrollable(String title) {
    //Create and set up the window.
    JFrame frame = new JFrame(title);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setSize(500,GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height);

    JPanel mainPanel = new JPanel();
    mainPanel.setLayout(new BoxLayout(mainPanel,BoxLayout.Y_AXIS));
    mainPanel.setBackground(Color.WHITE);

    mainPanel.add(new UIElement());

    JScrollPane scrollPane = new JScrollPane(mainPanel,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    frame.getContentPane().add(scrollPane);

    //Display the window.
    frame.setVisible(true);
}

And here is the UIElement class:

public abstract class UIElement extends JPanel {
    public static final int DESIREDHEIGHT = 40;

    JPanel componentsPanel, childPanel;

    public UIElement () {
        super();
        this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
        this.setBackground(Color.BLACK);

        // componentsPanel
        componentsPanel = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                Dimension d = super.getPreferredSize();
                d.setSize(d.getWidth(),DESIREDHEIGHT);
                return d;
            }

            @Override
            public Dimension getMaximumSize() {
                Dimension d = super.getMaximumSize();
                d.setSize(d.getWidth(),DESIREDHEIGHT);
                return d;
            }

            @Override
            public Dimension getMinimumSize() {
                Dimension d = super.getPreferredSize();
                d.setSize(d.getWidth(),DESIREDHEIGHT);
                return d;
            }
        };
        componentsPanel.setLayout(new BoxLayout(componentsPanel,BoxLayout.X_AXIS));
        componentsPanel.setBackground(Color.BLUE);
        this.add(componentsPanel);

        // child panel
        childPanel = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                float height = 0;
                for (Component c: super.getComponents())
                    height += c.getPreferredSize().height;
                Dimension d = super.getPreferredSize();
                d.setSize(d.getWidth(),height);
                return d;
            }

            @Override
            public Dimension getMaximumSize() {
                float height = 0;
                for (Component c: super.getComponents())
                    height += c.getMaximumSize().height;
                Dimension d = super.getMaximumSize();
                d.setSize(d.getWidth(),height);
                return d;
            }

            @Override
            public Dimension getMinimumSize() {
                float height = 0;
                for (Component c: super.getComponents())
                    height += c.getMinimumSize().height;
                Dimension d = super.getMinimumSize();
                d.setSize(d.getWidth(),height);
                return d;
            }
        };
        childPanel.setLayout(new BoxLayout(childPanel,BoxLayout.Y_AXIS));
        childPanel.setBackground(Color.RED);

        // parent for childPanel and spacer
        JPanel childParent = new JPanel();
        childParent.setLayout(new BoxLayout(childParent,BoxLayout.X_AXIS));

        // spacer
        JPanel spacer = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(DESIREDHEIGHT,DESIREDHEIGHT);
            }

            @Override
            public Dimension getMaximumSize() {
                return new Dimension(DESIREDHEIGHT,DESIREDHEIGHT);
            }

            @Override
            public Dimension getMinimumSize() {
                return new Dimension(DESIREDHEIGHT,DESIREDHEIGHT);
            }
        };
        spacer.setBackground(Color.RED);
        childParent.add(spacer);
        // add the childPanel later
        childParent.add(childPanel);
    }


    @Override
    public Dimension getPreferredSize() {
        Dimension c = componentsPanel.getPreferredSize();
        Dimension d = childPanel.getPreferredSize();
        return new Dimension(c.width, c.height + d.height);
    }

    @Override
    public Dimension getMaximumSize() {
        Dimension c = componentsPanel.getMaximumSize();
        Dimension d = childPanel.getMaximumSize();
        return new Dimension(c.width, c.height + d.height);
    }

    @Override
    public Dimension getMinimumSize() {
        Dimension c = componentsPanel.getMinimumSize();
        Dimension d = childPanel.getMinimumSize();
        return new Dimension(c.width, c.height + d.height);
    }

}

Upvotes: 1

Views: 665

Answers (1)

camickr
camickr

Reputation: 324118

Don't override getPreferredSize() (or maximum/minim sizes) of the panels.

Each panel will determine its preferred size based on the layout manager of the panel and the components added to the panel.

That is if a panel uses a layout manager, there is no need to override those methods. You only need to override the getPreferredSize() methods for a custom component that has no layout manager. In Swing terms this would be a JButton, JTextField, JLabel etc.

So you if are creating a custom component then you set the size. If you just use a component as a container with a layout manager to hold other components then you don't calculate the size.

Upvotes: 1

Related Questions