2

I want to put FlowLayout with lets say 5 labels inside BorderLayout as north panel (BorderLayout.NORTH), and when I resize my window/frame I want the labels to not disappear but instead move to new line.

I have been reading about min, max values and preferredLayoutSize methods. However they do not seem to help and I am still confused.

Also, I would not like to use other layout like a wrapper or something.

Ankit
  • 6,772
  • 11
  • 48
  • 84
user2141889
  • 2,255
  • 5
  • 23
  • 25
  • Looks like a cross posting: http://www.coderanch.com/t/606655/GUI/java/Swing-FlowLayout-BorderLayout. Funny how you get the same answer. – camickr Mar 07 '13 at 04:35

2 Answers2

6

One of the annoying things about FlowLayout is that it doesn't "wrap" it's contents when the available horizontal space is to small.

Instead, take a look at WrapLayout, it's FlowLayout with wrapping...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
1

The following code does exactly what you asked.

The program has a frame whose contentPane is set for BorderLayout. It contains another panel flowPanel that has a flow layout and is added to the BorderLayout.NORTH.

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class PanelFun extends JFrame {
    final JPanel flowPanel;

    public PanelFun() {
        setPreferredSize(new Dimension(300,300));
        getContentPane().setLayout(new BorderLayout());
        flowPanel = new JPanel(new FlowLayout());
        addLabels();
        getContentPane().add(flowPanel, BorderLayout.NORTH);


        addComponentListener(new ComponentAdapter() {

            @Override
            public void componentResized(ComponentEvent e) {
                PanelFun.this.getContentPane().remove(flowPanel); //this statement is really optional.
                PanelFun.this.getContentPane().add(flowPanel);
            }
        });
    }

    void addLabels(){
        flowPanel.add(new JLabel("One"));
        flowPanel.add(new JLabel("Two"));
        flowPanel.add(new JLabel("Three"));
        flowPanel.add(new JLabel("Four"));
        flowPanel.add(new JLabel("Five"));
    }



    public static void main(String[] args) {
        final PanelFun frame = new PanelFun();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.pack();
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                frame.setVisible(true);

            }
        });
    }
}

So, how does it work?

The key to having the components inside flowPanel realign when the frame is resized is this piece of code

PS: Let me know if you are new to Swing and do not understand some part of the code.

addComponentListener(new ComponentAdapter() {

                @Override
                public void componentResized(ComponentEvent e) {
                    PanelFun.this.getContentPane().remove(flowPanel);
                    PanelFun.this.getContentPane().add(flowPanel);
                }
            });

Without this code the flowPanel will not realign its components as it is not its normal behaviour to reposition components when the containing frame is resized.

However, it is also its behaviour that when flowPanel is added to a panel, it would position components as per the available space. So, if we add the flowPanel everytime the frame resizes, the inner elements will be repositioned to use the available space.

Update:

As camickr pointed out correctly, this method will not work in case you add anything to the center (BorderLayout.CENTER)

Ankit
  • 6,772
  • 11
  • 48
  • 84
  • 1
    -1, This only works because you didn't add any components to the CENTER of the BorderLayout. – camickr Mar 07 '13 at 04:31
  • @camickr On completely another note, (assuming from the site name) are you also the guy who actually wrote `WrapLayout`? – Ankit Mar 07 '13 at 06:49