【问题标题】:MigLayout: strange gap behaviourMigLayout:奇怪的间隙行为
【发布时间】:2013-05-30 16:32:29
【问题描述】:

我对 MigLayout 有一些奇怪的行为。我有一个反映我的问题的 SSCCE。基本上,顶部两个面板之间存在间隙(该间隙属于左侧单元格)。其他一切都如我所愿。仅当JFrame 调整大小且足够大时才会出现间隙。

左侧面板(名为Measurement)应具有固定宽度,而中间面板(名为Config)为pushx, growx,因此应填充该行上其他两个组件留下的所有空间。但左面板单元格似乎偷走了剩余的空间。

如何删除该空间(以便配置面板直接接触测量面板并且测量面板的宽度正好为 500 像素)?

我正在使用 MigLayout 4.0。

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

import net.miginfocom.swing.MigLayout;

public class Main {
    private static JButton minimizeButton;
    private static JPanel configPanel, plotPanel, measPanel;

    public static void main(final String[] args) {
        final JFrame frame = new JFrame("test");

        frame.setLayout(new MigLayout("insets 10, hidemode 3, debug", "", ""));

        frame.add(getMeasPanel(), "w 500!");
        frame.add(getConfigPanel(), "left, grow, pushx");
        frame.add(getMinimizeButton(), "right, top, wrap");
        frame.add(getPlotPanel(), "spanx 3, grow, push, wrap");

        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private static JPanel getConfigPanel() {
        if (configPanel == null) {
            configPanel = new JPanel(new MigLayout("insets 10"));
            configPanel.add(new JLabel("test123"), "spanx 2, wrap");
            configPanel.add(new JLabel("test123"), "h 40!");
            configPanel.add(new JLabel("test123"), "right, wrap");
            configPanel.setBorder(BorderFactory.createTitledBorder(null,
                    "Plot", TitledBorder.LEFT, TitledBorder.TOP, new Font(
                            "null", Font.BOLD, 12), Color.BLUE));
        }
        return configPanel;
    }

    private static JButton getMinimizeButton() {
        if (minimizeButton == null) {
            minimizeButton = new JButton("_");
            minimizeButton.setFocusPainted(false);
            minimizeButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    toggleConfigMinimize();
                }
            });
        }
        return minimizeButton;
    }

    private static JPanel getPlotPanel() {
        if (plotPanel == null) {
            plotPanel = new JPanel();
            plotPanel.setBorder(BorderFactory.createTitledBorder(null,
                    "Plot Config", TitledBorder.LEFT, TitledBorder.TOP,
                    new Font("null", Font.BOLD, 12), Color.BLUE));
        }
        return plotPanel;
    }

    private static JPanel getMeasPanel() {
        if (measPanel == null) {
            measPanel = new JPanel(new MigLayout("insets 10"));
            measPanel.add(new JLabel("test123"), "spanx 2, wrap");
            measPanel.add(new JLabel("test123"), "h 40!");
            measPanel.add(new JLabel("test123"), "right, wrap");
            measPanel.add(new JLabel("test123"), "spanx 2, wrap");
            measPanel.add(new JLabel("test123"), "spanx 2, wrap");
            measPanel.setBorder(BorderFactory.createTitledBorder(null,
                    "Measurement", TitledBorder.LEFT, TitledBorder.TOP,
                    new Font("null", Font.BOLD, 12), Color.BLUE));
        }
        return measPanel;
    }

    private static boolean showConfig = true;

    protected static void toggleConfigMinimize() {
        showConfig = !showConfig;
        getMeasPanel().setVisible(showConfig);
        getConfigPanel().setVisible(showConfig);
    }
}

【问题讨论】:

    标签: java swing miglayout


    【解决方案1】:

    一种解决方案是在列约束中定义配置列的增长行为:

    frame.setLayout(new MigLayout("insets 10, hidemode 3, debug",
            "[][fill, grow][]", ""));
    frame.add(getMeasPanel(), "w 500!");
    frame.add(getConfigPanel(), "left, grow");
    frame.add(getMinimizeButton(), "right, top, wrap");
    frame.add(getPlotPanel(), "spanx 3, grow, wrap, push");
    

    推送单元约束存在一些怪癖(阅读:我个人不完全理解的行为:-),因此我倾向于尽可能避免它们。另外,我的偏好是在布局约束中定义 wrap 3

    更新

    只记得一个怪癖:跨越情节行中的 push(实际上是隐含的 pushx)是真正的罪魁祸首 - 它的多余空间进入了它的第一列。想一想,这种行为并非不合理,毕竟细胞约束是关于……细胞,它们不太关心其他细胞。

    因此,另一种解决方案是仅在 y 中使绘图具有压力(x 推送已由其上方第二列中的配置单元处理)

    frame.setLayout(new MigLayout("insets 10, hidemode 3, debug",
            // cell constraints are empty in original
            "",
            ""));
    
    // meas should have a fixed size
    frame.add(getMeasPanel(), "w 500!");
    // the config should get all excess space when growing
    frame.add(getConfigPanel(), "left, grow, pushx");
    frame.add(getMinimizeButton(), "right, top, wrap");
    // remove implicit the pushx
    frame.add(getPlotPanel(), "spanx 3, grow, wrap, pushy");
    

    我的偏好是第一个:在(约束)层次结构中尽可能多地进行配置,使 ui 代码比将它们分散在单元格中更易于维护。

    【讨论】:

    • 太棒了!感谢您的回答,这正是我正在寻找的。​​span>
    【解决方案2】:

    问题在于您的measurement panel 的大小固定。您在具有span, push, grow 属性的新行中添加plot panel 并且当您调整框架大小时,measurementconfig 面板的两个单元格也将调整大小,但您的measurement 面板的大小将根据w 500! 属性。我的建议是强制增长measurementconfig 面板及其单元格。

    像这样:

    import javax.swing.BorderFactory;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    import net.miginfocom.swing.MigLayout;
    
    public class MigTest {
        JFrame frame = new JFrame();
        JPanel msmPanel = new JPanel();
        JPanel configPanel = new JPanel();
        JPanel plotPanel = new JPanel();
        JLabel lbl1 = new JLabel("Test 123");
        JLabel lbl2 = new JLabel("Test 123");
    
        public MigTest() {
            frame.setLayout(new MigLayout());
            msmPanel.add(lbl1);
            configPanel.add(lbl2);
            msmPanel.setBorder(BorderFactory.createTitledBorder("Measurement"));
            configPanel
                    .setBorder(BorderFactory.createTitledBorder("Configuration"));
            plotPanel.setBorder(BorderFactory.createTitledBorder("Plot"));
            frame.add(msmPanel, "pushx,grow");
            frame.add(configPanel, "pushx, grow, wrap");
            frame.add(plotPanel, "span, push, grow");
    
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new MigTest();
                }
            });
        }
    
    }
    

    这就是你会得到的:

    祝你好运!

    【讨论】:

    • 感谢您的建议。不幸的是,这不是我想要的。我需要测量面板保持固定宽度。不能将单元格设置为固定宽度吗?我尝试使用shrinkx,但这也不起作用。
    猜你喜欢
    • 1970-01-01
    • 2012-07-11
    • 2018-01-25
    • 1970-01-01
    • 2012-01-30
    • 2014-09-30
    • 2012-03-20
    • 1970-01-01
    • 2011-01-28
    相关资源
    最近更新 更多