gabby
gabby

Reputation: 639

Swing flow layout break element in scrollable JPanel

I'm trying to put multiple JPanel cards into my main panel. and if new card panel does not fit I want it to be placed in next line. In the image below, you see that all my card panels go to right and if I set HORIZONTAL_SCROLLBAR_ALWAYS horizontal scroll works. So here I want 4 card panel in each line of my main panel so that vertical scroll works.

public class PanelTraining extends JPanel{
    private static final long serialVersionUID = 1L;


    public PanelTraining(List<FccMeta> ffcms) {
        super(new BorderLayout()); // set layout to absolute
        setPreferredSize(new Dimension(880, 580));
        setBorder(new LineBorder(Color.decode("#A11E1E"),1, true));

        JPanel pnlChart = new JPanel();

        pnlChart.setPreferredSize(new Dimension(860, 180));
        pnlChart.setBackground(Color.YELLOW);
        add(pnlChart, BorderLayout.NORTH);

        JPanel pnlTrSet = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 5));
        //pnlTrSet.setSize(860, 380);

        for (FccMeta fccMeta : ffcms) {
            JPanel pnlCard = new MyCustomPanelCard();
            pnlTrSet.add(pnlCard);
        }


        JScrollPane scroll = new JScrollPane(pnlTrSet);
        //scroll.setPreferredSize(new Dimension(860, 380));
        scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        add(scroll, BorderLayout.CENTER);

    }
}

enter image description here

EDIT according to the answer given below. I changed my implementation by this Class

ScrollablePanel pnlTrSet = new ScrollablePanel(new FlowLayout());
pnlTrSet.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
pnlTrSet.setScrollableBlockIncrement(
       ScrollablePanel.VERTICAL, ScrollablePanel.IncrementType.PIXELS, 230);

enter image description here

Upvotes: 0

Views: 400

Answers (1)

camickr
camickr

Reputation: 324098

You need to implement the Scrollable interface of your panel to have the width fixed to the size of the viewport of the scrollpane.

Basically you need to override the getScrollableTracksViewportWidth() method to return “true”.

An easy way to do this is to use the Scrollable Panel. It has a method that allows you to control this property.

Edit:

The above will only prevent the horizontal scrollbar from appearing. However the FlowLayout will continue to display all the buttons on a single row because the preferred size calculation of the panel is still not correct.

To get the buttons to wrap, you must replace the FlowLayout of your panel with the Wrap Layout. The Wrap Layout will recalculate the preferred height of the panel correctly so that the components can wrap and the vertical scrollbar can appear.

Upvotes: 3

Related Questions