我试图将方法名称传递给动作侦听器,以便它可以在没有50个if语句的情况下调用该方法。我知道在C ++中有函数指针,但是在Java中这不是问题。 Java中是否有一种方法可以使某些东西符合
actionPerfomed(ActionEvent e){
String command = e.getSource().getActionCommand()
//use command to look up a method on the implementing class
//and call it without an if
所有需要调用的方法都没有返回值,也没有需要传递给它们的值,它们可以从拥有它的框架中获取所有需要的信息。我认为反射是一个有效的选择,但是我在Java中的使用经验有限,而且我从没读过任何有关它的文章。
这是针对框架构想的,这样就可以将ActionListener从项目中剥离出来,并且几乎不需要修改就可以重用。我正在与其他人一起在我的工作中开发的框架一起工作,该框架使用C#进行编写,并且编写了这个人在编写时所从事的工作。因此,我尝试创建它的Java实现,因为C#具有其局限性(Windows)。
最佳答案
您可以通过几种方法来做到这一点,一种可能是设计一个通用接口,所有“命令”都需要实现该接口,它只有一个方法,您的ActionListener
然后可以执行该方法。
例如...
public interface Command {
public void execute();
}
然后,您的UI中将有一个
Map
,它将actionCommand
映射到Command
的实例public class ... extends ... {
private Map<String, Command> commands = new HashMap<>(25);
//...
现在,您可以使用一个不错的“添加”方法,该方法可让您动态添加命令,为每个新命令创建一个新的
JButton
或根据需要在类中自行设置然后在您的
ActionListener
中,只需获取actionCommand
属性,在Command
中查找Map
,然后在execute
处将其有效@Override
public void actionPerformed(ActionEvent e) {
Command cmd = commands.get(e.getActionCommand());
if (cmd != null) {
cmd.execute();
}
}
例如...
package javaapplication659;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestCommand {
public static void main(String[] args) {
new TestCommand();
}
public TestCommand() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Map<String, Command> commands = new HashMap<>(25);
private ActionListener actionListener;
private GridBagConstraints gbc;
public TestPane() {
setLayout(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(1, 1, 1, 1);
actionListener = new ActionHandler();
add("Take over the world", new Command() {
@Override
public void execute() {
System.out.println("Take over the world");
}
});
add("Quwell up rising", new Command() {
@Override
public void execute() {
System.out.println("Bring the boot down");
}
});
add("Buy milk", new Command() {
@Override
public void execute() {
System.out.println("Buy milk");
}
});
}
public void add(String text, Command cmd) {
JButton btn = new JButton(text);
btn.addActionListener(actionListener);
commands.put(text, cmd);
add(btn, gbc);
}
public class ActionHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Command cmd = commands.get(e.getActionCommand());
if (cmd != null) {
cmd.execute();
}
}
}
}
public interface Command {
public void execute();
}
}
现在,这是一个非常基本的示例,并且可能会更复杂,具体取决于您的需求,但是它展示了基本思想