javaswinglook-and-feeljmenuitem

Double icons with JMenuItem setHorizontalTextPosition on Win


Two icons are rendered when using JMenuItem setHorizontalTextPosition(SwingConstants.LEFT) with Windows Look and Feel. It works fine with the default Java Look and Feel.

I just filed a Java bug report, posting here for anyone else having the same problem.

Does anyone have another workaround to suggest?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.SwingConstants;
import javax.swing.UIManager;


public class WinMenuItemIcon {

public static void main(String[] args) {
    
    //NOTE: Bug happens with Windows L&F
    String name = UIManager.getSystemLookAndFeelClassName();
    try {
        UIManager.setLookAndFeel( name );
    } catch (Exception e) {
        e.printStackTrace();
    }

    JFrame frame = new JFrame();
    frame.setTitle("Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    JMenuBar menuBar = new JMenuBar();
    JMenu menu = new JMenu("Menu");
    
    ImageIcon icon = createIcon();
    
    JMenuItem menuItem = new JMenuItem("Command", icon);
    menuItem.setHorizontalTextPosition(SwingConstants.LEFT);
    menu.add(menuItem);
    menuBar.add(menu);

    frame.setJMenuBar(menuBar);
    frame.setPreferredSize(new Dimension(500, 500));
    frame.pack();
    frame.setVisible(true);
}

protected static ImageIcon createIcon() {
    BufferedImage bi = new BufferedImage(25,25,BufferedImage.TYPE_INT_ARGB);
    Graphics g = bi.createGraphics();
    g.setColor(Color.RED);
    g.fillOval(0,0, 25, 25);
    return new ImageIcon(bi);
}

}

Solution

  • enter image description here

    import java.awt.*;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    
    public class WinMenuItemIconTest {
      private static JMenuBar makeManuBar() {
        JMenuItem menuItem0 = new JMenuItem("Command", createIcon());
    
        JMenuItem menuItem1 = new JMenuItem("LEFT bug?", createIcon());
        menuItem1.setHorizontalTextPosition(SwingConstants.LEFT);
        //menuItem1.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
    
        JMenuItem menuItem2 = new JMenuItem("CENTER bug?", createIcon());
        menuItem2.setHorizontalTextPosition(SwingConstants.CENTER);
    
        JMenuItem menuItem3 = new JMenuItem("RIGHT_TO_LEFT", createIcon());
        menuItem3.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
    
        JMenu menu = new JMenu("Menu");
        menu.add(menuItem0);
        menu.add(menuItem1);
        menu.add(menuItem2);
        menu.add(menuItem3);
    
        JMenuBar menuBar = new JMenuBar();
        menuBar.add(menu);
        return menuBar;
      }
      public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
          //NOTE: Bug happens with Windows L&F
          String name = UIManager.getSystemLookAndFeelClassName();
          try {
            UIManager.setLookAndFeel(name);
          } catch (Exception e) {
            e.printStackTrace();
          }
          JFrame frame = new JFrame("Test");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.setJMenuBar(makeManuBar());
          frame.setSize(320, 240);
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
        });
      }
      protected static ImageIcon createIcon() {
        BufferedImage bi = new BufferedImage(25, 25, BufferedImage.TYPE_INT_ARGB);
        Graphics g = bi.createGraphics();
        g.setColor(Color.RED);
        g.fillOval(0, 0, 25, 25);
        g.dispose();
        return new ImageIcon(bi);
      }
    }