为什么我需要在 MigLayout 中使用 "X:X" 以便将组件居中放置在多个面板上?

Why do I need to use "X:X" in the MigLayout in order to center components over several panels?

我尝试使用 MigLayout () 将一些组件置于多个面板的中心。 当我将页面拆分为所有面板中相同的百分比时,它突然起作用了。

但是我不得不在每个 grow 前面使用参数“0:0”,我不明白到底发生了什么。

我去了 MigLayout CheatSheet-Page and the QuickStart-guide 但只能找到值为 > 0

的参数

The format is "min:preferred:max", however there are shorter versions since for instance it is seldom needed to specify the maximum size. A single value (E.g. "10") sets only the preferred size and is exactly the same as "null:10:null" and ":10:" and "n:10:n".

Two values (E.g. "10:20") means minimum and preferred size and is exactly the same as "10:20:null" and "10:20:" and "10:20:n"

但它没有解释当您使用 0 作为参数时会发生什么,或者为什么您需要使用 X:X or X:Y 而不是 X:Y:Z or X:X:X

那么为什么我需要在这里使用 X:X 来居中我的组件?

这里重要的是首选大小。在你的另一个问题中,你说你使用了下面的代码来让它工作。

locationPanel.setLayout(new MigLayout("gap rel 2", "[0:0, grow 60, center][grow 40, left]"));
usagePanel.setLayout(new MigLayout("gap rel 2", "[0:0, grow 60, center][grow 40, left]"));
structuralAspectsPanel.setLayout(new MigLayout("gap rel 2", "[0:0, grow 60, center][grow 40, left]"));

如果您写了

,这也会起作用
locationPanel.setLayout(new MigLayout("gap rel 2", "[:0:, grow, center][grow, left]"));
usagePanel.setLayout(new MigLayout("gap rel 2", "[:0:, grow, center][grow, left]"));
structuralAspectsPanel.setLayout(new MigLayout("gap rel 2", "[:0:, grow, center][grow, left]"));
//Obviously you could use any number not just 0

您可以使用的选项是(其中 X <= Y <= Z)

X:Y:Z
X:Y:
:Y:Z
:Y:
:Y

那么为什么要这样做呢?
这样做是因为列以相同的速率增长,并且当您在所有三个面板中设置第一列的首选大小时,您将初始大小设置为 MigLayout 将初始列大小设置为首选大小。

本质上,您将列设置为相同的大小并且它们以相同的速率增长,因此它们彼此保持相同的大小。因此他们保持一致。

工作示例
使用 :Y,其中 YFont Metrics

确定
import java.awt.*;
import javax.swing.*;
import net.miginfocom.swing.MigLayout;

public class MigLay extends JFrame {

    private MigLay() {
        super("Button Layout");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new MigLayout("wrap", //Layout Constraints
        "grow, fill", //Column Constraints
        "grow, fill")); //Row Constraints
        createPanels();
        pack();
        setMinimumSize(getSize()); //Sets minimum size to the preferred size. Remove or change this line if you do not want that to happen
        setVisible(true);
    }

    private void createPanels() {

        JPanel locationPanel = new JPanel();
        JPanel usagePanel = new JPanel();
        JPanel structuralAspectsPanel = new JPanel();

        //JLabels for font metrics
        JLabel one = new JLabel("This is the first of all labels");
        JLabel two = new JLabel("Second Label");
        JLabel three = new JLabel("This Label is fairly large and long and pushes the text around");
        JLabel four = new JLabel("A label in the usage panel");
        JLabel five = new JLabel("And another one and another one and another one");

        //Font Metrics
        FontMetrics metrics = three.getFontMetrics(three.getFont()); //Take longest label manually or dynamically (You will have to add that code)
        int width = metrics.stringWidth(three.getText());

        locationPanel.setLayout(new MigLayout("gap rel 2", "[:" + width + ", grow, center][grow, left]"));
        locationPanel.setBorder(BorderFactory.createTitledBorder("Location"));

        usagePanel.setLayout(new MigLayout("gap rel 2", "[:" + width + ", grow, center][grow, left]"));
        usagePanel.setBorder(BorderFactory.createTitledBorder("Usage"));

        locationPanel.add(one);
        locationPanel.add(new JCheckBox("Checkbox with Label"), "wrap");
        locationPanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        locationPanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        locationPanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        locationPanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        locationPanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        locationPanel.add(new JSeparator(), "growx, span");
        locationPanel.add(two);
        locationPanel.add(new JCheckBox("Checkbox with Label"), "wrap");
        locationPanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        locationPanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        locationPanel.add(new JSeparator(), "growx, span");
        locationPanel.add(three);
        locationPanel.add(new JCheckBox("Checkbox with Label"), "wrap");
        locationPanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        locationPanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");

        usagePanel.add(four);
        usagePanel.add(new JCheckBox("Checkbox with Label"), "wrap");
        usagePanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        usagePanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        usagePanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        usagePanel.add(new JSeparator(), "growx, span");
        usagePanel.add(five);
        usagePanel.add(new JCheckBox("Checkbox with Label"), "wrap");
        usagePanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        usagePanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        usagePanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        usagePanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        usagePanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");
        usagePanel.add(new JCheckBox("Checkbox with Label"), "skip, wrap");

        getContentPane().add(locationPanel);
        getContentPane().add(usagePanel);
    }

    public static void main(String[] args) {
        new MigLay();
    }
}