【问题标题】:how to add a action listner to jmenuitem如何将动作监听器添加到 jmenuitem
【发布时间】:2014-09-09 14:12:13
【问题描述】:
  1. 我的菜单项正在通过数据库添加。
  2. 如果用户选择特定的菜单项,我必须执行诸如打开新的 jframe 之类的操作。
  3. 这里将菜单维度添加到 Menubar ,并在其下添加各种菜单项,例如 Period , Entity ,它们正在从数据库中获取。
  4. 现在我想通过点击 Period menuitem 打开一个新的 jframe。

         public  void MenuExp(){
               JMenu DimensionMenu = new JMenu("Dimension");
               JMenu editMenu = new JMenu("Help");
               jMenuBar1.add(DimensionMenu);
               jMenuBar1.add(editMenu);
    
        //JMenuItem newAction = new JMenuItem("Account");
        //fileMenu.add(newAction);
        //JMenuItem newPeriod = new JMenuItem("Period");
        //fileMenu.add(newPeriod);
    
        try{
             Class.forName("oracle.jdbc.OracleDriver");
             Connection comm = (Connection)DriverManager.getConnection("jdbc:oracle:thin:@192.168.100.25:1521:orcl","SYSTEM","Admin123");
             Statement st = comm.createStatement();
             String Query = "select OBJECT_NAME from RAHUL_APP1.HSP_OBJECT where OBJECT_TYPE = 2 AND OBJECT_ID <> 30" ;
             //and User_Name ='" + jTextField1.getText()+"'";
             ResultSet rs = st.executeQuery(Query);
    
             while(rs.next()){ 
                    JMenuItem newAction = new JMenuItem(rs.getString(1));
                    DimensionMenu.add(newAction); 
    
                   rs.close();
                   st.close();
                   comm.close(); 
                   newAction.addActionListener(new ActionListener(){
                          public void actionPerformed(ActionEvent arg0){
                             System.out.println("You have clicked on the Account");
                          }
                   });
              }
            } catch(Exception e){
                  JOptionPane.showMessageDialog(this,e);
            }   
        }
    

【问题讨论】:

  • 我的菜单项正在通过数据库添加 为什么?它是一种“自定义菜单”的功能吗?另一方面,您可以为每个菜单项存储一个唯一的操作命令,并将其设置回菜单项,就像您设置其文本一样。然后创建一个通用动作侦听器,根据源的动作命令执行不同的动作,并将其附加到每个菜单项。这可能就足够了,但感觉有点脏。
  • 是的,它是自定义菜单,因为应用程序会连接到各种表格,每次表格改变菜单都会改变
  • @user3135761:请查看此链接上的example5。使用Action 而不是ActionListener 希望它会有所帮助。

标签: java swing jtable jmenuitem


【解决方案1】:

您需要对框架进行一些参数化,或者将例如框架类也存储在 DB 中并使用反射对其进行初始化...


更新:

实现可以是这样的:

package betlista.so.swing.menuitemdialogsfromdb;

import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class MainFrame extends JFrame {

    public MainFrame() {
        super("Frame");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        add(createMenu());

        pack();
    }

    private JMenuBar createMenu() {
        JMenuBar menuBar = new JMenuBar();

        JMenu menu = new JMenu("Open");
        menu.add(new DialogCreatingMenuItem("Dialog 1", "betlista.so.swing.menuitemdialogsfromdb.MainFrame$MyDialog1"));
        menu.add(new DialogCreatingMenuItem("Dialog 2", "betlista.so.swing.menuitemdialogsfromdb.MainFrame$MyDialog2"));

        menuBar.add(menu);

        return menuBar;
    }

    class DialogCreatingMenuItem extends JMenuItem implements ActionListener {

        String className;

        public DialogCreatingMenuItem(String text, String className) throws HeadlessException {
            super(text);
            this.className = className;
            addActionListener(this);
        }

        @Override
        public void actionPerformed(ActionEvent ae) {
            try {
                Class<JDialog> clazz = (Class<JDialog>)Class.forName(this.className);
                JDialog dialog = clazz.newInstance();
                dialog.setVisible(true);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

    }

    public static class MyDialog1 extends JDialog {
        public MyDialog1() {
            setTitle("Dialog 1");
            add(new JLabel("Dialog 1"));
            pack();
        }
    }

    public static class MyDialog2 extends JDialog {
        public MyDialog2() {
            setTitle("Dialog 2");
            add(new JLabel("Dialog 2"));
            pack();
        }       
    }

    public static void main(String[] args) {
        new MainFrame().setVisible(true);
    }

}

字符串在哪里

    menu.add(new DialogCreatingMenuItem("Dialog 1", "betlista.so.swing.menuitemdialogsfromdb.MainFrame$MyDialog1"));
    menu.add(new DialogCreatingMenuItem("Dialog 2", "betlista.so.swing.menuitemdialogsfromdb.MainFrame$MyDialog2"));

从数据库中检索...

【讨论】:

  • 看到我无法弄清楚如何比较从数据库添加的 JMenuItem 的值
  • 我添加了实现示例,当然在更复杂的示例中,对话框类可以在不同的文件中,也可以在不同的项目中(但必须在类路径上)。
【解决方案2】:

这是一个示例代码:

menuItem1.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent e){
                    ...
                }
            });

记住创建菜单的步骤: 1.创建一个MenuBar并添加到面板 2.创建一个Menu并添加到MenuBar 3.创建一个MenuItem并添加到Menu

然后将监听器添加到MenuItem

编辑:如果你在 try 语句之外使用它应该可以工作

【讨论】:

    【解决方案3】:

    现在我想通过点击 Period menuitem 打开一个新的 jframe

    当然,您必须在菜单中添加 ActionListener 才能做到这一点,但真正的问题是 您如何确定每个菜单项的正确侦听器? 因为您获取菜单项从数据库中,那么它并不像看起来那么容易。

    注意:The Use of Multiple JFrames, Good/Bad Practice?


    选项 1(有点脏)

    正如我所说,您可以存储一个操作命令并将其设置回菜单项,就像设置菜单名称一样:

    while(rs.next()) { 
        String menuName =  rs.getString("menuname");
        String actionCommand = rs.getString("actioncommand");
        JMenuItem newAction = new JMenuItem(menuName);
        newAction.setActionCommand(actionCommand);
        DimensionMenu.add(newAction);
        ...
    }
    

    然后您可以拥有一个使用ActionEvent#getActionCommand() 的侦听器来决定要执行的正确操作并将此侦听器附加到您的所有菜单项:

    class MenuActionListener implements ActionListener {
    
        @Override
        public void actionPerformed(ActionEvent evt) {
            String actionCommand = evt.getActionCommand();
            switch (actionCommand) {
                case "OpenNewDialog": openNewDialog(); break;
                ...
            }
        }
    
        private void openNewDialog() {
            // implementation here
        }
    }
    

    然后:

    ActionListener listener = new MenuActionListener();
    
    while(rs.next()) { 
        String menuName =  rs.getString("menuname");
        String actionCommand = rs.getString("actioncommand");
        JMenuItem newAction = new JMenuItem(menuName);
        newAction.setActionCommand(actionCommand);
        newAction.addActionListener(listener);
        DimensionMenu.add(newAction);
        ...
    }
    

    选项 2

    实现Factory method pattern 以根据菜单的操作命令创建特定的ActionListenerAction

    class ActionListenerFactory {
    
        public static Action createAction(final String actionCommand) {
            switch (actionCommand) {
                case "OpenNewDialog": return openNewDialogAction(); break;
                ...
            }
        }
    
        private Action openNewDialogAction() {
            Action action = new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent evt) {
                    // open new dialog here
                }
            };
            return action;
        }
    }
    

    然后:

    while(rs.next()) {
        String menuName =  rs.getString("menuname");
        String actionCommand = rs.getString("actioncommand");
        JMenuItem newAction = new JMenuItem(menuName);
        newAction.setActionCommand(actionCommand);
        newAction.addActionListener(ActionListenerFactory.createAction(actionCommand));
        DimensionMenu.add(newAction);
        ...
    }
    

    另见:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      • 2011-01-17
      • 2014-06-17
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多