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);
            }
        });
    }
}
Mizipzor
  • 51,151
  • 22
  • 97
  • 138

2 Answers2

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.

kleopatra
  • 51,061
  • 28
  • 99
  • 211
  • 1
    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? – Mizipzor Feb 10 '12 at 13:56
  • Unintuitive would be the understatement of the day. But at least I got it working now. Thanks! :) – Mizipzor Feb 10 '12 at 14:17
  • 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. – Koenigsberg Sep 30 '21 at 13:20
  • This means definitions such as `Component.LEFT_ALIGNMENT` can be used to set alignment for the `BoxLayout`. – Koenigsberg Sep 30 '21 at 13:23
  • @Koenigsberg 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. – kleopatra Sep 30 '21 at 15:05
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);
  }
}
Grigory K
  • 1,301
  • 10
  • 10