Double icons with JMenuItem setHorizontalTextPosition on Win

爷,独闯天下 提交于 2021-02-07 18:28:38

问题


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? Thanks.

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);
}

}

回答1:


  • My envirment: Windows 10 64bit + JDK 1.8.0_72
  • I'm not sure if this is a bug... Now this bug seems fixed: JDK-8152981 Double icons with JMenuItem setHorizontalTextPosition on Win 10 - Java Bug System

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);
  }
}



回答2:


Delete the line

 menuItem.setHorizontalTextPosition(SwingConstants.LEFT);

and you will have only 1 icon

or use an if statement to exclude that line for windows look and feel as follows

if(!UIManager.getLookAndFeel().equals("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"))
{
     menuItem.setHorizontalTextPosition(SwingConstants.LEFT);
}

here is an alternative to @aterai's code that will work better if tweaked a bit more according to your needs, probably it is some bug but here this does it i am not sure how @aterai needs center to look like but here is what i assumed :-

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()); // always left by defaulr


    JMenuItem menuItem2 = new JMenuItem("CENTER bug?", createIcon());

     menuItem2.setMargin(new Insets(5, 50, 5, 5)); // using set margin to centerise 

    JMenuItem menuItem3 = new JMenuItem("RIGHT_TO_LEFT", createIcon());
    menuItem3.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); // Right to left seems to work

    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);
        return new ImageIcon(bi);
      }
    }

Note:- I am on Windows 10 too




回答3:


For aligning icon and label text from left to right:

  JMenuItem menuItem3 = new JMenuItem("LEFT_TO_RIGHT", createIcon());
  menuItem3.setHorizontalTextPosition(JMenuItem.RIGHT);
  menuItem3.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);

The above code worked for me.



来源:https://stackoverflow.com/questions/35437356/double-icons-with-jmenuitem-sethorizontaltextposition-on-win

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!