使用 JPopupMenu 从 JMenuItem 获取 JMenu

Get JMenu from JMenuItem with JPopupMenu

我想在单击带有 JPopupMenu 的 JMenuItem 时获取 JMenu 的名称。

我在每个 JMenuItem 上放置了一个名为 "menuContextuelListener" 的 ActionListener:

ActionListener menuContextuelListener = new ActionListener() {
    public void actionPerformed(ActionEvent event) {
        System.out.println(event.getActionCommand());
    }
};

如何从所选的 JMenuItem 中获取 JMenu 父项的名称?

我也在同一个监听器中尝试过这种方式,但它不起作用:

JMenuItem jmi = (JMenuItem) event.getSource();
JPopupMenu jpm = (JPopupMenu) jmi.getParent();
JMenu menu = (JMenu) jpm.getInvoker();

这一个来自 how to get the name of a JMenu when a JMenuItem is clicked

JPopupMenu menu = (JPopupMenu) ((JMenuItem) evt.getSource()).getParent();
JMenu actMenu = menu.getInvoker();

监听器的完整代码:

ActionListener menuContextuelListener = new ActionListener(){
             public void actionPerformed(ActionEvent event)
              {

                     JMenuItem source = (JMenuItem)(event.getSource());
                        try{
                            JMenuItem menuItem = (JMenuItem) event.getSource(); 
                            JPopupMenu popupMenu = (JPopupMenu) menuItem.getParent(); 
                            Component invoker = popupMenu.getInvoker();      
                            JPopupMenu popup = (JPopupMenu) invoker.getParent();
                            System.out.println("NAME OF JMENU: "+popup.getName());

                        }catch(Exception ex){
                            ex.printStackTrace();
                        }
              }
        };

这里是菜单构造的一个例子(动态):

tJMenu.add(new JMenu(ligne.substring(0, pos-1)));
tJMenu.get(tJMenu.size()-1).setName(ligne.substring(0, pos-1));

我检查了下面的代码...我可以看到 JMenu 的名称:

System.out.println(tJMenu.get(tJMenu.size()-1).getName());
JMenuItem menuItem = (JMenuItem) event.getSource(); 
JPopupMenu popupMenu = (JPopupMenu) menuItem.getParent(); 
Component invoker = popupMenu.getInvoker();      
//JPopupMenu popup = (JPopupMenu) invoker.getParent(); // why did you add this?

您在论坛中找到了有关如何执行此操作的建议,那么为什么要更改找到的代码?

快速浏览一下,您的代码中有一个额外的 getParent() 语句。

调用者将是 JMenu。不需要第二个 getParent() 语句。

下面是一些更通用的代码,可让您获取菜单项和子菜单项的 JMenu:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MenuItemAction implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        JMenuItem mi = (JMenuItem)e.getSource();
        mi.setText(mi.getText() + "0");
        JMenu menu = getMenuBarMenu(mi);
        System.out.println("Menu: " + menu.getText());

        JFrame frame = (JFrame)SwingUtilities.windowForComponent(menu);
        System.out.println("Frame: " + frame.getTitle());
    }

    private JMenu getMenuBarMenu(JMenuItem item)
    {
        JMenu menu = null;

        while (menu == null)
        {
            JPopupMenu popup = (JPopupMenu)item.getParent();
            item = (JMenuItem)popup.getInvoker();

            if (! (item.getParent() instanceof JPopupMenu) )
                menu = (JMenu)item;
        }

        return menu;
    }


    private static void createAndShowGUI()
    {
        ActionListener listener = new MenuItemAction();

        // Create menu bar

        JMenuBar menuBar = new JMenuBar();

        JMenu menu = new JMenu( "File" );
        menuBar.add( menu );

        JMenuItem item1 = new JMenuItem("Item 1");
        menu.add( item1 );

        JMenu subMenu1 = new JMenu("SubMenu 1");
        menu.add( subMenu1 );

        JMenuItem subItem1 = new JMenuItem("SubItem 1");
        subMenu1.add( subItem1 );

        JMenu subMenu12 = new JMenu("SubMenu 12");
        subMenu1.add( subMenu12 );

        JMenuItem subItem12 = new JMenuItem("SubItem 12");
        subMenu12.add( subItem12 );

        item1.addActionListener( listener );
        subItem1.addActionListener( listener );
        subItem12.addActionListener( listener );

        JFrame frame = new JFrame("Get Menu and Frame");
        frame.setJMenuBar( menuBar );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setSize(200, 200);
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater( () -> createAndShowGUI() );
/*
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
*/
    }
}

以后当您提问时,请 post 完整 SSCCE 就像我所做的那样,这样我们才能准确地看到您在做什么。