3

TL;DR

Is there a way to getting rid of the icon gap between the MenuItem border and the defined text? It appears as soon as I create the menu item, even if I do not set an icon, as well as if I set the icon to null.

Long Version

The Java application we develop in our company exists since the 90'. In the 2000's it got restyled and used to have one of those awful, eehrm I mean fancy and colourful, "Synthetica" themes. So now the time has come to get a bit more serious and reputable, having a more elegant and modern L&F. That's why I switched from the SyntheticaLookAndFeel to the built-in SystemLookAndFeel.

Ok, that was not as easy as I thought before, but anyway... I'm on the right path ;)

The only thing I'm struggling to get to work as it should, are those MenuItems. Typically in Java, if you create a simple Menu or PopMenu and you add a JMenuItem, it should look like a normal menu having just a text in it. In our application I can do whatever I want, it ALWAYS shows a space on the left hand side of every menu item.

I searched the entire workspace for any (wrong) pre-set configuration. I checked the UIManager and tried out different ways of setting the menu items icons to nothing but I did not find anything useful. I even created a new class EmptyIcon, which sets an icon with a width of 1px and set that as a pre-set into my 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());

Nothing helped so far. Does anybody know, where this behaviour could come from? Where should I look into, to find this misconfiguration?

Is there any way to force the ui to get rid of those icons?

To get a better idea you can find some pictures hereafter. This is the main menu bar:

MainMenu

This is a simple popup menu I just created:

PopupMenu

And this is the code I tried to use in order to remove the gap:

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");
Iamnino
  • 360
  • 1
  • 4
  • 17
  • Note that you don't have to add `JMenuItem` objects to a `JMenu`. You can add any `JComponent`. Refer to [this answer](https://stackoverflow.com/questions/42156886/java-how-to-add-jcombobox-header/63977793#63977793) for an example. – Abra Oct 30 '20 at 14:23
  • Thank you @Abra for this hint. Actually it would be a lot more work to implement an own type of "menu item" that works in all situations. Just think, for example, if you have submenus. How do you handle the jmenu inside the topmost jmenu? You have to create an own component for that as well. As for now I used maloomeister's workaround in the most simple way: I created own class, which extends the JMenuItem and always sets its orientation, except for cases where I want to use an icon. – Iamnino Oct 30 '20 at 14:33

1 Answers1

5

I tried to replicate this, and it turns out it is actually directly linked to the LookAndFeel, when it is changed to SystemLookAndFeel (I'm running Win10). Seems like this is (or was) a bug - see https://bugs.openjdk.java.net/browse/JDK-8152981 (reference taken from this thread). This seems like it is intentional and I didn't find a way to completely remove the icon-spacing.

Adding this to the JMenuItem helped though:

menuItem.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

This will change the component orientation, thus removing the space on the left side. Negative side-effect: it will move the space to the right side. Nonetheless, maybe this works out for you.

Another way I found, which I think only would work if you never use any Icons in your JMenuItem, is like this:

item.setMargin(new Insets(2, -20, 2, 2));

You may tweak these values according to your needs. I don't know if these workarounds might have any side-effects, I just compiled what I found on the issue.

maloomeister
  • 2,461
  • 1
  • 12
  • 21
  • Ok this helps. Thank you first of all. So that means, there is no real fix to it. Only workarounds... I'm not happy about it, but it's better than nothing. Anyway I don't get why it is like that. It doesn't make sense. There isn't always an icon in menus. Even though the way menus are shown has changed over the past years... – Iamnino Oct 29 '20 at 12:41
  • Well, in theory, yes. As far as I understood the issue, for this specific L&F there is no "fix". You could check out other L&Fs, which might not cause this, this would at least keep you from using these unpleasant workarounds. – maloomeister Oct 29 '20 at 12:48
  • You are right. Thank you so much for all hints and explanations. I'm not going to use any other L&F because they will cost every time you want to update them, and because I don't feel like creating my own from scratch :D I'm OK with your workarounds. Thanks again – Iamnino Oct 30 '20 at 14:38
  • I'm on Java 6 SE, Windows 7 x64, and this solution does not work... Even worse, I have a thin vertical separator line on the right from the "icon spot", that can't be removed. – Alex Popov Feb 27 '23 at 21:22