-2

So I have a calculator app. built and it works correctly however if the user inputs for example 4+√ I get an error (shown below). I was told I need to find if the user has entered in an operation already when they hit the √ button and if they have then just don't do anything. I'm really new to Java though and I'm not sure how to do that.

Here is the action listener where all the calculations are done (I believe the code needs to go under where you see if (a.getSource() == textSqrt)):

    public class event implements ActionListener {

    public void actionPerformed(ActionEvent a) {
        String text = a.getActionCommand();


        if (text.equals("1")) {
            result.setText(result.getText() + "1");
        } else if (text.equals("2")) {
            result.setText(result.getText() + "2");
        } else if (text.equals("3")) {
            result.setText(result.getText() + "3");
        } else if (text.equals("4")) {
            result.setText(result.getText() + "4");
        } else if (text.equals("5")) {
            result.setText(result.getText() + "5");
        } else if (text.equals("6")) {
            result.setText(result.getText() + "6");
        } else if (text.equals("7")) {
            result.setText(result.getText() + "7");
        } else if (text.equals("8")) {
            result.setText(result.getText() + "8");
        } else if (text.equals("9")) {
            result.setText(result.getText() + "9");
        } else if (text.equals("0")) {
            result.setText(result.getText() + "0");
        } else if (result.getText().indexOf(".") < 1){
            result.setText(result.getText() + "."); 
        }


        String str = result.getText();
        textBox = Double.parseDouble(str);

        if (a.getSource()
                == textAdd) {
            op = 1;
            firstInput = textBox;
            result.setText("");
        }

        if (a.getSource()
                == textSubtract) {
            op = 2;
            firstInput = textBox;
            result.setText("");
        }

        if (a.getSource()
                == textMultiply) {
            op = 3;
            firstInput = textBox;
            result.setText("");
        }

        if (a.getSource()
                == textDivide) {
            op = 4;
            firstInput = textBox;
            result.setText("");
        }

        if (a.getSource()
                == textPercent) {
            op = 5;
            firstInput = textBox;
            result.setText("");
        }

        if (a.getSource() == textSqrt) {
            op = 6;
            firstInput = textBox;
            answer = Math.sqrt(textBox);
            str = Double.toString(answer);
            result.setText(str);
        }

        if (a.getSource()
                == textSign) {
            double neg;
            op = 7;
            neg = 0 - textBox;
            str = Double.toString(neg);
            result.setText(str);
        }

        if (a.getSource()
                == textEqual) {
            if (op == 1) {
                answer = firstInput + textBox;
                str = Double.toString(answer);
                result.setText(str);
            } else if (op == 2) {
                answer = firstInput - textBox;
                str = Double.toString(answer);
                result.setText(str);
            } else if (op == 3) {
                answer = firstInput * textBox;
                str = Double.toString(answer);
                result.setText(str);
            } else if (op == 4) {
                answer = firstInput / textBox;
                str = Double.toString(answer);
                result.setText(str);
            } else if (op == 5) {
                answer = firstInput % textBox;
                str = Double.toString(answer);
                result.setText(str);
            }

        }
    }
}

and here is the error I get when I press an operation and the square root button

Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "."
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
    at java.lang.Double.parseDouble(Double.java:540)
    at inlab05.InLab05$event.actionPerformed(InLab05.java:215)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6505)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6270)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:708)
    at java.awt.EventQueue$4.run(EventQueue.java:706)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

Sorry for such a long post. Hopefully someone can help me :)

Mark Shimala
  • 65
  • 10
  • Do you have an off-by-one error in this part: "result.getText().indexOf(".") < 1" For example, what if the input *starts* with '.'? The indexOf would return '0' but still exist in the string. You may want result.getText().contains(".") – drobert Oct 23 '13 at 18:45
  • >if (text.equals("1")) { result.setText(result.getText() + "1"); } else if (text.equals("2")) { result.setText(result.getText() + "2"); } else if (text.equals("3")) My eyes... make me unsee it – Display Name Oct 23 '13 at 18:45
  • @drobert the point of that code is to make it so the user cannot enter more than one decimal point. Would I still want to make it .contains(".")? – Mark Shimala Oct 23 '13 at 18:49
  • @SargeBorsch Yeah I know it's not really how it should be but that's how we're learning it right now. Should I use switch statements instead? – Mark Shimala Oct 23 '13 at 18:49
  • You should start with simpler problems to solve. And always get rid of code duplication. @MarkShimala – Display Name Oct 23 '13 at 18:50
  • For detecting digits, use Character.isDigit(...) (if i remember name right) @MarkShimala – Display Name Oct 23 '13 at 18:51
  • One more suggestion: move your string manipulation code out of your ActionListener and into simpler objects/functions so you can write unit tests. The ability to test simple inputs and outputs without bootstrapping a GUI will help you solve your text processing problems. – drobert Oct 23 '13 at 20:43

2 Answers2

1

Checking for the presence of "." byindexOf('.') < 1 is erroneous.

If '.' doesn't exist at all it would return -1, but if it exists in the first character, it will return 0, both of which are < 1 but mean completely different things.

Azad
  • 5,047
  • 20
  • 38
drobert
  • 1,230
  • 8
  • 21
  • @Azad the purpose of that line of code is so that the user can not enter more than one decimal point. What would be a better way of doing that? – Mark Shimala Oct 23 '13 at 18:50
  • How would that prevent a user from entering more than one decimal point? Seems like it reads the value then, if it contains a decimal point in the first two characters or doesn't contain one it all adds one at the end. That can't be what you want. – drobert Oct 23 '13 at 20:45
0
java.lang.NumberFormatException: For input string: "."

A single period is not a valid number according to the parser.

Figure out why that input, which is obviously unexpected, is getting to the formatter.

Using == to compare Strings is a common mistake. Use the equals() method instead. (Make sure you understand why - search for the question in SO).

Bucket
  • 7,415
  • 9
  • 35
  • 45
duffymo
  • 305,152
  • 44
  • 369
  • 561