如何从JMenuItem(Java Swing)中删除空图标间隙?

如何从JMenuItem(Java Swing)中删除空图标间隙?,java,swing,imageicon,jmenuitem,Java,Swing,Imageicon,Jmenuitem,TL;DR 有没有办法消除菜单项边框和定义文本之间的图标间隙?它会在我创建菜单项时立即出现,即使我没有设置图标,或者如果我将图标设置为空 长版本 我们公司开发的Java应用程序自90年代就存在了。在2000年,它重新设计了风格,曾经有一个可怕的,我指的是花哨和多彩的,“合成”主题。因此,现在是时候变得更严肃、更知名,拥有更优雅、更现代的L&F了。这就是为什么我从SyntheticaLookAndFeel切换到内置的SystemLookAndFeel 好吧,这不像我以前想的那么容易,但无论如何。。

TL;DR

有没有办法消除菜单项边框和定义文本之间的图标间隙?它会在我创建菜单项时立即出现,即使我没有设置图标,或者如果我将图标设置为空

长版本

我们公司开发的Java应用程序自90年代就存在了。在2000年,它重新设计了风格,曾经有一个可怕的,我指的是花哨和多彩的,“合成”主题。因此,现在是时候变得更严肃、更知名,拥有更优雅、更现代的L&F了。这就是为什么我从
SyntheticaLookAndFeel
切换到内置的
SystemLookAndFeel

好吧,这不像我以前想的那么容易,但无论如何。。。我走在正确的道路上;)

我唯一努力工作的就是那些
MenuItems
。通常在Java中,如果创建一个简单菜单或PopMenu并添加一个JMenuItem,它应该看起来像一个普通菜单,其中只有一个文本。在我们的应用程序中,我可以做任何我想做的事情,它总是在每个菜单项的左侧显示一个空格

我搜索了整个工作区,寻找任何(错误的)预设配置。我检查了UIManager并尝试了不同的方法将菜单项图标设置为nothing,但我没有发现任何有用的东西。我甚至创建了一个新类
EmptyIcon
,它设置了一个宽度为1px的图标,并将其设置为UIManager中的预设值

// The empty icon class
public class EmptyIcon implements Icon {
    private int width = 1, height = 0;

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {}

    @Override
    public int getIconWidth() {
        return width;
    }

    @Override
    public int getIconHeight() {
        return height;
    }
}

// set this config in the gui configuration file
UIManager.put("MenuItem.arrowIcon", new EmptyIcon());
UIManager.put("MenuItem.checkIcon", new EmptyIcon());
到目前为止没有任何帮助。 有人知道这种行为是从哪里来的吗?我应该到哪里去寻找这个错误的配置呢

有没有办法强制用户界面去掉这些图标?

为了得到更好的想法,你可以在后面找到一些图片。 这是主菜单栏:

这是我刚刚创建的一个简单的弹出菜单:

这是我试图用以消除差距的代码:

jMenuItem1.setIcon(null);
jMenuItem1.setHorizontalAlignment(JMenuItem.LEFT);
jMenuItem1.setHorizontalTextPosition(JMenuItem.LEFT);
jMenuItem1.setIconTextGap(0);
jMenuItem1.setMargin(new Insets(0, 0, 0, 0));
jMenuItem1.setPressedIcon(null);
jMenuItem1.setText("TEST TEST TEST");

我试图复制它,结果它实际上直接链接到LookAndFeel,当它被更改为
SystemLookAndFeel
(我运行的是Win10)。 似乎这是(或曾经是)一个bug-请参阅(引用自)。 这似乎是故意的,我没有找到一种方法来完全删除图标间距

将此项添加到
JMenuItem
会有所帮助:

menuItem.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
这将更改零部件方向,从而删除左侧的空间。负面影响:它会将空间移到右侧。尽管如此,也许这适合你

我发现的另一种方法是这样的,我认为只有在
JMenuItem
中从不使用任何图标时,这种方法才会起作用:

item.setMargin(new Insets(2, -20, 2, 2));
您可以根据需要调整这些值。
我不知道这些变通方法是否会有任何副作用,我只是整理了我在这个问题上的发现。

Ok这很有帮助。首先谢谢你。这意味着,它没有真正的解决办法。只有变通办法。。。我不高兴,但总比什么都没有好。不管怎样,我不明白为什么会这样。这没有道理。菜单中并不总是有图标。尽管菜单的显示方式在过去几年发生了变化……理论上是的。据我所知,对于这个特定的L&F,没有“修复”。你可以看看其他的L&F,这可能不会导致这种情况,这至少会阻止你使用这些令人不快的解决方法。你是对的。非常感谢您的提示和解释。我不打算使用任何其他L&F,因为每次你想要更新它们时,它们都会花费成本,而且因为我不想从头开始创建自己的:D我同意你的解决方法。感谢againNote,您不必将
JMenuItem
对象添加到
JMenu
。您可以添加任何
JComponent
。有关示例,请参阅。感谢@Abra的提示。实际上,要实现一个在所有情况下都能工作的自己类型的“菜单项”,需要做更多的工作。试想一下,例如,如果你有子菜单。如何在最顶层的jmenu中处理jmenu?您还必须为此创建自己的组件。至于现在,我以最简单的方式使用了maloomeister的解决方案:我创建了自己的类,它扩展了JMenuItem并总是设置它的方向,除非我想使用图标。