Search code examples
javaswinglayout-managergridbaglayoutboxlayout

Box Layout Won't Align Left


I have a custom panel (APanel). Two questions:

  1. I need the label ("Top Label") and sub panel (bPanel) to align on the left side of the panel. bPanel is aligning on the left side but Top Label is being place in the middle. How do I fix?

    enter image description here

  2. How do I set the label and bPanel so they don't change in vertical size and maintain the same vertical distance between each other when the entire frame is expanded? In other words, how do I prevent the below from happening?

    enter image description here

Code for APanel and bPanel are below. In case it matters, APanel is loaded as the CENTER component in a JFrame set to BorderLayout (not including the frame code here).

public class APanel extends JPanel {

    private JLabel jLabel1;
    private BPanel bPanel; 

    public APanel () {
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 

        jLabel1 = new JLabel("Top Label", JLabel.LEFT);
        jLabel1.setHorizontalAlignment(SwingConstants.LEFT);
        jLabel1.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 
        add(jLabel1);

        bPanel = new BPanel();
        bPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        add(bPanel); 

        this.setAlignmentX(LEFT_ALIGNMENT);

    }

    private class bPanel extends JPanel {
        private JLabel sLabel;
        private JLabel tLabel;

        public bPanel() {
            sLabel = new JLabel("Jeepers");
            tLabel = new JLabel("Creepers");

            setLayout(new GridBagLayout());           
            GridBagConstraints gc = new GridBagConstraints();

            gc.gridx = 0;
            gc.gridy = 0;
            gc.weightx = 1;
            gc.weighty = 1;
            gc.fill = GridBagConstraints.HORIZONTAL;
            add(sLabel, gc);

            gc.gridx = 1;
            add(tLabel, gc);

        }
    }
}

Solution

  • I need the label ("Top Label") and sub panel (bPanel) to align on the left side of the panel.

    jLabel1.setHorizontalAlignment(SwingConstants.LEFT);
    

    Wrong method to control alignment with respect to the container. Read the JLabel API. That method is used to align the text within the bounds of the JLabel, in case the size of the label is greater than the preferred size of the text.

    this.setAlignmentX(LEFT_ALIGNMENT);
    

    Close, but that is not needed because if refers to the alignment of this entire panel in its parent container.

    Instead, you need to set the "alignment" of all the components you are adding the this panel using the vertical BoxLayout. Each component may have a different default value. Some will default to "left" and some to "center".

    Read the section from the Swing tutorial on Fixing Alignment Problems for more information.

    How do I set the label and bPanel so they don't change in vertical size and maintain the same vertical distance between each other when the entire frame is expanded?

    The BoxLayout will allow components to grow (up to their maximum size) when extra space is available. For a JLabel the maximum size is the same as its preferred size. For a JPanel the maximum size is the value of Integer.MAX_VALUE.

    So you can override the getMaximumSize() method of you panel with code something like:

    @Override
    public Dimension getMaximumSize()
    {
        Dimension preferred = getPreferredSize();
        Dimension maximum = super.getMaximumSize();
        maximum.height = preferred.height;
    
        return maximum;
    }
    

    Or another option is to wrap the panel in another panel that will respect the height. For example.

    JPanel wrapper = new JPanel( new BorderLayout() );
    wrapper.add(bPanel, BorderLayout.PAGE_START);
    add(wrapper);
    //add(bPanel);