Java swing: Three ways to implement ActionListener listener

Swing is an indispensable window tool group in Java and a powerful tool for users to build graphical user interface (GUI) programs. Java Swing components automatically generate events to respond to user behavior. When a user clicks a button or selects a menu item, the Swing component generates an Action Event. Swing components generate many events, such as ActionEvent s, ChangeEvents, ItemEvents, etc., to respond to user's mouse click behavior, list box median changes, timer start timing behavior. In Java Swing programming, by registering listeners, we can listen for events generated by event sources, thus handling user behavior that we need to deal with in event handlers.
  
The general steps for handling component events in Java Swing are:
  
1. Create a new component (e.g. JButton).
  
2. Add the component to the appropriate panel (such as JPanel).
  
3. Register the listener to listen for events generated by the event source (e.g. by responding to the user clicking the button through the ActionListener).
  
4. Define methods for handling events (e.g. in actionPerformed in ActionListener).
  
The above steps can be implemented in many ways. But people usually use two methods. The first method is to use only one listener and multiple if statements to determine which component produces the event; the second method is to use multiple internal classes to respond to the various events generated by different components. Its implementation can be divided into two ways, one is anonymous internal classes, the other is general internal classes.
  
To illustrate how to use the above three methods to implement event handling, we build a simple application. The program interface has two buttons, when the user clicks on the corresponding button, a dialog box will pop up to display the corresponding content. With this simple program, you can implement more and more complex user interface programs.  
  
First, we use a single listener to implement the program. We define a class called Simple1 to include all the code. All user behavior (such as clicking on a button) is handled by an action Performed method in a listener SimpleListener. The following is the code:

 /**
  * Simple1.java - The first way to handle events
  * In this example, an ActionListener is used to listen for events generated by the event source.
  * Use some if statements to determine which event source it is
  */
  
  
  import java.awt.*;
  import java.awt.event.*;
  import javax.swing.*;
  
  public class Simple1
  {
       private static JFrame frame; //Define static variables for main to use
       private static JPanel myPanel; //The panel is used to place button components
       private JButton button1; //Define the button component here
       private JButton button2; //To enable ActionListener to use
   
       public Simple1() //Constructor, graphical interface
       {
           //New panel
           myPanel = new JPanel();
           //New button
           button1 = new JButton("Button 1"); //New button 1
           button2 = new JButton("Button 2");
  
           SimpleListener ourListener = new SimpleListener();
          //Create an action listener for two buttons to share
           button1.addActionListener(ourListener);
           button2.addActionListener(ourListener);
  
           myPanel.add(button1); //Add buttons to the panel
           myPanel.add(button2);
       }
  
       private class SimpleListener implements ActionListener
       {
       /**
       * Use this internal class to listen for events generated by all event sources
       * Easy to handle event code modularization
       */
           public void actionPerformed(ActionEvent e)
           {
               //Get the button name using getAction Command
               //You can also use getSource()
               // if (e.getSource() ==button1)
  
               String buttonName = e.getActionCommand();
               if (buttonName.equals("Button 1"))
               JOptionPane.showMessageDialog(frame,
               "Button 1 Be clicked");
               else if (buttonName.equals("Button 2"))
               JOptionPane.showMessageDialog(frame,
               "Button 2 Be clicked");
               else
               JOptionPane.showMessageDialog(frame,
               "Unknown event" );
           }
       }
  
       public static void main(String s[])
       {
           Simple1 gui = new Simple1(); //New Simple1 component
           
           frame = new JFrame("Simple1"); //New JFrame
           //Common methods for handling closure events
           frame.addWindowListener(new WindowAdapter() {
           public void windowClosing(WindowEvent e)
           {System.exit(0);} });
          
           frame.getContentPane().add(myPanel);
           frame.pack(); 
           frame.setVisible(true);
       }
  }
  


Let's see how the above code works. In the main method, we define a JFrame and then add the panel Jpanel to the form, which contains two buttons. The corresponding variables Frame,button1,button2 are defined at the beginning of the program.
  
In the main method of program entry, we first create a new Simple1 component, build a user GUI through the constructor, define a panel Jpanle, add two buttons, then use JButton. addAction Lister to add two buttons to an activity monitor SimpleLister, and finally, add two buttons to the panel. When the GUI is established, we add panels to the form and display the results. When the user clicks the button, the program calls the actionPerformed method to determine which button is clicked through the if statement, and then displays the corresponding content in the dialog box.
  
The disadvantage of using a listener to deal with events is that when the program is complex, it needs a large number of if statements to implement, and the program code is difficult to read and maintain. Of course, this approach is simpler if fewer events are handled.
  
These problems can be solved by using anonymous inner classes. Use a simple anonymous inner class as a variable for addActionListener. The following is the implementation code:

 /**
  * Simple2.java - The second way to handle events
  * In this example, anonymous inner classes are used to listen for events generated by each event source.
  * Avoid using some if statements to determine which event source it is
  */
  
  import java.awt.*;
  import java.awt.event.*;
  import javax.swing.*;
  
  public class Simple2
  {
       private static JFrame frame; //Define static variables for main to use
       private static JPanel myPanel; //The panel is used to place button components
       private JButton button1; //Define the button component here
       private JButton button2; //To enable ActionListener to use
       
       public Simple2() //Constructor, graphical interface
       {
           //New panel
           myPanel = new JPanel();
           //New button
           button1 = new JButton("Button 1"); //New button 1
           button2 = new JButton("Button 2");
          
           //Each event source needs a listener
           //Define an anonymous inner class to listen for events generated by event sources
           button1.addActionListener(
               new ActionListener()
               {
                   public void actionPerformed(ActionEvent e)
                   {
                       JOptionPane.showMessageDialog(frame,"Button 1 Be clicked");
                   }
               }
           );
          
           button2.addActionListener(
               new ActionListener()
               {
                   public void actionPerformed(ActionEvent e)
                   {
                       JOptionPane.showMessageDialog(frame,"Button 2 Be clicked");
                   }
               }
           );
          
           myPanel.add(button1); //Add buttons to the panel
           myPanel.add(button2);
        }
          
        public static void main(String s[])
        {
            Simple2 gui = new Simple2(); //New Simple2 components
                               
            frame = new JFrame("Simple2"); //New JFrame
            //Common methods for handling closure events
            frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e)
            {System.exit(0);} });
            frame.getContentPane().add(myPanel);
            frame.pack(); 
            frame.setVisible(true);
        }
  }


There are also many other problems with using anonymous inner classes. First of all, according to the different locations of components defined in the code, the definition of classes and the code dealing with events will be scattered in all parts of the program, not centralized, and also not easy to read and maintain. The processing of each event is all composed of nested program blocks. It is very difficult to locate the program code visually. If the event handler is complex, the code in the inner class will become very long, and you will not find the corresponding component definition location. Finally, when toolbars, menu columns, etc. need to deal with the same user behavior, this method will make the code more difficult to maintain.
  
We can solve many of these problems by using generic named inner classes. All event handling methods are clustered together and have meaningful names. The program is very easy to read and maintain. Individual event handlers can also be reused by toolbars, menu bars, etc.
  
The following is the implementation code:

 /**
  * Simple3.java - The third way to handle events
  * For this example, we will use inner member classes to
  * In this example, a general internal class is used to listen for events generated by each event source.
  * This method avoids the code confusion caused by using anonymous inner classes in the second method.
  * Easy to centralize event code
  * Each Hander can be used multiple times by toolbars or menus
  */
  import java.awt.*;
  import java.awt.event.*;
  import javax.swing.*;
  
  public class Simple3
  {
       private static JFrame frame; //Define static variables for main to use
       private static JPanel myPanel; //The panel is used to place button components
       private JButton button1; //Define the button component here
       private JButton button2; //To enable ActionListener to use
       
       //Use general internal classes to monitor events generated by each event source, such as (button1, button2)
       private class Button1Handler implements ActionListener
       {
           public void actionPerformed(ActionEvent e)
           {
               JOptionPane.showMessageDialog(frame,"Button 1 Be clicked");
           }
       }
       
       private class Button2Handler implements ActionListener
       {
           public void actionPerformed(ActionEvent e)
           {
               JOptionPane.showMessageDialog(frame,"Button 2 Be clicked");
           }
       }
       
       public Simple3() //// Constructor, graphical interface
       {
           //New panel
           myPanel = new JPanel();
           //New button
           button1 = new JButton("Button 1"); //New button 1
           button2 = new JButton("Button 2");
          
           //Register and listen for internal classes for each component
           button1.addActionListener(new Button1Handler());
           button2.addActionListener(new Button2Handler());
          
           myPanel.add(button1); //Add buttons to the panel
           myPanel.add(button2);
       }
      
       public static void main(String s[])
       {
           Simple3 gui = new Simple3(); //New Simple3 components
          
           frame = new JFrame("Simple3"); //New JFrame
           //The usual way to handle closure events
           frame.addWindowListener(new WindowAdapter() {
               public void windowClosing(WindowEvent e)
               {System.exit(0);} });
          
           frame.getContentPane().add(myPanel);
           frame.pack(); 
           frame.setVisible(true);
       }
  }

Keywords: Java Programming

Added by Quevas on Fri, 31 May 2019 22:38:16 +0300