当仅使用一个单元格时,如何在Miglayout中强制每行4个单元格具有相等的宽度?

时间:2019-01-15 10:08:23

标签: java swing layout-manager miglayout

我有一个动态宽度的面板。添加到面板中的组件应从左到右排列,每行最多4个组件(单元),其中每个组件/单元占面板宽度的25%。如果只有一个分量,则它应占父宽度的25%-其余的75%(3个单元格)空间应为空。

我使用hack使其正常工作,但是我对该实现并不满意-使用单元格并为每个未使用的单元格创建一个“空”面板。请参见下面的代码段:

MigLayout migLayout = new MigLayout("fillx, insets 0, wrap 4", "", "");
JPanel panel = new JPanel(migLayout);
JLabel label1 = new JLabel("1");
JLabel label2 = new JLabel("2");
JPanel filler1 = new JPanel();
JPanel filler2 = new JPanel();
panel.add(label1, "cell 0 0);
panel.add(label2, "cell 1 0);
panel.add(filler1, "cell 2 0);
panel.add(filler2 , "cell 3 0);

这提供了如下所示的内容,其中外括号是外面板,两个内括号是标签:

[  [ 1 ]  [ 2 ]                ]

我希望不使用填充符,而是可以设置约束,像这样:

MigLayout migLayout = new MigLayout("always 4 cells, fillx", "[fill][fill][fill][fill]", "");
JPanel panel = new JPanel(migLayout);
JLabel label1 = new JLabel();
JLabel label2 = new JLabel();
panel.add(label1);
panel.add(label2);

我尝试了各种布局约束并添加了组件参数,但是它们的格式通常如下:

[  [ 1 ]         [ 2 ]         ]

3 个答案:

答案 0 :(得分:1)

我会选择GridLayout。 GridLayout会根据给定的行数/列数将面板分为多个单元格(检查其构造函数)。然后,每个组件将适合单元格100%(宽度和高度)。

但是::如果将网格布局设置为1行和4列(根据您的情况),并且仅添加1个组件,则布局将被调整为:1行和1列,因为它赢得了不要让空白。

技巧/解决方案:添加一个空组件的方式与向BoxLayout添加间隙的方式完全相同。

private static Component createSpace() {
    return Box.createRigidArea(new Dimension(1, 1));
}

缺点: 如果要在显示后在面板中添加组件,则必须删除空格,因此必须将所有空组件存储到结构中或执行以下操作(我总是喜欢):

gridLayoutPanel.removeAll();
gridLayoutPanel.add(component1);
gridLayoutPanel.add(newComponent); //This was space before
gridLayoutPanel.add(createSpace());
gridLayoutPanel.add(createSpace());
gridLayoutPanel.repaint();
gridLayoutPanel.revalidate();

SSCCE是(忽略组件的高度):

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class GridLayoutTest extends JFrame {
    public GridLayoutTest() {
        getContentPane().setLayout(new GridLayout(1, 4));
        JButton component1 = new JButton("Component1");
        JButton component2 = new JButton("Component2");
        JButton component3 = new JButton("Component3");
        add(component1); //25% of the width
        add(component2); //25% of the width
        add(component3); //25% of the width
        add(createSpace()); //25% of the width
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(500, 200);
        setLocationRelativeTo(null);
    }

    private static Component createSpace() {
        return Box.createRigidArea(new Dimension(1, 1));
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new GridLayoutTest().setVisible(true));
    }
}

答案 1 :(得分:0)

您可以在列约束中使用%,并记住添加“!”这样每一列都有固定的宽度。

MigLayout migLayout = new MigLayout("wrap 4, fill", "[25%!,fill][25%!,fill][25%!,fill][25%!,fill]");
JPanel panel = new JPanel(migLayout);
JLabel label1 = new JLabel();
JLabel label2 = new JLabel();
panel.add(label1, "grow"); // add grow here if you want to fill up the 25%
panel.add(label2, "grow");

还要查看http://www.miglayout.com/whitepaper.html,所有miglayout技巧都包含在其中

答案 2 :(得分:0)

可能有点晚了,但是我认为这是解决方案:

public class Test extends JFrame {

    public Test() {
        // Col Constraint
        String ccol="[fill, 25%:25%:25%]";
        // Cell Constraint
        String ccell="";
        MigLayout migLayout = new MigLayout("debug, fillx, insets 5, wrap 4", ccol+ccol+ccol+ccol, "");
        Container panel = getContentPane();
        panel.setLayout(migLayout);
        MyComponent label;

        // row 1
        label = new MyComponent("1.1");
        panel.add(label, ccell + "cell 0 0");
        label = new MyComponent("1.2");
        panel.add(label, ccell + "cell 1 0");

        // row 2
        label = new MyComponent("2.1");
        panel.add(label, ccell + "cell 0 1");


        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(500, 200);
        setLocationRelativeTo(null);
    }



    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Test().setVisible(true));
    }

    private static class MyComponent extends JLabel {

        public MyComponent(String text) {
            super(text);
            setOpaque(true);
            setBackground(Color.YELLOW);
        }

    }

}