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();
}
}
2 Answers 2
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 Listener
s 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
.
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"));
...