繁体   English   中英

Java JButton传递对actionlistener的方法调用

[英]Java JButton pass method call to actionlistener

我试图将方法名称传递给动作侦听器,以便它可以在没有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 ,该Map会将actionCommand映射到Command的实例。

public class ... extends ... {
    private Map<String, Command> commands = new HashMap<>(25);
    //...

现在,您可以拥有一个不错的“添加”方法,该方法将允许您动态添加命令,为每个新命令创建一个新的JButton或根据需要在类中JButton设置它

然后在ActionListener ,您只需获取actionCommand属性,在Map查找Command ,然后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();
    }
}

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

这不是一个完美的解决方案,但是尽管我可以在这里说一下...

JButtonSpecial是我的课程,扩展了JButton。 JButtonSpecial将包含您要传递给ActionListener的方法。 然后您可以做类似的事情,

button=new JButtonSpecial("Click Here");
button.addActionListener(new ActionListener(){
   public void actionPerformed(ActionEvent e) {
      JButtonSpecial tmpButton = (JButtonSpecial)e.getSource();
      tmpButton.yourCustomMethod();//this method will be defined in JButtonSpecial
   }
});

我同意您将要在其中对方法名称进行硬编码,但是您可以在对象之间更改方法的实现...

Java没有函数指针,因此您将必须执行以下操作:

private JButton button = new JButton("Click me!");
public YourClass()
{
    ...
    button.setActionCommand("foo");
    button.addActionListener(this);
    ...
}
public void actionPerformed(ActionEvent e)
{
    String command = e.getActionCommand();
    if(command.equals("foo"))
        foo();
    else if(...)
}

另外, e.getSource().getActionCommand()会给您带来语法错误。 getActionCommand()ActionEvent的方法,并且getSource()返回一个对象,因此您可以执行e.getActionCommand()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM