TheMightyLlama
TheMightyLlama

Reputation: 1273

How can I create a single ActionListener for multiple JButtons

I'm creating a basic calculator using MVC. So far I'm adapting a tutorial which merely sums two user entered values together.

Currently each button I'm adding to the view has it's own listener, which is ok. However, the controller as per the tutorial has a single ActionListener inner class per button. This repeats a huge amount of code.

How can I create a single ActionListener class for all buttons pressed, and use a case statement on the id of the button pressed?

Registering the oneButton in the View

void oneListener(ActionListener listenForOneButton){    
    oneButton.addActionListener(listenForOneButton);
}    

Implementing the ActionListener for the oneButton in the Controller inner class

class oneListener implements ActionListener{
    public void actionPerformed(ActionEvent e){
        int previousNumber, displayNumber = 0;          
        try{
            previousNumber = theView.getPreviousDisplayNumber();
            displayNumber = previousNumber+1;               
            theView.setDisplayNumber(displayNumber);
        }           
        catch(NumberFormatException ex){                
            System.out.println(ex);             
            theView.displayErrorMessage("You Need to Enter Integers");              
        }           
    }
}

Upvotes: 0

Views: 2165

Answers (2)

AvmnuSng
AvmnuSng

Reputation: 335

public class SingleActionListener implements ActionListener {
    public void initializeButtons() {
        JButton[] buttons = new JButton[4];
        String[] buttonNames = new String[] {"button1", "button2", "button3", "button4"};

        for (int i = 0; i < 4; i++) {
            buttons[i] = new JButton(buttonNames[i]);
        }
    }

    public void addActionListenersToButtons() {
        for (int i = 0; i < 4; i++) {
            buttons[i].addActionListener(this);
        }
    }

    public void actionPerformedd(ActionEvent actionEvent) {
        if (actionEvent.getSource() == buttons[0]) {
            //Do required tasks.
        }

        if (actionEvent.getSource() == buttons[1]) {
            //Do required tasks.
        }

        if (actionEvent.getSource() == buttons[2]) {
            //Do required tasks.
        }

        if (actionEvent.getSource() == buttons[3]) {
            //Do required tasks.
        }
    }
}

Upvotes: 1

MadProgrammer
MadProgrammer

Reputation: 347204

Start with class which implements ActionListener...

public class CalculatorHandler implements ActionListener{

    public static final String ADD_ACTION_COMMAND = "Action.add";

    public void actionPerformed(ActionEvent e){

        if (ADD_ACTION_COMMAND.equals(e.getActionCommand()) {
            // Do your addition...
        } else if ...

    }
}

It's best to define the action commands that this class can handle is constants, thus removing any ambiguity...

Next, in the class that holds the buttons, create an instance of the ActionListener...

CalculatorHandler handler = new CalculatorHandler();

Then create you buttons as per usual and register the handler...

JButton plus = new JButton("+");
plus.setActionCommand(CalculatorHandler.ADD_ACTION_COMMAND);
plus.addActionListener(handler);

The only problem with this approach, IMHO, is that it can create a monster if-else statement which may become difficult to maintain.

To my mind, I'd create some kind of model/builder that contained a series of helper methods (like add(Number), subtract(Number) etc) and use Actions API for the individual actions for each button...but that's just me...

Upvotes: 2

Related Questions