Search code examples
javaswinglayoutjpaneljscrollpane

How to arrange the Components in multiple rows in a Scrollpane


I need to add about 600 Images to a Scrollpane, but all the Images are arranged side-by-side

Screenshot

public CollectionPanel(Controller controller)
  this.setBackground(Color.white);
  this.setLayout(new BorderLayout());
  JPanel content = new JPanel();
  content.setLayout(new FlowLayout());
  JScrollPane scrollPane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
  for(int i = 0; i < 100; ++i){
    content.add(new Sticker(i+1)); 
  }
  scrollPane.setViewportView(content);
  this.add(scrollPane, BorderLayout.CENTER);
}

How is it possible to arrange them to make a "linebreak" when they reached the end of the screen?


Solution

  • Have a look at Rob Camick's WrapLayout.

    You can resize the frame, and all your components will be reformatted for you. Here's an example usage

    enter image description hereenter image description here

    import java.awt.*;
    import javax.swing.*;
    
    public class TestWrapLayout {
        public TestWrapLayout () {
            ImageIcon icon = new ImageIcon(getClass().getResource("/resources/stackoverflow2.png"));
            JPanel panel = new JPanel(new WrapLayout());
            for (int i = 1; i <= 250; i++) {
                JLabel iconlabel = new JLabel(icon);
                iconlabel.setLayout(new BorderLayout());
                JLabel textlabel = new JLabel(String.valueOf(i));
                textlabel.setHorizontalAlignment(JLabel.CENTER);
                textlabel.setForeground(Color.WHITE);
                textlabel.setFont(new Font("impact", Font.PLAIN,20));
                iconlabel.add(textlabel);
                panel.add(iconlabel);
            }
            JFrame frame = new JFrame();
            frame.add(new JScrollPane(panel));
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(300, 300);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable(){
                public void run() {
                    new TestWrapLayout();
                }
            });
        }
    }