簡體   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