So my assignment is to design a simple GUI calculator using the stack data structure to perform additions, subtractions, multiplications and divisions. The calculator window should have at least two panels - one for display and the other for buttons (0 - 9, . , +, -, X, /, =, C). After an expression is entered, its postfix or prefix is displayed and then the result.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.util.Stack;

public class JCalculator implements ActionListener {
JFrame jfrm;
JFrame jfrm2;
JTextField txt;
JLabel results;
String str = "";
Stack operands = new Stack();
char[] a = new char[0];
int used = 0;



JCalculator(){
    jfrm = new JFrame("JCalc");
    jfrm.getContentPane().setLayout(new GridLayout(0,1));
    jfrm.setSize(210,210);

   results = new JLabel("",SwingConstants.RIGHT);
   jfrm.getContentPane().add(results);
   jfrm.setLocation(400,300);
   jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

   JButton[] calbut= new JButton[14];
   String []but = {"7","8","9","/","4","5","6","*","1","2","3","-","0","C"
   };
   JButton equal = new JButton("=");
   JButton add = new JButton("+");

   JPanel jbutton = new JPanel();
   jbutton.setLayout(new GridLayout(4,3));
   for(int i=0; i< but.length;i++){
       jbutton.add(calbut[i] = new JButton(but[i]));

       calbut[i].addActionListener(this);
   }
   jbutton.add(equal);
   jbutton.add(add);

   equal.addActionListener(this);
   add.addActionListener(this);

   jfrm.getContentPane().add(jbutton);


    jfrm.setVisible(true);
}
public void actionPerformed(ActionEvent ae){
    char[] a = new char[0];
    int used = 0;
    if(used == a.length){
        char[] newa= new char[a.length + 1];
        for(int i = 0; i <used; i++) newa[i]= a[i];
        a= newa;
    }

    if(ae.getActionCommand().equals("1")){
        str = results.getText();
        results.setText(str + "1");
        operands.push(1);
    }
    if(ae.getActionCommand().equals("2")){
        str = results.getText();
        results.setText(str + "2");
        operands.push(2);
    }
    if(ae.getActionCommand().equals("3")){
        str = results.getText();
        results.setText(str + "3");
        operands.push(3);
    }
    if(ae.getActionCommand().equals("4")){
        str = results.getText();
        results.setText(str + "4");
        operands.push(4);
    }
    if(ae.getActionCommand().equals("5")){
        str = results.getText();
        results.setText(str + "5");
        operands.push(5);
    }
    if(ae.getActionCommand().equals("6")){
        str = results.getText();
        results.setText(str + "6");
        operands.push(6);
    }
    if(ae.getActionCommand().equals("7")){
        str = results.getText();
        results.setText(str + "7");
        operands.push(7);
    }
    if(ae.getActionCommand().equals("8")){
        str = results.getText();
        results.setText(str + "8");
        operands.push(8);
    }
    if(ae.getActionCommand().equals("9")){
        str = results.getText();
        results.setText(str + "9");
        operands.push(9);
    }
    if (ae.getActionCommand().equals("0")) {
        str = results.getText();
        results.setText(str + "0");
        operands.push(0);
    }
    if(ae.getActionCommand().equals("+")){
        str = results.getText();
        double operand = Double.parseDouble(str);
        operands.push(operand);
        results.setText("");
        a[used]= '+';
        used++;

    }
    if(ae.getActionCommand().equals("-")){
        str = results.getText();
        double operand = Double.parseDouble(str);
        operands.push(operand);
        results.setText("");
        a[used]= '+';
        used++;
    }
    if(ae.getActionCommand().equals("/")){
        str = results.getText();
        double operand = Double.parseDouble(str);
        operands.push(operand);
        results.setText("");
        a[used]= '+';
        used++;
    }
    if(ae.getActionCommand().equals("*")){
        str = results.getText();
        double operand = Double.parseDouble(str);
        operands.push(operand);
        results.setText("");
        a[used]= '*';
        used++;
    }
    if(ae.getActionCommand().equals("=")){

        for(int i = 0; i< used; i++){
           performBinaryOp(a[i]);
        }

        str = String.valueOf(operands.pop());
        results.setText(str);
    }


}
 public void performBinaryOp(char nextOperation) {
     double leftOperand, rightOperand;
    Double result = new Double(0);
    rightOperand = (Double) operands.pop();
    leftOperand = (Double) operands.pop();
    switch (nextOperation) {
        case '+':
            result = new Double(leftOperand + rightOperand);
            break;
        case '-':
            result = new Double(leftOperand - rightOperand);
            break;
        case '*':
            result = new Double(leftOperand * rightOperand);
            break;
        case '/':
            result = new Double(leftOperand / rightOperand);
            break;
    }
    operands.push(result);
}

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

The error that I run into is when pressing the equals button, for example pressing 2+3= it return the first value 2.0 then I receive an error saying:

Exception in thread "AWT-EventQueue-0" java.util.EmptyStackException
at java.util.Stack.peek(Unknown Source)
at java.util.Stack.pop(Unknown Source)
at JCalculator.actionPerformed(JCalculator.java:152)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

I'm not really sure whats wrong with my code so if someone could point out the error for me and help me out that be greatly apprciated thanks in advance.

Recommended Answers

All 3 Replies

You are trying to pop from an empty stack at line 152. You need to debug the code to see why the stack is empty there.

okay thanks, i'll look into that

If you don't have an interactive debugger, add lots of println statements to show the values of all the variables the code uses. The Arrays class's toString() method is useful for formatting arrays for printing.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.