JFrame Action Listener侦听所有菜单项?

时间:2015-07-05 11:33:04

标签: java swing jframe jmenuitem

所以我设置了一个带有当前结构的菜单的JFrame,看起来就像这样:

File
  Exit
Pages
  Reviews
    A
    B
    C
Help
  About

我想创建一个仅侦听评论下的菜单项的动作侦听器。这是一种可能性(如果是的话,如何)或者我是否必须创建一个通用的监听器并检查它是否是其中一个项目?

2 个答案:

答案 0 :(得分:4)

是的,有可能:

  • 将您的菜单项目存储为字段
  • 为每个菜单项添加相同的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);

答案 1 :(得分:0)

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

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