Resizing panel with flow layout does not invoke the scroll bars
I have a containing panel JPanel with a Flow Layout, the containing panel is in a JScrollPane, the containing panel holds a bunch of other JPanels, inner panels, in it. All the inner panels have the same dimensions. If there are more panels then the containing panel can hold in its width then they are开发者_StackOverflow中文版 gridded downwards, and if there are more panels then the containing panel can hold in its height, then the inner panels are aligned in the same grid with the exception of the last row which is centered with the row before last.
While I resize the dialog the containing panel extends and the layout flow layout perform its duty, but the scroll bars do not appear although the size of the panel exceeds the bounds of the JScrollPane.
How do I control the appearance of the scroll bars when I resize the containing panel dynamically?
as for the images, they should sum it up:
After extending the dialog width:
Adam
You need to make the containing panel implement Scrollable
, and set the preferred scrollable viewport size 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 hardcoded for simplicity, but you should get the idea.
精彩评论