java - MigLayout:奇怪的间隙行为

标签 java swing miglayout

我对 MigLayout 有一些奇怪的行为。我有一个 SSCCE 反射(reflect)了我的问题。基本上,顶部两个面板之间有一个间隙(该间隙属于左侧单元格)。其他一切都如我所愿。仅当 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);
    }
}

最佳答案

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

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 代码比将它们分散在单元格中更易于维护。

关于java - MigLayout:奇怪的间隙行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16841467/

相关文章:

java - 为什么这个 while 循环在满足条件后才运行?

java - 带有 JTable 的 JScrollpane 中的背景图像

java - JComboBox,如果所选项目发生更改或选择相同的项目,则触发操作

java - Swing MigLayout - 无法避免不必要的间隙

java - MigLayout "wrap"行为不一致

java - 在 IntelliJ 中创建 gradle 项目的问题

java - 定时器任务不起作用!

java - 我怎样才能显示jpanel?

java - 绝对定位(无布局管理器)与 MiGlayout 中的绝对定位

java - JPAEntityManagerFactory.createEntityManager()在getter中,何时缓存/重用?