我在使用带有 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
类>JMenuItemJMenuItem
是何时使用 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
中。您根本不必实际创建 JMenuItem
。 Action
将替代 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();
}
}
}
您可以在菜单、工具栏或按钮中按“向左”键,它们将产生相同的结果,因为它们源自相同的操作
。
如果您想测试一下,这是我使用的图像
注意您不必使用这些精确构造函数。您可以使用不同的参数创建自己的。这只是我喜欢使用的自定义一个。
Aslo See How to use Action tutorial
关于java - 如何为多个 JMenuItem 创建 ActionListener?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20820966/