java - JPopupMenu 中带有图标的 JLabel 不遵循其他 JMenuItem 对齐方式

标签 java swing jlabel jmenuitem jpopupmenu

我需要在其中包含其他 JMenuItemJPopupMenu 顶部添加一个标签。到目前为止,一切都很好。出现此问题的原因是我的标签左侧有一个图标,就像“正常”JMenuItem 一样,但其他项目不会像使用 JMenuItem< 那样遵循标签对齐方式。像这样:

JPopupMenu with JMenuItem and icon

第一个项目是带有图标的 JMenuItem。请注意,所有其他 JMenuItem 将遵循具有较宽图标的文本对齐方式。

现在,如果我将带有图标的 JLabel 添加到 JPopupMenu 中,效果将不一样:

JPopupMenu with JLabel and icon

或者更糟糕的是,如果我将没有图标的 JLabel 添加到包含其他带图标的 JMenuItemJPopupMenu 中,则标签获胜不遵循另一个的对齐方式,并将保持向左对齐:

JPopupMenu with JLabel and JMenuItem with icon

我的问题:是否可以将 JLabel 对齐方式(图标和文本)附加到 JPopupMenuJMenuItem 的对齐方式?如果是,怎么办?

最佳答案

  • 也许可以使用禁用的 JMenuItem 而不是 JLabel
  • 编辑:WindowsLookAndFeel 只能正常工作。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public final class MenuItemAlignmentTest2 {
  public JComponent makeUI() {
    JTextArea textArea = new JTextArea();
    textArea.setComponentPopupMenu(makeTestPopupMenu(null));

    JTree tree = new JTree();
    tree.setComponentPopupMenu(makeTestPopupMenu(new ColorIcon(Color.RED)));

    JPanel p = new JPanel(new GridLayout(1, 2));
    p.add(new JScrollPane(textArea));
    p.add(new JScrollPane(tree));
    return p;
  }
  private static JPopupMenu makeTestPopupMenu(Icon icon) {
    //UIManager.put("MenuItem.disabledAreNavigable", Boolean.FALSE);
    //UIManager.put("MenuItem.disabledForeground", Color.RED);
    JMenuItem item0 = new JMenuItem("JMenuItem.setEnabled(false);");
    item0.setEnabled(false);

    JLabel item1 = new JLabel("JLabel");

    JPanel item2 = new JPanel(new BorderLayout());
    item2.setOpaque(false); //<----------------------------- add this line
    item2.add(new JMenuItem("JPanel with JMenuItem") {
      @Override public boolean contains(int x, int y) {
        return false; //disable mouse events
      }
    });

    JMenuItem item3 = new JMenuItem(" ");
    item3.setBorder(BorderFactory.createEmptyBorder()); //<- add this line
    item3.setEnabled(false);
    item3.add(new JMenuItem("JMenuItem(disabled) with JMenuItem") {
      @Override public boolean contains(int x, int y) {
        return false; //disable mouse events
      }
    });

    JPopupMenu popup = new JPopupMenu();
    popup.add(makeTestMenuItems("Test0", item0, icon));
    popup.add(makeTestMenuItems("Test1", item1, icon));
    popup.add(makeTestMenuItems("Test2", item2, icon));
    popup.add(makeTestMenuItems("Test3", item3, icon));

    return popup;
  }
  private static JMenu makeTestMenuItems(String title, JComponent item, Icon icon) {
    JMenu menu = new JMenu(title);
    menu.add(item);
    menu.addSeparator();
    menu.add(new AbstractAction("JMenuItem") {
      @Override public void actionPerformed(ActionEvent e) {
        System.out.println("actionPerformed");
      }
    });
    menu.add("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
    menu.add(new JMenuItem("bbbbb", icon));
    return menu;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (ClassNotFoundException | InstantiationException
        | IllegalAccessException | UnsupportedLookAndFeelException ex) {
        ex.printStackTrace();
      }
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

      JMenuBar mb = new JMenuBar();
      mb.add(LookAndFeelUtil.createLookAndFeelMenu());
      f.setJMenuBar(mb);

      f.getContentPane().add(new MenuItemAlignmentTest2().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

final class LookAndFeelUtil {
  private static String lookAndFeel = UIManager.getLookAndFeel().getClass().getName();
  public static JMenu createLookAndFeelMenu() {
    JMenu menu = new JMenu("LookAndFeel");
    ButtonGroup lookAndFeelRadioGroup = new ButtonGroup();
    for (UIManager.LookAndFeelInfo lafInfo : UIManager.getInstalledLookAndFeels()) {
      menu.add(createLookAndFeelItem(
          lafInfo.getName(), lafInfo.getClassName(), lookAndFeelRadioGroup));
    }
    return menu;
  }
  private static JRadioButtonMenuItem createLookAndFeelItem(
      String lafName, String lafClassName, ButtonGroup lookAndFeelRadioGroup) {
    JRadioButtonMenuItem lafItem = new JRadioButtonMenuItem();
    lafItem.setSelected(lafClassName.equals(lookAndFeel));
    lafItem.setHideActionText(true);
    lafItem.setAction(new AbstractAction() {
      @Override public void actionPerformed(ActionEvent e) {
        ButtonModel m = lookAndFeelRadioGroup.getSelection();
        try {
          setLookAndFeel(m.getActionCommand());
        } catch (ClassNotFoundException | InstantiationException
                   | IllegalAccessException | UnsupportedLookAndFeelException ex) {
          ex.printStackTrace();
        }
      }
    });
    lafItem.setText(lafName);
    lafItem.setActionCommand(lafClassName);
    lookAndFeelRadioGroup.add(lafItem);
    return lafItem;
  }
  private static void setLookAndFeel(String lookAndFeel)
      throws ClassNotFoundException, InstantiationException,
             IllegalAccessException, UnsupportedLookAndFeelException {
    String oldLookAndFeel = LookAndFeelUtil.lookAndFeel;
    if (!oldLookAndFeel.equals(lookAndFeel)) {
      UIManager.setLookAndFeel(lookAndFeel);
      LookAndFeelUtil.lookAndFeel = lookAndFeel;
      updateLookAndFeel();
      //firePropertyChange("lookAndFeel", oldLookAndFeel, lookAndFeel);
    }
  }
  private static void updateLookAndFeel() {
    for (Window window : Frame.getWindows()) {
      SwingUtilities.updateComponentTreeUI(window);
    }
  }
}

class ColorIcon implements Icon {
  private final Color color;
  protected ColorIcon(Color color) {
    this.color = color;
  }
  @Override public void paintIcon(Component c, Graphics g, int x, int y) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.translate(x, y);
    g2.setPaint(color);
    g2.fillRect(1, 1, getIconWidth() - 2, getIconHeight() - 2);
    g2.dispose();
  }
  @Override public int getIconWidth() {
    return 12;
  }
  @Override public int getIconHeight() {
    return 12;
  }
}

关于java - JPopupMenu 中带有图标的 JLabel 不遵循其他 JMenuItem 对齐方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38360595/

相关文章:

Java 设置窗口的 "Document"

java - Swing - 在 View 之间进行交互的最佳方式?

Java - 设置 JLabel 的宽度/高度

java - Lombok 对jdk.compiler内部软件包的访问与Java-16不兼容

java - 函数式编程方式: How to avoid overhead of copy object in Java?

java - 如何使您在 JColorChooser 中选择的颜色改变 JTextArea 中字体的颜色?

java - JLabel 没有显示?

java - 使用 FlowLayout 管理器将 3 个面板保留在不同的行中

java - 遍历 java 中枚举的子集

java - JLabel 不在全屏居中