1

I have created a GUI calculator program, that performs calculations in a linear order, but i want it to perform calculations in an order of "Divide, multiply, add, subtract".

I'm a beginner, so please suggest me if there is any other simpler way to implement the same thing, which I have coded.
Please help me with the 'DMAS' thing.

My code:

public class keypadGUI extends JFrame{
private JTextField lcd;
private JButton n1,n2,n3,n4,n5,n6,n7,n8,n9,n0;
private JButton plus,minus,multiply,divide,equalTo,dot;
//private JButton[] buttons = new JButton[10];
//private JButton[] opButtons = new JButton[6];
private double ans = 0;                     //For storing final ans
char[] op;                              //Character array for stroing operators
private double[] nums;                      //For storing the numbers
public JPanel keypad;
private StringBuilder sb = new StringBuilder();         //For storing the input of the user as string

public keypadGUI(){
    setLayout(new BorderLayout(10,10));
    lcd = new JTextField();
    lcd.setEditable(false);

    Border low = BorderFactory.createLoweredSoftBevelBorder();
    lcd.setBorder(low);
    lcd.setHorizontalAlignment(JTextField.RIGHT);
    lcd.setFont(new Font("Serif",Font.BOLD,30));
    lcd.setText("0");

    Font numFont = new Font("Serif",Font.BOLD,20);


    n1 = new JButton("1");  n2 = new JButton("2");  n3 = new JButton("3");  n4 = new JButton("4");
    n5 = new JButton("5");  n6 = new JButton("6");  n7 = new JButton("7");  n8 = new JButton("8");
    n9 = new JButton("9");  n0 = new JButton("0");  dot = new JButton(".");
    plus = new JButton("+");
    minus = new JButton("-");
    multiply = new JButton("*");
    divide = new JButton("/");
    equalTo = new JButton("=");
    n1.setFont(numFont);    n2.setFont(numFont);    n3.setFont(numFont);    n4.setFont(numFont);
    n5.setFont(numFont);    n6.setFont(numFont);    n7.setFont(numFont);    n8.setFont(numFont);
    n9.setFont(numFont);    n0.setFont(numFont);    dot.setFont(numFont);   plus.setFont(numFont);
    minus.setFont(numFont); multiply.setFont(numFont);  divide.setFont(numFont);    equalTo.setFont(numFont);

    plus.setForeground(Color.DARK_GRAY);        minus.setForeground(Color.DARK_GRAY);   multiply.setForeground(Color.DARK_GRAY);
    divide.setForeground(Color.DARK_GRAY);      equalTo.setForeground(Color.DARK_GRAY);

    listen listener = new listen();
    n1.addActionListener(listener); n2.addActionListener(listener); n3.addActionListener(listener); n4.addActionListener(listener);
    n5.addActionListener(listener); n6.addActionListener(listener); n7.addActionListener(listener); n8.addActionListener(listener);
    n9.addActionListener(listener); n0.addActionListener(listener); plus.addActionListener(listener);   minus.addActionListener(listener);
    multiply.addActionListener(listener);   divide.addActionListener(listener);
    equalTo.addActionListener(new equalListener());

    keypad = new JPanel(new GridLayout(4,4,10,10));
    keypad.add(n7); keypad.add(n8); keypad.add(n9); keypad.add(divide);
    keypad.add(n4); keypad.add(n5); keypad.add(n6); keypad.add(multiply);
    keypad.add(n1); keypad.add(n2); keypad.add(n3); keypad.add(plus);
    keypad.add(n0); keypad.add(dot);    keypad.add(equalTo);    keypad.add(minus);

    add(lcd,BorderLayout.NORTH);
    add(keypad,BorderLayout.CENTER);
    setVisible(true);
    setLookAndFeel();
    setSize(280,280);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("MY Calc");


}


private void setLookAndFeel(){
    try{
        for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    }catch(Exception ae){}
}

private class listen implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e){
            String bName = ((JButton)e.getSource()).getText();
            sb.append(bName);
            lcd.setText(sb.toString());
    }
}

private class equalListener implements ActionListener{
    public void actionPerformed(ActionEvent e){
        String[] tokkens = sb.toString().split("-|\\+|\\*|\\/");
        nums = new double[tokkens.length];
        for(int i=0;i<nums.length;i++){
            nums[i] = Double.parseDouble(tokkens[i]);
        }
        op = new char[10];
        op[0]='+';
        int c =1;
        for(int i=0;i<sb.length();i++){
            if(sb.charAt(i)=='+' || sb.charAt(i)=='-' || sb.charAt(i)=='*' || sb.charAt(i)=='/')
            {    op[c]=sb.charAt(i); c++; }
        }
        performOP();
        sb = sb.delete(0, sb.length());
        sb.append(ans);
        lcd.setText(sb.toString());


        System.out.println(op);
        System.out.println(Arrays.toString(tokkens));
    }
}

private void performOP(){
    for(int i=0;i<nums.length;i++){
        switch(op[i]){
            case '+':
                ans = ans + nums[i];
            break;
            case '-':
                ans = ans - nums[i];
            break;
            case '*':
                ans = ans * nums[i];
            break;
            case '/':
                ans = ans / nums[i];
            break;
            default:
            System.out.println("INVALID CASE !!!");
        }
    }
}
}
Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
Jaydeep Solanki
  • 2,895
  • 5
  • 36
  • 50
  • Nope, I'm just practicing, upto now i had created a calculator that performed only two number operations, so now I thought to create a gui calc which can perform more than one operations at a time – Jaydeep Solanki Dec 28 '11 at 06:58
  • @Jaydeep The easiest way to do this i think is just to convert it to something like postfix notation. – Matt Dec 28 '11 at 07:02
  • For the hardest part, you may want to refer to this question: http://stackoverflow.com/questions/28256/equation-expression-parser-with-precedence – prusswan Dec 28 '11 at 07:02
  • 1+2*3-1 should be (1+2) * (3-1) or 1 + (2*3) -1 ? [the first one could be easily achieved using recursion] – amit Dec 28 '11 at 07:10
  • @amit for 1+2*3-1, it should be 1+(2*3)-1, because we want to perform multiplication before addition or subtraction. – Jaydeep Solanki Dec 28 '11 at 07:14
  • then I believe you are going to need some context free parser for this, such as [bison](http://www.gnu.org/software/bison/) – amit Dec 28 '11 at 07:16

2 Answers2

1

You currently have a linear approach to understanding the expression, you build a list of operators and execute them in order.

You need to build something more like a tree so that you can give your desired meaning to

3 + 4 * 5

and you probably want to allow parentheses too

2 + ( 3 * 4) + ( 5 * ( 6 + 7 ) )

This is a very common parsing problem, generally known as recursive descent parsing. You will be able to find libraries that implement such parsers. For example ANTLR. It's quite a big jump from where you are to this sort of stuff. If you dig around you'll probably find simple implementations you can clone, but if you really want to understand the area then you'd need to study quite a bit: articles such as this may help.

djna
  • 54,992
  • 14
  • 74
  • 117
0

Umm , how about if you just store all the characters that you take as operands and operators in a linked list. Store all the operators in an array, according to their precedence. Such as, arr[]={'/','*','+','-'}, iterate through these operators. While you are doing that detect any of the operation that needs to be applied first , store its answer in a new node, then delete those nodes containing the detected operations and operands.Link the new node to the node after the last operand upon which operation was being performed upon. You can repeat this process, until the base or head node's next pointer becomes zero.And yeah honestly, iam also kind of a beginner to this matter,so this solution is obviously not great. I also kind of thought this just right now and ofcourse havenot implemented this idea myself. But yeah , you can give it a shot, if you want to though.Hope it helps, even if just a bit.

Faiq arif
  • 21
  • 4