Trying to add ActionListener to JButtons

后端 未结 6 1138
忘掉有多难
忘掉有多难 2020-12-21 23:50

I cannot figure out how to add Actionlisteners to the JButtons, any help would be much appreciated.

public class Translator extends         


        
6条回答
  •  梦毁少年i
    2020-12-22 00:25

    There are plenty of ways to add an ActionListener, to a given JComponent (that supports it's use). I have added some comments in the code snippets, to help explain them a bit better, and some links in the comments for future reference.

    1.) If the class implements the ActionListener interface, i.e. the class itself contains the actionPerformed(...) method, then one can do it, in this manner:

    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.) If one doesn't wants to create unnecessary class files. Then this approach, which uses, EventHandler can be used:

    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.) If one is more concern about the concept of Encapsulation, then this approach is beneficial:

    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.) If one is more inclined towards creation of Anonymous Classes, then this approach can be used:

    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);
        }    
    }
    

    EDIT:

    5.) This approach, includes using Action instead of ActionListener. This is to be used for sharing same functionality among various JComponents, which leads to code reusability

    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);
        }    
    }
    

提交回复
热议问题