监听所有菜单项的JFrame Action Listener



所以我有一个JFrame,它设置了一个菜单,菜单的当前结构如下:

File
  Exit
Pages
  Reviews
    A
    B
    C
Help
  About

我想创建一个只监听Reviews下菜单项的Action Listener。这是一种可能性吗(如果是,如何(,还是我必须创建一个通用侦听器并检查它是否是这些项之一?

是的,有可能:

  • 将菜单项存储为字段
  • 将相同的ActionListener添加到每个菜单项
  • 在侦听器中,检查源以了解单击了哪个项目

应该看起来像:

public class YourFrame extends JFrame implements ActionListener {
   private final JMenuItem menuA, menuB;
   public YourFrame(){
      super("Your app");
      JMenuBar menuBar = new JMenuBar();
      JMenu menuReviews = new JMenu("Reviews");
      menuA = new JMenuItem("A");
      menuB = new JMenuItem("B");
      ...
      menuReviews.add(menuA);
      menuReviews.add(menuB);
      menuBar.add(menuReviews);
      setJMenuBar(menuBar);
      ...
      menuA.addActionListener(this);
      menuB.addActionListener(this);
      ...
   }
   public void actionPerformed(ActionEvent event){
      if(event.getSource()==menuA){
         System.out.println("Menu A clicked");
         ...
      }else if(event.getSource()==menuB){
         System.out.println("Menu B clicked");
         ...
      }
   }
}

注意,这里我让JFrame实现ActionListener,但这只是为了方便。您可以使用一个专用类,或者在构造函数中创建一个匿名类:

ActionListener reviewsListener = new ActionListener(){
   public void actionPerformed(ActionEvent event){
      if(event.getSource()==menuA){
         System.out.println("Menu A clicked");
         ...
      }else if(event.getSource()==menuB){
         System.out.println("Menu B clicked");
         ...
      }
   }
};
menuA.addActionListener(reviewsListener);
menuB.addActionListener(reviewsListener);

如果你想进一步集成这个过程,我也可以建议扩展JMenu,这样你就可以将它传递给你的动作监听器,并系统地将它添加到新的菜单项中。

public class YourJMenu extends JMenu {
   private ActionListener listener;
   public YourJMenu(String name, ActionListener listener){
      super(name);
      this.listener = listener;
   }
   @Override
   public JMenuItem add(JMenuItem item){
      item.addActionListener(listener);
      return super.add(item);
   }
}

有了这个,你只需要写:

JMenu menuReviews = new YourJMenu("Reviews", this);

并放下:

menuA.addActionListener(this);
menuB.addActionListener(this);

使用一种通用方法,我们可以将动作侦听器添加到菜单下的所有菜单项中。下面是一个示例代码。

public class MenuItemEvent {
    JFrame objFrm = new JFrame("Menu event demo");
    JMenuBar mBar;
    JMenu mnu;
    JMenuItem mnuItem1, mnuItem2, mnuItem3;
    public void show() {
        objFrm.setSize(300, 300);
        mBar = new JMenuBar();
        mnu = new JMenu("Reviews");
        mBar.add(mnu);
        mnuItem1 = new JMenuItem("A");
        mnu.add(mnuItem1);
        mnuItem2 = new JMenuItem("B");
        mnu.add(mnuItem2);
        mnuItem3 = new JMenuItem("C");
        mnu.add(mnuItem3);
        //method call
        fnAddActionListener(mnu);
        objFrm.setJMenuBar(mBar);
        objFrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        objFrm.setVisible(true);
    }
    //method to add action listener to all menu items under a menu
    public void fnAddActionListener(JMenu mnu) {
        if (mnu.getItemCount() != 0) {
            for (int iCount = 0; iCount < mnu.getItemCount(); iCount++) {
                (mnu.getItem(iCount)).addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        fnMenuItemAction(e);
                    }
                });
            }
        }
    }
    //menu item action event
    public void fnMenuItemAction(ActionEvent e) {
        if (e.getSource().equals(mnuItem1)) {
            System.out.println("Menu Item 1");
        } else if (e.getSource().equals(mnuItem2)) {
            System.out.println("Menu Item 2");
        } else if (e.getSource().equals(mnuItem3)) {
            System.out.println("Menu Item 3");
        }
    }
    public static void main(String[] args) {
        new MenuItemEvent().show();
    }
}

或具有以下功能

//fnMenuItemAdd(mnu,mnuItem1)
//etc.
public void fnMenuItemAdd(JMenu mnu, JMenuItem mni) {
    mnu.add(mni);
    mni.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            fnMenuItemAction(e);
        }
    });
}

最新更新