Markus Tonsaker
Markus Tonsaker

Reputation: 479

Which way is correct? Multiple ActionListeners vs One ActionListener

Which way of implementing an ActionListener is more correct? Is there any major performance differences?

Implementing an ActionListener to the class:

public class MainFrame implements ActionListener {

    JButton exampleButton1 = new JButton();
    JButton exampleButton2 = new JButton();
    JButton exampleButton3 = new JButton();

    public MainFrame(){
        exampleButton1.addActionListener(this);
        exampleButton2.addActionListener(this);
        exampleButton3.addActionListener(this);
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        Object src = e.getSource();

        if(src.equals(exampleButton1)){
            //Do something
        }else if(src.equals(exampleButton2)){
            //Do something
        }else if(src.equals(exampleButton3)){
            //Do something
        }
    }
}

Versus adding ActionListeners to each JButton:

public class MainFrame {

    JButton exampleButton1 = new JButton();
    JButton exampleButton2 = new JButton();
    JButton exampleButton3 = new JButton();

    public MainFrame(){
        exampleButton1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //Do something
            }
        });

        exampleButton2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //Do something
            }
        });

        exampleButton3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //Do something
            }
        });
    }
}

Or perhaps even using Lambdas..?

Upvotes: 0

Views: 509

Answers (3)

Yuriy N.
Yuriy N.

Reputation: 6107

If someone is still using Swing in 2024, the code below, though looks weird, works.

 public class HelpMenuitem extends JMenuItem implements ActionListener{
    
    HelpMenuitem(){
        this.setText("Help");
        this.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Help button clicked");
    }
    
}

Upvotes: 0

michaeak
michaeak

Reputation: 1669

As you can spot, for single ActionListener-approach there are three more branches for each single if test, which button was pressed. There was nothing done yet, so no real action, just testing which button was pressed.

  • Now, if you want to achieve high quality work there are metrics like branch coverage. Firstly, If you go for the single ActionListener-approach each of your if is creating two branches. So you have to come up with 6 tests to just test if the base idea of your ActionListener is working correctly, so to find out which button was pressed and the correct if part was used. This is some overhead effort.

  • Secondly, there is the Single Responsibility Paradigm (SRP). It states that each class should be responsibly for one task only. Now, there are three things this single ActionListener is handling.

  • Thirdly, the reusage of the single ActionListener is very limited and highly depending on the buttons.

  • Fourthly, I also call this kind of single ActionListener-approach Manual written Object Orientation, because this would be an approach if there was no object orientation and you have to switch or if/else for calling different methods, like exampleButton1Pressed(), exampleButton2Pressed() etc. But, this can be achieved by three dedicated ActionListeners.

So go for dedicated ActionListeners.

Upvotes: 1

camickr
camickr

Reputation: 324118

I would prefer to use an individual Action as the listener for the button. An Action is a slightly more advanced listener that can be used anywhere an ActionListener can be used.

It provides additional functionality such as:

  1. The same Action can be used by multiple components, such as a JButton, JMenuItem
  2. You can disable the Action, which will disable all components that use the Action
  3. It allows to assign mnemonics and accelerators to your components

See the Swing tutorial on How to Use Actions for more information and examples on this concept.

Upvotes: 2

Related Questions