如何摆脱 Nimbus LAF 中按钮周围的 space?

How to get rid of the space around buttons in Nimbus LAF?

我需要将一些 JButton 放在一个非常小的地方,问题是 Nimbus LAF 会自动将一些 space 放在它们周围,结果按钮看起来比实际小。

在下面的示例程序中,我使用了水平和垂直间隙为 0 的 FlowLayout,并且我希望按钮之间没有任何 space。如果我注释掉 Nimbus LAF 的设置,它们会按预期运行。

import javax.swing.*;
import java.awt.FlowLayout;

public class NimbusSpace {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                buildGUI();
            }
        });
    }

    private static void buildGUI() {
        try {
            UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
        p.add(createButton("aa"));
        p.add(createButton("bb"));
        p.add(createButton("cc"));

        f.add(p);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static JButton createButton(String text) {
        JButton b = new JButton(text);

//        b.setBorder(null);
//        b.setBorderPainted(false);
//        b.setMargin(new Insets(0,0,0,0));
//        b.putClientProperty("JComponent.sizeVariant", "large");
//        b.putClientProperty("JComponent.sizeVariant", "mini");

//        UIDefaults def = new UIDefaults();
//        def.put("Button.contentMargins", new Insets(0,0,0,0));
//        b.putClientProperty("Nimbus.Overrides", def);

        return b;
    }
}

正如您在 createButton 中注释掉的代码中看到的那样,我尝试了很多方法,但他们没有删除按钮周围的 space。

编辑:根据评论中的讨论,似乎无法删除按钮的矩形边缘与绘制的矩形边缘之间的space圆角矩形轮廓。 Nimbus 为 "focus highlight" 保留了这两个像素,如果不重新实现大量 Nimbus 功能,这可能无法更改。

所以我接受了 guleryuz 的把戏:如果按钮位于重叠和负位置,它们可以看起来更大。在实践中这个想法似乎可行,但它不是一个非常干净的解决方案,所以如果您知道更好(并且相当容易实施)的解决方案,请不要犹豫回答...

请注意,如果您设置背景颜色然后调用 setOpaque(true),您会看到按钮彼此正对着。这就是 Nimbus 绘制按钮的方式;我认为您不能更改按钮的矩形边缘和绘制的 rounded-rectangle 轮廓之间的 space。

如果 space 是溢价,您可以通过取消注释 UIDefaults 行并修改 contentMargins 属性(但不要使用 0,0,0,0,使用类似 2,8,2,8) 的东西。

方法一:

JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT, -4, 0));

方法二:

    JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
    p.add(createButton("aa", 1));
    p.add(createButton("bb", 2));
    p.add(createButton("cc", 3));

对 createButton 方法进行了一些修改

private static JButton createButton(String text, final int s) {
    JButton b = new JButton(text){
        @Override
        public void setLocation(int x, int y) {
            super.setLocation(x-(s*4), y);
        }
    };
    return b;
}

方法 3

JPanel p = new JPanel(new MigLayout("ins 0, gap -5","[][][]"));