简体   繁体   中英

How to have FlowLayout reposition components upon resizing.

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.

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...

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 )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM