0

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

SSCCE

左侧面板(名为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);
    }
}
4

2 回答 2

2

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

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在布局约束中定义 a 。

更新

只记得其中一个怪癖:跨越情节行中的推动(实际上是隐含的 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 代码比将它们分散在单元格中更易于维护。

于 2013-06-25T08:54:13.813 回答
1

问题在于您的measurement panel. 您plot panel在新行中添加具有属性的新行,span, push, grow并且当您调整框架的大小时,单元格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();
            }
        });
    }

}

这就是你将得到的: 在此处输入图像描述

祝你好运!

于 2013-05-30T16:57:22.927 回答