Java: MigLayout Center 中心不工作 |绝对定位的替代方案

Java: MigLayout Center Center not working | alternative for absolute positioning

元素不会垂直居中,我不知道为什么。我试过 "center center",但没有用。

MigLayout

private JPanel panel = new JPanel(new MigLayout("center center, filly"));

组件

panel.add(header, "span");
panel.add(input, "split 4");
panel.add(unit1);
panel.add(to);
panel.add(unit2, "wrap");
panel.add(convert, "span");
panel.add(output, "span");

我想将组件居中,但是不能使用绝对定位(因为我知道如何使用这种方法居中)

TL;DR

你真丢脸但是

  • center center 不是 center, center
  • center, center, filly - filly 减轻垂直中心
  • 要对齐各个组件,您需要 align center - 例如,panel.add(new JLabel("Header"), "span, align center");

假设您询问如何水平对齐组件,您需要针对每个组件进行指定。但是,首先最好看看下面这行代码实际上做了什么。

private JPanel panel = new JPanel(new MigLayout("center center, filly"));

或者更具体地说,以下摘录的含义。

new MigLayout("center center, filly")

center center - 这会水平对齐 JPanel.

上的打包组件

假设您试图让组件垂直和水平居中,您实际上需要 center, center。注意两个 center 关键字之间的 ,

filly - 引用白皮书,"Claims all available space in the container for the columns and/or rows".

这大大减轻了 "center, center" 的影响,您真正需要的只是 center, filly.


现在要在多列中水平对齐组件,您需要将关键字 align center 添加到要对其执行此操作的每个组件。例如

panel.add(new JLabel("Header"), "span, align center");

你的组件的一个例子是

String[] dummyList  = new String[] {
    "Val 1",
    "Val 2"
};
JPanel migPanel = new JPanel(new MigLayout("center, filly")); //Maybe you wanted center, center. I'm not sure
migPanel.add(new JLabel("Header"), "span, align center");
migPanel.add(new JTextField("Input"), "split 4");
migPanel.add(new JComboBox<String>(dummyList));
migPanel.add(new JLabel("To"), "span");
migPanel.add(new JComboBox<String>(dummyList), "wrap");
migPanel.add(new JButton("Convert"), "span, align center");
migPanel.add(new JTextField("Output"), "span, align center");

因为 MadProgrammer mentioned there are other layouts that can be used to achieve a very similar look to what you had; GridBagLayout 是最简单的。

混合使用 GridBagConstraints 您可以获得非常相似的布局。

例如,

String[] dummyList  = new String[] {
    "Val 1",
    "Val 2"
};
JPanel gridBagPanel = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();

gc.weighty = 1; //Delete this line if you are after an equivalent of `center, center` from the MigLayout
gc.gridwidth = 4;
gridBagPanel.add(new JLabel("Header"), gc);

gc.gridy = 1;
gc.gridwidth = 1;
gridBagPanel.add(new JTextField("Input"), gc);

gc.gridx = 1;
gridBagPanel.add(new JComboBox<String>(dummyList), gc);

gc.gridx = 2;
gridBagPanel.add(new JLabel("To"), gc);

gc.gridx = 3;
gridBagPanel.add(new JComboBox<String>(dummyList), gc);

gc.gridy = 2;
gc.gridx = 0;
gc.gridwidth = 4;
gridBagPanel.add(new JButton("Convert"), gc);

gc.gridy = 3;
gridBagPanel.add(new JTextField("Output"), gc);

可运行示例 - LayoutExample.java

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

import net.miginfocom.swing.MigLayout;

@SuppressWarnings("serial")
public class LayoutExample extends JFrame {
    private JTabbedPane tabs;
    private JPanel migPanel;
    private JPanel gridBagPanel;
    private JPanel migPanelCC;
    private JPanel gridBagPanelCC;
    private String[] dummyList  = new String[] {
        "Val 1",
        "Val 2"
    };

    private LayoutExample() {
        super("Layout Example");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setUpTabs();
        add(tabs);

        setSize(800, 500);
        setVisible(true);
    }

    private void setUpTabs() {
        tabs = new JTabbedPane();

        setUpMig();
        tabs.add(migPanel, "Mig Panel");

        setUpMigCC();
        tabs.add(migPanelCC, "Mig Panel Center Center");

        setUpGridBag();
        tabs.add(gridBagPanel, "Grid Bag Panel");

        setUpGridBagCC();
        tabs.add(gridBagPanelCC, "Grid Bag Panel Center Center");
    }

    private void setUpMig() {
        migPanel = new JPanel(new MigLayout("center, filly"));
        addToMigPanel(migPanel);
    }

    private void setUpMigCC() {
        migPanelCC = new JPanel(new MigLayout("center, center"));
        addToMigPanel(migPanelCC);
    }

    private void addToMigPanel(JPanel mPanel) {
        mPanel.add(new JLabel("Header"), "span, align center");
        mPanel.add(new JTextField("Input"), "split 4");
        mPanel.add(new JComboBox<String>(dummyList));
        mPanel.add(new JLabel("To"), "span");
        mPanel.add(new JComboBox<String>(dummyList), "wrap");
        mPanel.add(new JButton("Convert"), "span, align center");
        mPanel.add(new JTextField("Output"), "span, align center");
    }

    private void setUpGridBag() {
        gridBagPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gc = new GridBagConstraints();

        gc.weighty = 1;
        addToGridBagPanel(gridBagPanel, gc);
    }

    private void setUpGridBagCC() {
        gridBagPanelCC = new JPanel(new GridBagLayout());
        GridBagConstraints gc = new GridBagConstraints();

        addToGridBagPanel(gridBagPanelCC, gc);
    }

    private void addToGridBagPanel(JPanel gblPanel, GridBagConstraints gc) {
        gc.gridwidth = 4;
        gblPanel.add(new JLabel("Header"), gc);

        gc.gridy = 1;
        gc.gridwidth = 1;
        gblPanel.add(new JTextField("Input"), gc);

        gc.gridx = 1;
        gblPanel.add(new JComboBox<String>(dummyList), gc);

        gc.gridx = 2;
        gblPanel.add(new JLabel("To"), gc);

        gc.gridx = 3;
        gblPanel.add(new JComboBox<String>(dummyList), gc);

        gc.gridy = 2;
        gc.gridx = 0;
        gc.gridwidth = 4;
        gblPanel.add(new JButton("Convert"), gc);

        gc.gridy = 3;
        gblPanel.add(new JTextField("Output"), gc);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new LayoutExample());
    }
}

最后,使用绝对定位是个坏主意。这是因为当容器改变大小时,容器内的组件不会自动调整。这对大多数事情都不起作用,因为你可能会很快丢失重要的 UI 组件,或者你可能会加载额外的白色 space.