java - 如何为多个 JMenuItem 创建 ActionListener?

标签 java swing actionlistener anonymous-class jmenuitem

我在使用带有 actionListener 的匿名内部类时遇到困难。有人可以向我解释一下我的代码有什么问题以及如何将匿名内部类与 actionListener 一起使用。我试图在一个类中创建一个菜单栏,在另一个类中创建一个 Action 监听器。当我尝试使用匿名内部类时遇到了一些困难。 java网站不清楚。您能否向我解释一下并帮助我修复我的代码。

 public class Listener implements ActionListener {
        HangmanView hangmanView = new HangmanView();
        JFrame dialogFrame = new JFrame();
        ImageIcon logo = new ImageIcon("logo.png");

        public void listener1() {
            hangmanView.getMenuItem().addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {// right click key
                    JOptionPane.showMessageDialog(dialogFrame, "Developer: Joe"
                            , "Developer",
                            JOptionPane.INFORMATION_MESSAGE, logo);
                }// end actionPerformed method
            });
        }
    }

另一个类:

public class HangmanView {

    public JMenuItem getMenuItem() {
        JMenuItem menuItem = new JMenuItem("Developer", KeyEvent.VK_T);
        menuItem.addActionListener(new Listener());
        return menuItem;
    }

    public JMenuBar menuBar() {

        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("File");
        menuBar.add(menu);
        menu.add(getMenuItem());// return here
        return menuBar;
    }

最佳答案

如果您尝试为不同的 JMenuItem 实现监听器,我会做的是创建一个可用于多个 的自定义 Action 类>JMenuItem,因为 JMenuItem 是何时使用 Action 的一个很好的示例。

private class MyAction extends AbstractAction {

    String name;

    public MyAction(String name, Icon icon) {
        super(name, icon);
        this.name = name;
    }

    public MyAction(String name, Icon icon, String desc,
            Integer mnemonic, KeyStroke accelorator) {
        super(name, icon);
        putValue(Action.SHORT_DESCRIPTION, desc);
        putValue(Action.MNEMONIC_KEY, mnemonic);
        putValue(Action.ACCELERATOR_KEY, accelorator);
        this.name = name;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        switch (name) {
            case "menu1Action":
                // do something for menuItem1
                break;
            case "menu2Action":
                // do something for menuItem2
                break;
            case "menu3Action":
                // do something for menuItem3
                break;
        }
    }
}

将该类作为 HangmanView 的内部类。然后,您可以为每个 JMenuItem 创建此自定义 Action 类的实例。这是一个例子

Action menu1Action = new MyAction(
 /* arg 1 */    "menu1Action", 
 /* arg 2 */    someIcon,
 /* arg 3 */    "Some Short description of the action",
 /* arg 4 */    new Integer(KeyEvent.VK_T),
 /* arg 5 */    KeyStroke.getKeyStroke(KeyEvent.VK_T, ActionEvent.CTRL_MASK));
  • 第一个参数是操作的名称。该名称将是您将在菜单中看到的名称
  • 第二个参数是您将在名称旁边的菜单中看到的图标。
  • 第三个参数是菜单项操作的描述
  • 第四个参数是助记符(即 Alt + T)。
  • 第五个参数是加速器(即 Ctrl + T)。

当您将 Action 添加到 JMenu 时,该 Action 的标题将自动放置为您在JMenu。因此,您所需要做的就是将此自定义 Action 添加到您的 JMenu 中。您根本不必实际创建 JMenuItemAction 将替代 JMenuItem。只需将所有 MyAction 对象添加到 JMenu 即可。

menu.add(menu1Action);

我遗漏的是 actionPerformed 中每个单独 switch case 的实现。 case 将是您在构造函数中为 action 命名的内容。因为我将 Action 命名为“menu1Action”,所以我应该在 switch case 中具有相应的名称。在这种情况下,当单击或通过键盘访问 JMenuItem 时,您可以执行 JOptionPane 或您希望执行的任何其他操作。

使用Action的另一个巨大好处是它可以服务于多种目的。通过您创建的相同 MyAction menu1Action,您可以对 JToolBar 使用相同的 Action。无需对上述 menu1Action 进行任何更改,您可以执行以下操作:

JTooBar toolbar = new JToolBar();
toolbar.add(menu1Action);

现在,在工具栏和菜单项中,您可以执行相同的操作。工具栏仅显示图标,不显示名称。

这是一个例子。我所做的是创建三个不同的 MyAction 对象。一种用于左对齐,一种用于居中对齐,一种用于右对齐。每个操作对于三个单独的组件(一个菜单项、一个收费栏和一个按钮)分别使用三次

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

public class ActionInterfaceDemo extends JFrame {
    static JPanel buttonPanel = new JPanel();
    static FlowLayout flowLayout = new FlowLayout();

    public ActionInterfaceDemo(){


        ImageIcon centerIcon = new ImageIcon(
                ActionInterfaceDemo.class.getResource("image/centeralignment.png"));
        ImageIcon rightIcon = new ImageIcon(
                ActionInterfaceDemo.class.getResource("image/rightalignment.png"));
        ImageIcon leftIcon = new ImageIcon(
                ActionInterfaceDemo.class.getResource("image/leftalignment.png"));

        Action leftAction = new MyAction("Left", leftIcon,
                "Left alignment for the buttons in the panel",
                new Integer(KeyEvent.VK_L),
                KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.CTRL_MASK));
        Action rightAction = new MyAction("Right", rightIcon,
                "Right alignment for the buttons in the panel",
                new Integer(KeyEvent.VK_R),
                KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK));
        Action centerAction = new MyAction("Center", centerIcon,
                "Center alignment for the buttons in the panel",
                new Integer(KeyEvent.VK_C),
                KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));

        JMenuBar menuBar = new JMenuBar();
        JMenu menuAlignment = new JMenu("Alignment");
        setJMenuBar(menuBar);
        menuBar.add(menuAlignment);

        menuAlignment.add(leftAction);
        menuAlignment.add(centerAction);
        menuAlignment.add(rightAction);

        JToolBar toolBar = new JToolBar("Alignment");
        toolBar.setBorder(BorderFactory.createLineBorder(Color.BLUE));
        toolBar.add(leftAction);
        toolBar.add(centerAction);
        toolBar.add(rightAction);

        buttonPanel.setLayout(flowLayout);
        JButton jbtLeft = new JButton(leftAction);
        JButton jbtCenter = new JButton(centerAction);
        JButton jbtRight = new JButton(rightAction);
        buttonPanel.add(jbtLeft);
        buttonPanel.add(jbtCenter);
        buttonPanel.add(jbtRight);

        add(toolBar, BorderLayout.EAST);
        add(buttonPanel, BorderLayout.CENTER);

        pack();
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                new ActionInterfaceDemo();
            }
        });

    }

    private class MyAction extends AbstractAction {

        String name;

        public MyAction(String name, Icon icon, String desc,
                Integer mnemonic, KeyStroke accelorator) {
            super(name, icon);
            putValue(Action.SHORT_DESCRIPTION, desc);
            putValue(Action.MNEMONIC_KEY, mnemonic);
            putValue(Action.ACCELERATOR_KEY, accelorator);
            this.name = name;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            switch (name) {
                case "Left":
                    flowLayout.setAlignment(FlowLayout.LEFT);
                    break;
                case "Right":
                    flowLayout.setAlignment(FlowLayout.RIGHT);
                    break;
                case "Center":
                    flowLayout.setAlignment(FlowLayout.CENTER);
                    break;
            }
            buttonPanel.revalidate();
        }
    }
}

enter image description here

您可以在菜单、工具栏或按钮中按“向左”键,它们将产生相同的结果,因为它们源自相同的操作

如果您想测试一下,这是我使用的图像

enter image description here enter image description here enter image description here

注意您不必使用这些精确构造函数。您可以使用不同的参数创建自己的。这只是我喜欢使用的自定义一个。

Aslo See How to use Action tutorial

关于java - 如何为多个 JMenuItem 创建 ActionListener?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20820966/

相关文章:

java - Quartz 调度程序不在 dropwizard 应用程序中执行 SQL 查询

Java类调用使用hibernate的方法 - 多次运行时出错

java - 如何在SilkTest中获取Java Swing应用程序对象的属性值?

java - 为什么当我按退出键时框架不关闭?

带有 JFrame 和 JButton 的 Java ActionListener

java - 如何为多个onClick()创建方法?

java - Zookeeper示例-分布式数学计算

java - 如何确定用户显示的中点?

java - 获取 BufferedImage 上像素的颜色

java - 循环内的监听器不允许更改外部 boolean 标志