使用箭头键在弹出菜单中导航时抛出 ClassCastException

Throws ClassCastException while navigating through the popup menu with the arrow keys

我有一个包含 JMenu 和 JMenuItem 的菜单栏。如果我使用箭头键导航,程序会在您遇到 JMenuItem 时立即抛出 ClassCastException。 有没有办法捕获此异常或确保在导航时跳过 JMenuItem?

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class GUI extends JFrame {

  public GUI() {
    JMenuBar menuBar = new JMenuBar();

    JMenu firstButtonMenu = new JMenu("Button 1");
    firstButtonMenu.add(new JMenuItem("Sub 1"));
    firstButtonMenu.add(new JMenuItem("Sub 2"));

    JMenu secondButtonMenu = new JMenu("Button 2");
    secondButtonMenu.add(new JMenuItem("Sub 1"));
    secondButtonMenu.add(new JMenuItem("Sub 2"));

    menuBar.add(firstButtonMenu);
    menuBar.add(secondButtonMenu);
    menuBar.add(new JMenuItem("Button 3"));

    add(menuBar);
    setVisible(true);
    pack();

  }
}

您应该只将 JMenu 个对象添加到 JMenuBar,而不是 JMenuItem 个对象。

如果你不这样做,你将得到:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JMenuItem cannot be cast to javax.swing.JMenu
    at javax.swing.plaf.basic.BasicPopupMenuUI$Actions.selectParentChild(BasicPopupMenuUI.java:531)
    at javax.swing.plaf.basic.BasicPopupMenuUI$Actions.actionPerformed(BasicPopupMenuUI.java:426)

JMenuBar 有一个您已经在使用的 add(JMenu) 方法。

但是如果你传递一个JMenuItem,这个方法将不会被调用,但是从java.awt.Container继承的add(Component)将会被调用,这就是为什么你可以添加任何Component,但只有JMenuItem得到正确支持。

底层 BasicPopupMenuUI class(参见第 531 行:BasicPopupMenuUI.java),期望添加到菜单栏的所有组件都是 JMenu 个对象,以至于强制转换在代码中完成,这就是崩溃发生的地方:

newSelection[2] = ((JMenu)nextMenu).getPopupMenu();

所以只需将您的组件添加为菜单即可:

menuBar.add(new JMenu("Button 3"));

也不要对菜单栏使用 add,请考虑使用 setJMenuBar(menuBar)