我试图将方法名称传递给动作侦听器,以便它可以在没有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();
    }
}


现在,这是一个非常基本的示例,并且可能会更复杂,具体取决于您的需求,但是它展示了基本思想

10-07 19:00
查看更多