开发者

Fixed width, variable height in JPanel with flow

开发者 https://www.devze.com 2023-01-14 19:39 出处:网络
I have an annoying problem with Java’s layout managers. I have the following situation: In a panel A are two other panels B with an absolute layout and C with a FlowLayout. B is highly customized and

I have an annoying problem with Java’s layout managers. I have the following situation: In a panel A are two other panels B with an absolute layout and C with a FlowLayout. B is highly customized and has a fixed size set via setPreferredSize. C should have the same fixed width as B but otherwise b开发者_运维百科e of a variable height, depending on how many components are added in the flow. The resulting A should then have the fixed width and A.height + B.height as the height – at least that is what I want.

However what I get is that the width of the panel A is not fixed at all (even if I set its preferred size), and the contents in panel C are not automatically wrapping but instead are displayed in a long line. Of course this also makes B having a larger width than it should be.

What can I do to fix that? Is there any better layout, or do I have to emulate that all using an absolute layout?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;

public class Test extends JPanel
{
    public Test ()
    {
        this.setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) );

        JPanel top = new JPanel( null );
        top.setBackground( Color.GREEN );
        top.setPreferredSize( new Dimension( 200, 20 ) );
        JPanel flowPanel = new JPanel( new FlowLayout( FlowLayout.LEFT, 2, 2 ) );

        this.add( top );
        this.add( flowPanel );

        flowPanel.add( new JButton( "x" ) );
        flowPanel.add( new JButton( "x" ) );
        flowPanel.add( new JButton( "x" ) );
        flowPanel.add( new JButton( "x" ) );
        flowPanel.add( new JButton( "x" ) );
        flowPanel.add( new JButton( "x" ) );
        flowPanel.add( new JButton( "x" ) );
        flowPanel.add( new JButton( "x" ) );
        flowPanel.add( new JButton( "x" ) );
        flowPanel.add( new JButton( "x" ) );
        flowPanel.add( new JButton( "x" ) );
        flowPanel.add( new JButton( "x" ) );
    }
}


Wrap Layout should help.


The best way to provide the kind of advanced view configuration you desire is by replacing you FlowLayout by the powerful GridBagLayoutManager. It's worth to note that the constraints, expressed usually by GridBagConstraints, are by far easier to understand when using fluent subclasses, like GBC.

Finally, like always, you should consider taking a look at the Swing tutorial.


  1. You shouldn't add children to the frame directly. Always add to the contentPane -> this.getContentPage().add(...)

  2. To make your layout work, put a JPanel with a GridBagLayout in the content page and make that panel fill the content page.

  3. Give the GridBagLayout 2 columns.

Now you can't disable horizontal resizing of the window, so you must find a different way to handle the extra space. I suggest to give the first column a fixed width (set fill=NONE) and let the panel C fill the remaining space.

If you set all the sizes (min,max,preferred) of the panel B to the preferred size, it should not change it's size anymore.

Tip: If a Swing layout doesn't work, nest it in another layout.


Everything you put in a LINE_END or LINE_START part of a BorderLayout will keep its width constant : Only height will be resized if container is resized

NORTH and SOUTH are width variable

CENTER is width & height variable

LINE_START & LINE_END are only height variable

So, I suggest you put your 'C' container in this kind of BorderLayout area

0

精彩评论

暂无评论...
验证码 换一张
取 消