【问题标题】:Trying to add ActionListener to JButtons尝试将 ActionListener 添加到 JButtons
【发布时间】:2014-10-26 22:23:45
【问题描述】:

我不知道如何将Actionlisteners 添加到JButtons,任何帮助将不胜感激。

public class Translator extends JPanel implements MouseListener, ActionListener {       

    private JButton french = new JButton();
    private JButton german = new JButton();
    private JButton irish = new JButton();

    public Translator(){
        french = new JButton("French");
        german = new JButton("German");
        irish = new JButton("Irish");           
        setLayout(new GridLayout(2,1));         
        buttonPanel.setLayout(new GridLayout(1,3));
        buttonPanel.add(french);
        buttonPanel.add(german);
        buttonPanel.add(irish);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
    }
}

【问题讨论】:

  • buttonName.addActionListener(this);

标签: java swing jbutton actionlistener


【解决方案1】:
french.addActionListener(an_instance_of_the_class_where_actionPerformed_is);

正如我在编辑后看到的那样,应该是 this

另外,请参阅this Example 和网络这个角落的一些教程文本

我认为对教程的引用和许多示例是高度相关的。

【讨论】:

    【解决方案2】:
    JButton button = new JButton("Button");
    button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
            //To-Do
            //Button clicked
            });
    

    希望这会有所帮助,它相对简单!您只需将 ActionListener 添加到所需的 JButton

    为了让您更广泛地了解如何在我想在按下按钮后运行新的 GUI 框架的案例场景中实现它:

    startNewFrame.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Starting new frame");
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        NewFrame newFrame = new NewFrame();
                        newFrame.setVisible(true);
                        dispose();//Disposes of current frame
                    }
                });
            }
        });
    

    【讨论】:

      【解决方案3】:
      button.addActionListener(<your_ActionListener_here>);
      

      在你的情况下,它将是:

      french.addActionListener(this);
      

      如果要对所有三个按钮使用相同的 ActionListener,可以使用 ActionEvent e 的 getSource() 函数来检测实际按下了哪个按钮。

      【讨论】:

        【解决方案4】:

        如果你使用的是Java8,你可以试试这个。

        JButton french = new JButton("French");
        french.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent ae){
                System.out.println("Button french clicked!");
            }
        });
        french.addActionListener(button -> System.out.println("Button Click listener..."));
        JFrame frame = new JFrame("Button Listener Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(french, BorderLayout.CENTER);
        frame.setSize(250, 250);
        frame.setVisible(true);
        

        【讨论】:

        • 最好不要将ActionEvent 变量命名为button
        【解决方案5】:

        有很多方法可以将ActionListener 添加到给定的JComponent(支持它的使用)。我在代码 sn-ps 中添加了一些 cmets,以帮助更好地解释它们,并在 cmets 中添加了一些链接以供将来参考。

        1.) 如果类实现了ActionListener接口,即类本身包含actionPerformed(...)方法,那么可以这样做:

        import java.awt.*;
        import java.awt.event.*;
        import javax.swing.*;
        
        public class Skeleton implements ActionListener {   
        
            private JFrame frame;
            private JPanel contentPane;
            private JButton button;
        
            private void displayGUI() {
                frame = new JFrame("Skeleton");
                /*
                 * EXIT_ON_CLOSE is same as putting System.exit(0),
                 * which in some sense, doesnot allows one's
                 * application to terminate graciously.
                 */ 
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        
                contentPane = new JPanel();
                button = new JButton("This is a button.");
                /*
                 * This is one way of attaching an ActionListener
                 * to the JButton, but the main disadvantage of
                 * this approach is, it breaks encapsulation,
                 * as you can see the public method, actionPerformed(),
                 * is lying free to be accessed by any code outside
                 * the scope of the class
                 */
                button.addActionListener(this);
        
                contentPane.add(button);
        
                frame.setContentPane(contentPane);        
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);                                
            }
        
            public static void main(String[] args) {
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        new Skeleton().displayGUI();
                    }
                };
                EventQueue.invokeLater(runnable);
            }
        
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(frame, "BINGO!",
                    "Information: ", JOptionPane.INFORMATION_MESSAGE);
            }    
        }
        

        2.) 如果不想创建不必要的class 文件。然后可以使用这种使用 EventHandler 的方法:

        import java.awt.*;
        import java.awt.event.*;
        import java.beans.EventHandler;
        import javax.swing.*;
        
        public class Example1 { 
        
            private JFrame frame;
            private JPanel contentPane;
            private JButton button;
        
            private void displayGUI() {
                frame = new JFrame("Skeleton");
                /*
                 * EXIT_ON_CLOSE is same as putting System.exit(0),
                 * which in some sense, doesnot allows one's
                 * application to terminate graciously.
                 */ 
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        
                contentPane = new JPanel();
                button = new JButton("This is a button.");
                /*
                 * This is another way of attaching 
                 * an ActionListener to the JButton,
                 * the main advantage of this approach
                 * is, that one does not have to create
                 * a new class to handle events
                 * More info regarding the use of this 
                 * approach, can be found on this link : 
                 * http://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html
                 */
                button.addActionListener((ActionListener)
                        EventHandler.create(ActionListener.class
                                , Example1.this, "buttonAction", ""));
        
                contentPane.add(button);
        
                frame.setContentPane(contentPane);        
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);                                
            }
        
            public static void main(String[] args) {
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        new Example1().displayGUI();
                    }
                };
                EventQueue.invokeLater(runnable);
            }
        
            public void buttonAction(ActionEvent e) {
                JOptionPane.showMessageDialog(frame, "BINGO!",
                    "Information: ", JOptionPane.INFORMATION_MESSAGE);
            }    
        }
        

        3.) 如果有人更关心Encapsulation的概念,那么这种方法是有益的:

        import java.awt.*;
        import java.awt.event.*;
        import javax.swing.*;
        
        public class Example2 { 
        
            private JFrame frame;
            private JPanel contentPane;
            private JButton button;
        
            private ActionListener buttonActions = 
                                    new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    JOptionPane.showMessageDialog(frame, "BINGO!",
                        "Information: ", JOptionPane.INFORMATION_MESSAGE);
                }
            };
        
            private void displayGUI() {
                frame = new JFrame("Skeleton");
                /*
                 * EXIT_ON_CLOSE is same as putting System.exit(0),
                 * which in some sense, doesnot allows one's
                 * application to terminate graciously.
                 */ 
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        
                contentPane = new JPanel();
                button = new JButton("This is a button.");
                /*
                 * This is another way of attaching 
                 * an ActionListener to the JButton,
                 * the main advantage of this approach
                 * is, it adheres to encapsulation.
                 */
                button.addActionListener(buttonActions);
        
                contentPane.add(button);
        
                frame.setContentPane(contentPane);        
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);                                
            }
        
            public static void main(String[] args) {
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        new Example2().displayGUI();
                    }
                };
                EventQueue.invokeLater(runnable);
            }    
        }
        

        4.) 如果更倾向于创建匿名类,那么可以使用这种方法:

        import java.awt.*;
        import java.awt.event.*;
        import javax.swing.*;
        
        public class Example3 { 
        
            private JFrame frame;
            private JPanel contentPane;
            private JButton button;
        
            private void displayGUI() {
                frame = new JFrame("Skeleton");
                /*
                 * EXIT_ON_CLOSE is same as putting System.exit(0),
                 * which in some sense, doesnot allows one's
                 * application to terminate graciously.
                 */ 
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        
                contentPane = new JPanel();
                button = new JButton("This is a button.");
                /* 
                 * This is the fourth way of attaching  
                 * an ActionListener to the JButton, 
                 * the main advantage of this approach 
                 * is, it adheres to encapsulation, the 
                 * public method remains hidden
                 * inside the Anonymous Class
                 * More info can be found on this link : 
                 * http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
                 * The main disadvantage of this approach is
                 * that it doesnot gives you the privilege
                 * of separation of concerns, which can
                 * be done using the fifth approach,
                 * which is MVC - Pattern (Model-View-Controller)
                 * and moreover, it creates a hell lot of classes, in 
                 * your project, which can lead to extra overhead
                 */
                button.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent ae) {
                        JOptionPane.showMessageDialog(frame, "BINGO!",
                            "Information: ", JOptionPane.INFORMATION_MESSAGE);
                    }
                });
        
                contentPane.add(button);
        
                frame.setContentPane(contentPane);        
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);                                
            }
        
            public static void main(String[] args) {
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        new Example3().displayGUI();
                    }
                };
                EventQueue.invokeLater(runnable);
            }    
        }
        

        编辑:

        5.) 这种方法包括使用Action 而不是ActionListener。这将用于在各种JComponents 之间共享相同的功能,从而导致代码可重用

        import java.awt.*;
        import java.awt.event.*;
        import javax.swing.*;
        
        public class Example4 { 
        
            private JFrame frame;
            private JPanel contentPane;
            private JMenuItem showMenuItem;
            private JButton button;
        
            private Action myActions;
        
            /*
             * This approach is basically used, when
             * one wants to share the same functionality
             * of different JComponents among each other,
             * without writing redundant codes for each
             * one of those components. Here JMenuItem
             * and JButton are both using the same 
             * functionality, to perform the same task.
             * More info can be found on this link:
             * http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html
             */
            private class MyActions extends AbstractAction {
                public MyActions(String title, String desc) {
                    super(title);
                    putValue(SHORT_DESCRIPTION, desc);
                }
        
                @Override
                public void actionPerformed(ActionEvent ae) {
                    JOptionPane.showMessageDialog(frame, "BINGO!",
                            "Information: ", JOptionPane.INFORMATION_MESSAGE);
                }
            }
        
            private void displayGUI() {
                frame = new JFrame("Skeleton");
                /*
                 * EXIT_ON_CLOSE is same as putting System.exit(0),
                 * which in some sense, doesnot allows one's
                 * application to terminate graciously.
                 */ 
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        
                contentPane = new JPanel();
                button = new JButton("This is a button.");
        
                myActions = new MyActions("Show", "A small description");
                button.setAction(myActions);
        
                contentPane.add(button);
        
                frame.setJMenuBar(getJMenuBar());
                frame.setContentPane(contentPane);        
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);                                
            }
        
            private JMenuBar getJMenuBar() {
                JMenuBar menuBar = new JMenuBar();
                JMenu fileMenu = new JMenu("File");
                showMenuItem = new JMenuItem(myActions);
                fileMenu.add(showMenuItem);
        
                menuBar.add(fileMenu);
        
                return menuBar;
            }
        
            public static void main(String[] args) {
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        new Example4().displayGUI();
                    }
                };
                EventQueue.invokeLater(runnable);
            }    
        }
        

        【讨论】:

        【解决方案6】:

        显然,答案是将this 放入您的addActionListener 方法中。

        addActionListener 方法将 实现 ActionListener 接口的对象作为参数,该接口强制您实现/放置在您的代码中的actionPerformed 方法,它是当一个动作被触发到分配的组件时被调用。

        因此,将this 放入您的方法中,它将在您传递的对象(在我们的例子中为Translator 对象)中搜索actionPerformed 方法并调用它。

        this.french.addActionListener(this);
        

        当然,为了工作,还缺少很多代码。

        我真的很喜欢 @Sandeep 回答使用 lambda 表达式。 您可以在下面查看完整示例。

        import java.awt.GridLayout;
        import java.awt.event.ActionEvent;
        import java.awt.event.ActionListener;
        import javax.swing.JButton;
        import javax.swing.JFrame;
        import javax.swing.JPanel;
        
        public class Translator extends JPanel implements ActionListener {       
        
            private JButton french = new JButton();
            private JButton german = new JButton();
            private JButton irish = new JButton();
        
            @SuppressWarnings("empty-statement")
            public Translator(){
                french = new JButton("French");
                german = new JButton("German");
                irish = new JButton("Irish");           
        //        setLayout(new GridLayout(2,1));         
                this.setLayout(new GridLayout(1,3));
                this.add(french);
                this.add(german);
                this.add(irish);
        
                ActionListener ac = (ActionEvent ae) -> { System.out.println(((JButton) ae.getSource()).getText()); };
                this.french.addActionListener(ac);
                this.german.addActionListener(ac);
                this.irish.addActionListener(ac);
                this.irish.addActionListener(Translator.this);
        
            }
        
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(((JButton) e.getSource()).getText());
            }
        
            public static void main(String[] args) {
                JFrame jframe = new JFrame("StackOverflow");
                jframe.add(new Translator());
                jframe.pack();
                jframe.setLocationRelativeTo(null);
                jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                jframe.setVisible(true);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2015-11-07
          • 1970-01-01
          • 2014-08-29
          • 1970-01-01
          • 1970-01-01
          • 2013-04-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-30
          相关资源
          最近更新 更多