Reputation: 336
I have a JPanel with a BoxLayout manager that contains subpanels. I want the components inside these subpanels to have a left alignment, but they always appear centered. It looks like BoxLayout correctly aligns components that are inserted directly, but fails to do that when they are inside a subpanel.
I have modified the example found in http://www.java2s.com/Tutorial/Java/0240__Swing/YAxisAlignment.htm so each button is placed inside a subpanel, and then the subpanel is placed inside the main panel with the BoxLayout manager:
public class YAxisAlignX {
private static Container makeIt(String title, float alignment) {
String labels[] = { "--", "----", "--------", "------------" };
JPanel container = new JPanel();
container.setBorder(BorderFactory.createTitledBorder(title));
BoxLayout layout = new BoxLayout(container, BoxLayout.Y_AXIS);
container.setLayout(layout);
// modified loop. the original version does not create JPanel pan.
// adds the buttons directly the the JPanel container with the
// BoxLayout
for (int i = 0, n = labels.length; i < n; i++) {
JPanel pan = new JPanel();
JButton button = new JButton(labels[i]);
pan.add(button);
button.setAlignmentX(alignment);
pan.setAlignmentX(alignment);
container.add(pan);
}
return container;
}
public static void main(String args[]) {
JFrame frame = new JFrame("Alignment Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container panel1 = makeIt("Left", Component.LEFT_ALIGNMENT);
Container panel2 = makeIt("Center", Component.CENTER_ALIGNMENT);
Container panel3 = makeIt("Right", Component.RIGHT_ALIGNMENT);
Container contentPane = frame.getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(panel1);
contentPane.add(panel2);
contentPane.add(panel3);
frame.pack();
frame.setVisible(true);
}
}
If you execute this version, you can see that the buttons are all centered, despite the alignment set. Why is this happening? Is there any solution? In my case, every subpanel contains several components, and I do not want to add then directly to the main panel.
Thank you very much.
Upvotes: 1
Views: 681
Reputation: 2468
But they are aligned!
First of all, setAlignmentX
changes a property at a JComponent level, the layout in which these components are placed may or may not use this information. For example, BoxLayout
uses it but FlowLayout
and BorderLayout
don't.
In your case you are placing some panels with a vertical BoxLayout and you are aligning them in various ways, and it works! It just so happens that the the panels stretch themselves to fit the whole column so actually aligning doesn't change their appearance. You can see this by setting a Border around the panels:
pan.setBorder(BorderFactory.createLineBorder(Color.red));
See:
The fact that the panels contain a button or anything else is mostly irrelevant (it only influences the size that the panel wants to take, and not definitely), the BoxLayout is aligning panels not what is there inside the panels, that's the work of each panel's layout. That's why the buttons wouldn't have its alignment affected by the BoxLayout
.
Now how are those buttons deciding its alignment? Well that's up to the layout they are in. The buttons are inside the pan
panel that is using the default LayoutManager FlowLayout
. Now, as I said, FlowLayout doesn't care for the alignmentX/Y property so the line:
button.setAlignmentX(alignment);
Doesn't accomplish anything. To align in a FlowLayout you need to change its alignment
field through FlowLayout.setAligment(int)
(docs), you can also do this in the constructor, so If we change the pan
declaration to:
JPanel pan = new JPanel(new FlowLayout(FlowLayout.LEFT));
You'll also have the buttons aligned to the left inside their panels:
Of course, all the columns are aligned to the left since the parameter float alignment
of makeIt
does not influence the FlowLayout's alignment just the BoxLayout's one (and it doesn't matter). You might want to change that argument to an int and call the function with the different FlowLayout
constants.
All in all, in the original version the line button.setAlignmentX(alignment);
made sense because the buttons were added directly to the container
panel and the BoxLayout aligned them properly:
However once you put the buttons inside other panels, the BoxLayout starts aligning the panels (which because of how panels works inside a BoxLayout they were being stretched to fill the whole width) not the buttons, and the buttons alignment is up to the panels layout. That's how it has to work so we can make consistent nested layouts.
I hope that's clear.
Upvotes: 2