Reputation: 160
I am trying to align three buttons on a Jpanel using Miglayout. Button1 is aligned 50% 50% of the Jpanel and Button2 and Button3 are aligned adjecent to each other at 50% 80%. It seems like this should be easy, but I cannot get all of the buttons to align properly. Here is a snippet of my code:
panel = new JPanel();
panel.setLayout(new MigLayout());
this.add(panel);// add to JFrame
JButton Button1 = new JButton("Button 1");
Button1.setPreferredSize(new Dimension(200,70));
JButton Button2 = new JButton("Button 2");
Button2.setPreferredSize(new Dimension(200,70));
JButton Button3 = new JButton("Button 3");
Button3.setPreferredSize(new Dimension(200,70));
panel.add(Button1, "push,align 50% 50%");
panel.add(Button2, "split,align 50% 80%");
panel.add(Button3, "push,align 50% 80%");
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.pack();
As you can see in the attached picture, the horizontal alignment is not as intended. However, if I add only Button1 or Button2 and Button3, the alignment is correct. How can I fix it?
Upvotes: 0
Views: 113
Reputation: 7724
MigLayout
is not really designed to work like that. It is not to say it is not possible, because there are a few workarounds, but they are not ideal.
The way MigLayout
works is it uses a grid to place components. When you add a component to a container that uses MigLayout
as the layout, it adds them in a horizontal order.
The way the align
attribute works is it trys to align the cells for that row as close as possible to what you ask it to, relative to the row and column you are currently in. It does not allow these cells to overlap.
That is why it does not seem to work for you, because you are trying to make the cells overlap.
Therefore, for what you are doing to work, you would need at least 2 rows and then to calculate how to align the component relative to each row. This is explained in the workaround section.
You can see what your code actually looks like by setting the MigLayout
layout to debug
mode with new MigLayout("debug")
.
Your Attempt
The Workaround
You could use some simple weighting to achieve this mixed with a little math.
Step 1 - Assign a weight for the rows height to grow at. I chose 70 for the first column and 30 for the second column. This means that when the rows get assigned height space, if there is room, the first row will take 70% of the space and the second row will take 30% of the space.
Step 2 - Using this weighting work out where the vertical positions of 50% and 80% on the whole container. In this case 50 / 70 ≈ 71% and 10 / 30 ≈ 33%. (The 10 comes from 80% - 70%)
Step 3 - Use these vertical alignment figures to line up the buttons.
Runnable Example
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame("Relative Panel");
JPanel panel = new JPanel(new MigLayout("", "", "[grow 70][grow 30]"));
JButton Button1 = new JButton("Button 1");
Button1.setPreferredSize(new Dimension(200,70));
panel.add(Button1, "push,align 50% 71%, wrap");
JButton Button2 = new JButton("Button 2");
Button2.setPreferredSize(new Dimension(200,70));
panel.add(Button2, "split,align 50% 33%");
JButton Button3 = new JButton("Button 3");
Button3.setPreferredSize(new Dimension(200,70));
panel.add(Button3, "push,align 50% 33%");
frame.add(panel);
frame.setPreferredSize(new Dimension(800, 800));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Upvotes: 1