Java 如何为多个JMenuItems创建ActionListener?
我在使用actionListener的匿名内部类时遇到困难。有人能解释一下我的代码有什么问题,以及如何将匿名内部类与actionListener一起使用吗。我试图在一个类中创建菜单栏,在另一个类中创建动作侦听器。我在尝试使用匿名内部类时遇到了一些困难。java网站不清楚。你能给我解释一下并帮我修改代码吗Java 如何为多个JMenuItems创建ActionListener?,java,swing,actionlistener,anonymous-class,jmenuitem,Java,Swing,Actionlistener,Anonymous Class,Jmenuitem,我在使用actionListener的匿名内部类时遇到困难。有人能解释一下我的代码有什么问题,以及如何将匿名内部类与actionListener一起使用吗。我试图在一个类中创建菜单栏,在另一个类中创建动作侦听器。我在尝试使用匿名内部类时遇到了一些困难。java网站不清楚。你能给我解释一下并帮我修改代码吗 public class Listener implements ActionListener { HangmanView hangmanView = new HangmanV
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;
}
Listener
,通过其继承层次结构成为ActionListener
public class Listener implements ActionListener {
需要实现actionperformed(ActionEvent)
方法
@Override
public void actionPerformed(ActionEvent e) {
// implement it
}
但是,由于您似乎要添加一个匿名的
ActionListener
,所以不要让您的Listener
类实现ActionListener
。删除该位。Listener
,通过继承层次结构作为ActionListener
public class Listener implements ActionListener {
需要实现actionperformed(ActionEvent)
方法
@Override
public void actionPerformed(ActionEvent e) {
// implement it
}
但是,由于您似乎要添加一个匿名的
ActionListener
,所以不要让您的Listener
类实现ActionListener
。删除该位。Listener
,通过继承层次结构作为ActionListener
public class Listener implements ActionListener {
需要实现actionperformed(ActionEvent)
方法
@Override
public void actionPerformed(ActionEvent e) {
// implement it
}
但是,由于您似乎要添加一个匿名的
ActionListener
,所以不要让您的Listener
类实现ActionListener
。删除该位。Listener
,通过继承层次结构作为ActionListener
public class Listener implements ActionListener {
需要实现actionperformed(ActionEvent)
方法
@Override
public void actionPerformed(ActionEvent e) {
// implement it
}
但是,由于您似乎要添加一个匿名的
ActionListener
,所以不要让您的Listener
类实现ActionListener
。删除该位。如果您试图为不同的JMenuItem
s实现侦听器,那么我要做的是创建一个自定义的Action
类,您可以将它用于多个JMenuItem
s,因为JMenuItem
s是何时使用操作的一个很好的例子
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)
当您向JMenu
添加操作时,该操作的标题将自动放置为您在JMenu
中看到的标题。因此,您只需将此自定义操作添加到JMenu
。您根本不需要实际创建JMenuItem
。操作
将替代JMenuItem
。只需将所有MyAction
对象添加到JMenu
menu.add(menu1Action);
我遗漏的是actionPerformed
中每个单独的开关案例的实现。案例
将是您在构造函数中命名的操作
。因为我将操作命名为“menu1Action”,所以在开关的大小写中应该有相应的名称。在这种情况下,您可以执行您的JOptionPane
,或者在单击或通过键盘访问JMenuItem
时希望执行的任何其他操作
使用操作
的另一大好处是它可以服务于多种用途。使用您创建的相同的MyAction menu1Action
,您可以对JToolBar
使用相同的Action
。无需对上述菜单1操作进行任何更改,您只需执行以下操作:
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();
}
}
}
您可以按菜单、工具栏或按钮中的“左”键,它们将产生相同的结果,因为它们来自相同的操作
如果你想测试的话,这里是我使用的图片
注意您不必使用这两个确切的构造函数中的任何一个。您可以使用不同的参数创建自己的参数。这只是我喜欢使用的一个定制的
另请参见如果您试图为不同的JMenuItem
s实现侦听器,我要做的是创建一个自定义的Action
类,您可以将其用于多个JMenuItem
s,因为JMenuItem
是何时使用操作的一个很好的示例
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)