Java Swing BoxLayout ignoring AlignmentX
Asked Answered
G

2

6

In the code below, by calling setAlignmentX with Component.LEFT_ALIGNMENT I expected to get a left aligned label over a centered slider. For some reason the label is also centered, seemingly regardless of what value is passed to setAlignmentX.

What value must I pass to setAlignmentX to get it left aligned?

package myjava;

import java.awt.Component;
import java.awt.Container;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;

public class LayoutTest {

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("BoxLayoutDemo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                // create left aligned label over centered column
                Container contentPane = frame.getContentPane();
                contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
                JLabel label = new JLabel("test");
                label.setAlignmentX(Component.LEFT_ALIGNMENT);
                contentPane.add(label);
                contentPane.add(new JSlider());

                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
Gurevich answered 10/2, 2012 at 13:43 Comment(0)
N
8

Basically, you can't have different alignments in BoxLayout, from How To Use BoxLayout

In general, all the components controlled by a top-to-bottom BoxLayout object should have the same X alignment.

Edit

Typically, it's not documented which default alignment a component type has (JSlider is centered by default, me incorrectly thought that a JLabel were centered while it is left-aligned ;-) One option is to keep a list somewhere (dooooh...), another is to simply force them all to the same alignment on adding.

Or use a third-party layoutManager, which doesn't have this rather unintuitve (for me) mix-in of layout and alignment.

Nielson answered 10/2, 2012 at 13:52 Comment(5)
I read that page but I thought that the slider "didn't have" an alignment. Whats the best way to enforce same alignment on all components?Gurevich
Unintuitive would be the understatement of the day. But at least I got it working now. Thanks! :)Gurevich
As of 2021 this answer is false (at least for Java 11). This can easily be shown by setting the layout in question to your container via setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) ); and then using .setAlignmentX( int ); on subcomponents. For 0 these are aligned left and the higher the value, the further these components are shifted to the right. So you can have different alingments for BoxLayout - whether this is intentional or not.Maidenhead
This means definitions such as Component.LEFT_ALIGNMENT can be used to set alignment for the BoxLayout.Maidenhead
@Maidenhead hmm .. don't know what you mean: the mixed alignment in the question (label == LEFT and slider == CENTER) still leads to unpredictable layout (here the label appears to be centered as well, but the output for differenct mixtures can be anything). Afaict, there was no change in versions, tested against java12.Nielson
B
0

BoxLayout have strange behavior. Try to use GridBagLayout instead:

https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html

public class Aligment {
  public static void main(String[] args) {

    final JPanel root = new JPanel(new GridBagLayout());
    root.setPreferredSize(new Dimension(500, 400));

    root.add(new JLabel("LEFT"), new GridBagConstraints() {{
        gridx = 0; 
        gridy = 0; 
        anchor = PAGE_START; 
    }});
    root.add(new JLabel("CENTER"), new GridBagConstraints() {{
        gridx = 1;
        gridy = 1; 
        anchor = CENTER; 
        weightx = 1.0; // fill Width
    }});
    root.add(new JLabel("RIGHT"),  new GridBagConstraints() {{ 
        gridx = 2; 
        gridy = 2; 
        anchor = LINE_END; 
    }});
    // hack: Push all rows to Top
    root.add(Box.createVerticalGlue(), new GridBagConstraints() {{
        gridx = 0; 
        gridy = 3; 
        weighty = 1.0; // fill Height
    }});

    new JFrame() {
      {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setContentPane(root);
        pack();
        setLocationRelativeTo(null);;
      }
    }.setVisible(true);
  }
}
Boutwell answered 3/6, 2015 at 7:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.