When adding plain text items to a menu, whether JMenu or JPopupMenu, each menu item has a height presumably based on its font plus some blank edges, which looks nice.
Adding an Icon to an item causes the item's height to be reduced to the height of the icon. If the icon's height is smaller than the font's size, then the item height is clearly bottoming out at the font's minimum height.
The closest post I could find was Setting icon in JMenuItem makes menu text match icon color, but color isn't a problem here. I've used a similar SSCCE:
import java.awt.*;
import javax.swing.*;
public class SquishText extends JFrame
{
public SquishText()
{
JMenu menu = new JMenu("a menu");
menu.add(new JMenuItem("item with no icon"));
menu.add(new JMenuItem("label text goes here", new Icon(){
@Override
public void paintIcon (Component c, Graphics g, int x, int y) {
((Graphics2D)g).fill3DRect (0, 0, 8, 8, true);
}
@Override
public int getIconWidth() {
return 8;
}
@Override
public int getIconHeight() {
return 8;
}
}));
menu.add(new JMenuItem("another item with no icon"));
JMenuBar menubar = new JMenuBar();
menubar.add(menu);
this.setJMenuBar(menubar);
}
public static void main (String[] args) throws Exception
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SquishText wtf = new SquishText();
wtf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
wtf.setVisible(true);
}
}
with results posted here: https://i.stack.imgur.com/3sJej.jpg
Mousing over the menu items shows the height of the middle entry to be visibly smaller and ugly.
For adding Icons in our actual code, they've tried both our preferred method of setting data on the Action,
action.putValue (Action.SMALL_ICON, the_icon_instance);
and as a desperate fallback, setting it on the created JMenuItem directly,
menu.add(action).setIcon(the_icon_instance);
Same behavior in both cases, which matches the SSCCE. How the icon gets added doesn't seem to matter, just the fact that an icon is present.
It might be a problem with the L&F (Java 8 on Windows 7), but trying to poke around inside the WindowsLookAndFeel code was immediately bewildering.
So they've asked me for help, but this is the first I've encountered anything like this. (My projects rarely use icons in menus.) I feel like the whole thing could be solved with a setMinimumSize' / 'setPreferredSize
in just the right spot, but I feel that shouldn't really be needed... and also we wouldn't know what the normal line height is until after rendering anyhow.
What noob mistake are we making here? (Pesky icons, back in my day it was all green text on a vt100, get off my lawn, etc.)