kraikov
kraikov

Reputation: 53

Individual class for each Action Listener?

My application has 15 different buttons and I've been wondering if it's a good idea to have a individual class for each button listener? I currently have only one class that handles all buttons using switch/case but it's hard to maintain and read.

I'm not huge fan of using anonymous classes - again because of the readability.

Any suggestions that can help me resolve this issue would be appreciated.

I'm using Java Swing if this matters.

Upvotes: 1

Views: 1042

Answers (2)

camickr
camickr

Reputation: 324118

Here is an example of the same listener being used by multiple buttons:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class CalculatorPanel extends JPanel
{
    private JTextField display;

    public CalculatorPanel()
    {
        Action numberAction = new AbstractAction()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
//              display.setCaretPosition( display.getDocument().getLength() );
                display.replaceSelection(e.getActionCommand());
            }
        };

        setLayout( new BorderLayout() );

        display = new JTextField();
        display.setEditable( false );
        display.setHorizontalAlignment(JTextField.RIGHT);
        add(display, BorderLayout.NORTH);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout( new GridLayout(0, 5) );
        add(buttonPanel, BorderLayout.CENTER);

        for (int i = 0; i < 10; i++)
        {
            String text = String.valueOf(i);
            JButton button = new JButton( text );
            button.addActionListener( numberAction );
            button.setBorder( new LineBorder(Color.BLACK) );
//          button.setPreferredSize( new Dimension(50, 50) );
            buttonPanel.add( button );

            InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
            inputMap.put(KeyStroke.getKeyStroke(text), text);
            inputMap.put(KeyStroke.getKeyStroke("NUMPAD" + text), text);
            button.getActionMap().put(text, numberAction);
        }
    }

    private static void createAndShowUI()
    {
        UIManager.put("Button.margin", new Insets(10, 10, 10, 10) );

        JFrame frame = new JFrame("Calculator Panel");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add( new CalculatorPanel() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

Upvotes: 1

alainlompo
alainlompo

Reputation: 4434

You can use one class but it is not a good dsign because you need to apply a principle of separation of concerns. You want coherance in a class so that the methods are meaningfull and logical according to the business domain your are dealing with. Also in some cases the same action listener can handle many buttons.

Example: assuming I am building a calculator. I know that the behavior of operators is similar when they are clicked on. And so is it with the digits buttons. Therefore I can have some classes, let's say

public class OperationActionListener {

    public void actionPerformed(ActionEvent e) {
        // Handle what happens when the user click on +, -, * and / buttons
    }
}


public class DigitActionListener {

    public void actionPerformed(ActionEvent e) {
        // Handle what happens when the user click on a digit button
    }
}

etc.

Now in my user interface I will add an instance of the same action listener

JButton buttonPlus = new JButton("+")
JButton buttonMinus = new JButton("-");
...

JButton buttonOne = new JButton("1");
JButton buttonTwo = new JButton("2"); 
...

OperationActionListener operationListener = new OperationActionListener();
DigitActionListener digitListener = new DigitsActionListener();

buttonPlus.addActionListener(operationListener);
buttonMinus.addActionListener(operationListener);
....

buttonOne.addActionListener(digitListener);
buttonTwo.addActionListener(digitListener);
....

Hope this helps.

Upvotes: 2

Related Questions