Resizing a layout panel does not cause scroll bars

I have a panel with a JPanel panel with a stream layout, the panel containing is located in JScrollPane, the panel containing contains a bunch of other JPanels, internal panels in it. All interior panels are the same size. If there are more panels, then the panel containing the panel can hold it in width , then they are attached to the grid down, and if there are more panels, the panel> can be held in height , then the inner panels are aligned in the same grid, except for the last row, which is centered with the previous row.

While I change the size of the dialog, the panel containing the panel expands , and the layout layout layout does its job, but the scrollbars are not displayed, although the size of the panel exceeds the bounds of JScrollPane.

How to control the appearance of scroll bars when dynamically resizing a panel ?

as for images, they should summarize:

alt text

After expanding the width of the dialog box:

alt text

Adam

+3
source share
1 answer

You need to make a control panel Scrollableand set the preferred size of the scrollable viewport according to the width.

import java.awt.*;
import javax.swing.*;

public class Test
{
    public static void main(String args[])
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                JPanel container = new ScrollablePanel();
                container.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
                for( int i = 0; i < 20; ++i )
                {
                    JPanel p = new JPanel();
                    p.setBorder(BorderFactory.createLineBorder(Color.RED));
                    p.setPreferredSize(new Dimension(50, 50));
                    p.add(new JLabel("" + i));
                    container.add(p);
                }

                JScrollPane scroll = new JScrollPane(container);
                scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
                scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

                JFrame f = new JFrame("Test");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                    
                f.getContentPane().add(scroll);                    
                f.pack();
                f.setSize(250, 300);
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });
    }
}

class ScrollablePanel extends JPanel implements Scrollable
{
    public Dimension getPreferredSize()
    {
        return getPreferredScrollableViewportSize();
    }

    public Dimension getPreferredScrollableViewportSize()
    {
        if( getParent() == null )
            return getSize();
        Dimension d = getParent().getSize();
        int c = (int)Math.floor((d.width - getInsets().left - getInsets().right) / 50.0);
        if( c == 0 )
            return d;
        int r = 20 / c;
        if( r * c < 20 )
            ++r;
        return new Dimension(c * 50, r * 50);
    }

    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction)
    {
        return 50;
    }

    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)
    {
        return 10;
    }

    public boolean getScrollableTracksViewportHeight()
    {
        return false;
    }

    public boolean getScrollableTracksViewportWidth()
    {
        return getParent() != null ? getParent().getSize().width > getPreferredSize().width : true;
    }
}

All numbers are hard-coded for simplicity, but you should get this idea.

+4

Source: https://habr.com/ru/post/1768145/


All Articles