2
\$\begingroup\$

How should I incorporate a JButton array, and how do I get rid of the multitude of action listeners? I would also like to modify it so that you can do more than one operation on numbers with multiple digits.

/*
 * A one operation calculator.
 * Only handles single digits for basic arithmetic.
 * Trig operations accept values in degrees.
 * 
 * I'll make a real calculator later.
 */

public class BasicCalculator extends JFrame {

    private JPanel panel;                   
    private JTextField input;   
    private JButton butt0, butt1, butt2, butt3,
                    butt4, butt5, butt6, butt7,
                    butt8, butt9, buttSine, buttCosine,
                    buttEquals, buttClear, buttAdd,
                    buttSubtract, buttMultiply, buttDivide,
                    buttTangent;
    private final int WINDOW_WIDTH = 360;   
    private final int WINDOW_HEIGHT = 300;

/*
 * Constructor calls the superclass's constructor and creates the window.
 */
    public BasicCalculator() {

        super("Calculate a Simple Expression");

        setSize(WINDOW_WIDTH, WINDOW_HEIGHT);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        buildPanel();

        add(panel);

        setVisible(true);

    }

/*
 * Method to put the input box and all the buttons onto the window.
 * 
 * I know, I know, I should've used an array for the buttons.
 */
    private void buildPanel() {

        input = new JTextField(16);

        buttEquals = new JButton("=");
        buttEquals.addActionListener(new Listener1());
        buttClear = new JButton("AC");
        buttClear.addActionListener(new Listener2());
        buttAdd = new JButton("+");
        buttAdd.addActionListener(new Listener3());
        buttSubtract = new JButton("-");
        buttSubtract.addActionListener(new Listener4());
        buttMultiply = new JButton("x");
        buttMultiply.addActionListener(new Listener5());
        buttDivide = new JButton("÷");
        buttDivide.addActionListener(new Listener6());
        butt0 = new JButton("0");
        butt0.addActionListener(new Listener7());
        butt1 = new JButton("1");
        butt1.addActionListener(new Listener8());
        butt2 = new JButton("2");
        butt2.addActionListener(new Listener9());
        butt3 = new JButton("3");
        butt3.addActionListener(new Listener10());
        butt4 = new JButton("4");
        butt4.addActionListener(new Listener11());
        butt5 = new JButton("5");
        butt5.addActionListener(new Listener12());
        butt6 = new JButton("6");
        butt6.addActionListener(new Listener13());
        butt7 = new JButton("7");
        butt7.addActionListener(new Listener14());
        butt8 = new JButton("8");
        butt8.addActionListener(new Listener15());
        butt9 = new JButton("9");
        butt9.addActionListener(new Listener16());
        buttSine = new JButton("sin");
        buttSine.addActionListener(new Listener17());
        buttCosine = new JButton("cos");
        buttCosine.addActionListener(new Listener18());
        buttTangent = new JButton("tan");
        buttTangent.addActionListener(new Listener19());

        panel = new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 30));

        panel.add(input);

        panel.add(buttEquals);
        panel.add(buttClear);
        panel.add(buttAdd);
        panel.add(buttSubtract);
        panel.add(buttMultiply);
        panel.add(buttDivide);
        panel.add(butt0);
        panel.add(butt1);
        panel.add(butt2);
        panel.add(butt3);
        panel.add(butt4);
        panel.add(butt5);
        panel.add(butt6);
        panel.add(butt7);
        panel.add(butt8);
        panel.add(butt9);
        panel.add(buttSine);
        panel.add(buttCosine);
        panel.add(buttTangent);

    }

/*
 * Action listener for the "equals" button.
 * All the calculations are done here.
 */
    private class Listener1 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            String str = input.getText();

            double num1, num2, radians, result;

            if (str.charAt(0) == 's' || str.charAt(0) == 'c' || str.charAt(0) == 't') 
            {
                radians = Math.toRadians(Double.parseDouble(str.substring(3)));

                switch (str.charAt(0)) {

                    case 's':
                        result = Math.sin(radians);
                        break;
                    case 'c':
                        result = Math.cos(radians);
                        break;
                    case 't':
                        result = Math.tan(radians);
                        break;
                    default:
                        result = 0; 
                }
            }   
            else 
            {
                num1 = Double.parseDouble(str.substring(0, 1));
                num2 = Double.parseDouble(str.substring(4, 5));

                switch (str.charAt(2)) {

                    case '+':
                        result = num1 + num2;
                        break;
                    case '-':
                        result = num1 - num2;
                        break;
                    case 'x':
                        result = num1 * num2;
                        break;
                    case '÷':
                        result = num1 / num2;
                        break;
                    default:
                        result = 0;
                }
            }

            input.setText(Double.toString(result)); 
            JOptionPane.showMessageDialog(null, str + " = " + result);

        }
    }

/*
 * The rest of the action listeners print the button text to the text field.
 */
    private class Listener2 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText("");
        }
    }
    private class Listener3 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + " + ");
        }
    }
    private class Listener4 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + " - ");
        }
    }
    private class Listener5 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + " x ");
        }
    }
    private class Listener6 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + " ÷ ");
        }
    }
    private class Listener7 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "0");
        }
    }
    private class Listener8 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "1");
        }
    }
    private class Listener9 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "2");
        }
    }
    private class Listener10 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "3");
        }
    }   
    private class Listener11 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "4");
        }
    }

    private class Listener12 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "5");
        }
    }
    private class Listener13 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "6");
        }
    }
    private class Listener14 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "7");
        }
    }
    private class Listener15 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "8");
        }
    }
    private class Listener16 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "9");
        }
    }
    private class Listener17 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "sin");
        }
    }
    private class Listener18 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "cos");
        }
    }
    private class Listener19 implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            input.setText(input.getText() + "tan");
        }
    }

/*
 * main method
 */
    public static void main(String[] args) {

        new BasicCalculator();
    }


}
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

You don't need to have implementations consisting of just single line. For example, you can replace the Listener2 direclty with a lambda as :

buttClear = new JButton("AC");
buttClear.addActionListener(event ->  input.setText(""));

Same goes will all one liner Listeners in your code.

There's also a bug in your code because of the way you are extracting numbers from the input field.
If you perform 4/3, you will get the result as 1.3333333, and if you continue doing more operations like 1.333333*3, your calculator returns the result as 0.0.

\$\endgroup\$
1
\$\begingroup\$

This is the power of classes: they encapsulate a common concept, so that you write them once, and reuse them multiple times. (And all in all this is the main act of programming: spot common patterns and derieve generalizations from these patterns.)

So, you have multiple classes along the lines of:

private class Listener17 implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        input.setText(input.getText() + "sin");
    }
}
private class Listener18 implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        input.setText(input.getText() + "cos");
    }
}   

... which differ only in the text you append. Thus, make ONE class of these, and pass the text to append as a parameter:

private class AppendingTextListener implements ActionListener {
    private final String textToAppend;

    AppendingTextListener(String textToAppend) {
        this.textToAppend = textToAppend;
    }

    public void actionPerformed(ActionEvent e) {
        input.setText(input.getText() + textToAppend);
    }
}

and then:

butt0.addActionListener(new AppendingTextListener("0"));
butt1.addActionListener(new AppendingTextListener("1"));
...
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.