0

This is probably the nth time you've received a newbie question regarding calculators, but I just can't figure it out, been working on it for two to three days. The way I have built my calculator at the moment does not suffice and I know I have to start calculating at the time I press the '=' button, but I simply can't figure out how to do so. Due to this reason I have reverted back to my original calculator code, in which it calculates when I press an operation button (like '+') which didn't work, but I was hoping that that would allow me to properly build on it. Here's the code:

package rekenmachine;

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

public class Rekenmachine extends JFrame
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setSize(300,500);
        frame.setLocation(800,400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Rekenmachine");
        RekenPaneel rekenpaneel = new RekenPaneel();
        frame.setContentPane(rekenpaneel);
        frame.setVisible(true);
    }

    private static int getal, totaalGetal;
    private boolean optellen, aftrekken, vermenigvuldigen, delen;

     public int Optellen(int getal)
    {
        reset();
        optellen = true;
        totaalGetal += getal;
        getal = 0;
        return totaalGetal;
    }
    public int Aftrekken(int getal)
    {
        reset();
        aftrekken = true;
        totaalGetal -= getal;
        getal = 0;
        return totaalGetal;
    }
    public int Delen(int getal)
    {
        reset();
        delen = true;
        totaalGetal /= getal;
        getal = 0;
        return totaalGetal;
    }
    public int Vermenigvuldigen(int getal)
    {
        reset();
        vermenigvuldigen = true;
        totaalGetal *= getal;
        getal = 0;
        return totaalGetal;
    }
    public int getGetal()
    {
        return getal;
    }
    public int getTotaalGetal()
    {
        return totaalGetal;
    }
    public void reset()
    {
        optellen = false;
        aftrekken = false;
        delen = false;
        vermenigvuldigen = false;

        getal = 0;
        totaalGetal = 0;
    }
}

class RekenPaneel extends JPanel
{
    JButton knop0, knop1, knop2, knop3, knop4, knop5, knop6, knop7, knop8, knop9,
            knopOptel, knopAftrek, knopVermenigvuldigen, knopDelen, knopUitkomst,
            knopWissen;
    JTextField invoerVak;
    JPanel textPaneel, knopPaneel, logoPaneel;
    Rekenmachine rekenmachine;

    public RekenPaneel()
    {
        rekenmachine = new Rekenmachine();

        setLayout(new BorderLayout());

        textPaneel = new JPanel();
        knopPaneel = new JPanel();
        logoPaneel = new JPanel();

        textPaneel.setLayout(new FlowLayout());
        knopPaneel.setLayout(new GridLayout(4,4));
        logoPaneel.setLayout(new FlowLayout());

        Border rand = BorderFactory.createEmptyBorder(10, 10, 10, 10);

        knop0 = new JButton("0");
        knop0.addActionListener(new knop0Handler());

        knop1 = new JButton("1");
        knop1.addActionListener(new knop1Handler());

        knop2 = new JButton("2");
        knop2.addActionListener(new knop2Handler());

        knop3 = new JButton("3");
        knop3.addActionListener(new knop3Handler());

        knop4 = new JButton("4");
        knop4.addActionListener(new knop4Handler());

        knop5 = new JButton("5");
        knop5.addActionListener(new knop5Handler());

        knop6 = new JButton("6");
        knop6.addActionListener(new knop6Handler());

        knop7 = new JButton("7");
        knop7.addActionListener(new knop7Handler());

        knop8 = new JButton("8");
        knop8.addActionListener(new knop8Handler());

        knop9 = new JButton("9");
        knop9.addActionListener(new knop9Handler());

        knopOptel = new JButton("+");
        knopOptel.addActionListener(new knopOptelHandler());

        knopAftrek = new JButton("-");
        knopAftrek.addActionListener(new knopAftrekHandler());

        knopVermenigvuldigen = new JButton("*");
        knopVermenigvuldigen.addActionListener(new knopVermenigvuldigenHandler());

        knopDelen = new JButton("/");
        knopDelen.addActionListener(new knopDelenHandler());

        knopUitkomst = new JButton("=");
        knopUitkomst.addActionListener(new knopUitkomstHandler());

        knopWissen = new JButton("C");
        knopWissen.addActionListener(new knopWissenHandler());

        invoerVak = new JTextField(25);
        invoerVak.setHorizontalAlignment(invoerVak.RIGHT);
        invoerVak.setEditable(false);
        invoerVak.setBackground(Color.WHITE);

        textPaneel.add(invoerVak);
        knopPaneel.add(knop7);
        knopPaneel.add(knop8);
        knopPaneel.add(knop9);
        knopPaneel.add(knopDelen);
        knopPaneel.add(knop4);
        knopPaneel.add(knop5);
        knopPaneel.add(knop6);
        knopPaneel.add(knopVermenigvuldigen);
        knopPaneel.add(knop1);
        knopPaneel.add(knop2);
        knopPaneel.add(knop3);
        knopPaneel.add(knopOptel);
        knopPaneel.add(knop0);
        knopPaneel.add(knopWissen);
        knopPaneel.add(knopUitkomst);
        knopPaneel.add(knopAftrek);

        add(textPaneel, BorderLayout.NORTH);
        add(knopPaneel, BorderLayout.CENTER);
        add(logoPaneel, BorderLayout.SOUTH);
    }
    class knop0Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "0");
        }
    }
    class knop1Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "1");
        }
    }
    class knop2Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "2");
        }
    }
    class knop3Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "3");
        }
    }
    class knop4Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "4");
        }
    }
    class knop5Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "5");
        }
    }
    class knop6Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "6");
        }
    }
    class knop7Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "7");
        }
    }
    class knop8Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "8");
        }
    }
    class knop9Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "9");
        }
    }
    class knopOptelHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            String invoer = invoerVak.getText();
            int invoerGetal = Integer.parseInt(invoer);
            rekenmachine.Optellen(invoerGetal);
            invoerVak.setText("");

        }
    }
    class knopAftrekHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            String invoer = invoerVak.getText();
            int invoerGetal = Integer.parseInt(invoer);
            rekenmachine.Aftrekken(invoerGetal);
            invoerVak.setText("");
        }
    }
    class knopVermenigvuldigenHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            String invoer = invoerVak.getText();
            int invoerGetal = Integer.parseInt(invoer);
            rekenmachine.Vermenigvuldigen(invoerGetal);
            invoerVak.setText("");
        }
    }
    class knopDelenHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            String invoer = invoerVak.getText();
            int invoerGetal = Integer.parseInt(invoer);
            rekenmachine.Delen(invoerGetal);
            invoerVak.setText("");
        }
    }
    class knopUitkomstHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText("" + rekenmachine.getTotaalGetal());
            rekenmachine.reset();
        }
    }
    class knopWissenHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            rekenmachine.reset();
            invoerVak.setText("");
        }
    }
}

What it basically does is look like a calculator, all buttons work, yet the way it calculates is way off, if at all. I think what I need to do is save a number, when I press + it should add the next number, if I press - it should substract the next number, if I press * it should multiply by the next number and if I press / it should divide by the next number, then when I press = it should show the result, yet I have no idea how to do that.

Should it be done with an arraylist? If so, how could I properly save the result? I mean, using it with two numbers isn't that hard, you just save two numbers and do something with them, then show the result, but a person doesn't always use just two numbers.

To explain the problem I'm having more clearly: for example, when I enter '50' and then press '+' it SHOULD convert "50" to getal = 50 and start the Optellen method, then totaalGetal should become 50, it then empties the textfield. If I then add '3', it should say 53 when I press '=' yet it still shows 50 if I'm lucky. To solve that I assume I have to make the calculation WHEN I press '=' but I don't know how to save/calculate numbers before having done that.

Can anybody tell me what to do before I've lost all my hair? :P

tommybee
  • 2,409
  • 1
  • 20
  • 23
Wesley Orth
  • 43
  • 1
  • 2
  • 8
  • 1
    It is good practice to code in english :p Especially for cases like this when you need help, not everyone speaks deutch ^^ "yet the way it calculates is way off" What does that mean? – Turtle Aug 30 '17 at 10:01
  • I have to code in Dutch because of certain reasons I'm afraid. Well, it means that it won't ever do what I want. As explained in the last paragraph, it should, for example, get 53 with 50 + 3, right? Yet it remains at 50 or at 0 because I get the feeling it calculates at the wrong place(s) and as such won't do anything or won't do it properly. getal = number totaalGetal = totalNumber knop = button optellen = add aftrekken = subtract vermenigvuldigen = multiply delen = ehm... / < that uitkomst = result wissen = erase Basically those are the translations. – Wesley Orth Aug 30 '17 at 10:03
  • You have a problem with your `reset()` calls. You're setting `getal` and `totaalGetal` to 0 at weird times. – Turtle Aug 30 '17 at 10:08
  • Oh crap! Well, I forgot to edit that back, it used to only reset the booleans. Same stuff though basically, it didn't add properly and subtracting changed the number into a negative number, multiplication and dividing (that's the word I was looking for earlier) didn't even work I believe. reset() used to be in the correct places at first. In other words, reset() didn't cause the problem earlier. I knew I forgot to edit something back xD – Wesley Orth Aug 30 '17 at 10:10
  • Split the reset() into two methods, seperating the 'change variable to 0' and the 'reset all booleans' parts. – Wesley Orth Aug 30 '17 at 10:13
  • See also this [calculator example](http://stackoverflow.com/a/7441804/418556). It uses `ScriptEngine` to evaluate the expression in the text field. – Andrew Thompson Aug 30 '17 at 13:40
  • I'll be sure to check it out once I've got some proper free time on my hands. Thanks! – Wesley Orth Aug 30 '17 at 14:03

3 Answers3

1

When developing something, you have to think first how you want to solve a problem. Work from there by designing a solution. If you have a programmable solution, implement it. The UI may come later. That's a core skill that a developer should have.

1) You want to have a calculator that support +, -, / and *. The output should be shown if "=" is clicked.

2) Think with classes. That concept may be new for you, but you will discover later from. Your main class that does the calculations is Rekenmachine. (From a design perspective, it should be a stand alone class, but that's not important now). You need to separate it from your UI layer.

Your class supports the actions that you have implemented with the UI. That's good. But I also see things that shouldn't be there

public int Vermenigvuldigen(int getal)
{
    reset(); // reset the calculator ?
    vermenigvuldigen = true; // purpose ?
    totaalGetal *= getal;
    getal = 0; // resetting argument getal ?
    return totaalGetal;
}

Here, I'm not sure why you're calling reset() because what it does is

public void reset()
{
    optellen = false;
    aftrekken = false;
    delen = false;
    vermenigvuldigen = false;

    getal = 0;
    totaalGetal = 0;
}

When reading the above method, you see that it resets the value that you tried to add on. Of course your calculation would go wrong because you're erasing previous data... resetting everything back to initial state. I also don't understand the setting to "true" or "false" on the actions. Perhaps for the UI? That is not required.

Make it simple:

When creating Rekenmachine, set the variable totaalGetal to 0 as default. That variable holds the value of your calculations performed so far. That's the start. When you have an addition, use

public void add(int getal) {
  totaalGetal+= getal; // means totaalGetal = totaalGetal + getal.
}

Before calling add() you have to parse the string to an integer. This can be done in the button action:

class knop1Handler implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        // get input
        String input = invoerVak.getText();
        // convert
        int converted = convertToInt(input);
        // instruct myRekenmachine to add the value
        myRekenmachine.add(converted);
    }
}

Important note ... use concise naming ... "knop1handler" is difficult to read. Use "addButtonHandler" to indicate that this class handles the add button. convertToInt is a method that reads in a String and returns with an integer. You have to implement that yourself. myRekenmachine is an instance of your Rekenmachine class.

This above is for addition. Implement the same for other operands. If you want to adjust the UI, do that in the handler.

Now, when you press =, just return the totaalGetal value.

PS: Not sure, but ask if you are allowed to write names in English. My native language is Dutch, but during my CS courses, I am allowed to program completely in English. Please try to ask it because English is the main language in IT world if you're aiming for a career in IT.

Turtle
  • 1,626
  • 16
  • 26
KarelG
  • 5,176
  • 4
  • 33
  • 49
  • Thanks for the answer, but unless I'm doing something INCREDIBLY wrong, it's practically no different than what I did if you don't count all the fluff around it. I actually started that way, but that's when the errors began to appear also... Except for convertToInt, that appears to not be recognised for some strange reason, Alt + Enter shows nothing viable. I use Netbeans. – Wesley Orth Aug 30 '17 at 10:32
  • " _convertToInt is a method that reads in a String and returns with an integer. **You have to implement that yourself**._ " ( just `Integer.parseInt` with exception handling...) But ... just realized that it's better to work with a `double` (to support decimals and a proper usage of `/`). keh. – KarelG Aug 30 '17 at 10:33
  • **'it is clearly visible that you're new in programming. When developing something, you have to think first how you want to solve a problem. Work from there by designing a solution. If you have a programmable solution, implement it.'** How do you mean that exactly? Could you tell me more about that core developer skill, please? – Wesley Orth Aug 30 '17 at 10:44
1

When you click on the +, you're calling this:

    knopOptel.addActionListener((ActionEvent e) ->
    {
        String invoer = invoerVak.getText();
        int invoerGetal = Integer.parseInt(invoer);
        rekenmachine.addition(invoerGetal);
        invoerVak.setText("");
    });

But when you click on +, you're not doing the calculation yet! What you should be doing is:

  • The user type a number
  • The user click on + (for example)
  • In your ActionListener, you read the number on the screen, you store it in getal, you clear the screen, and you set your boolean optel to true
  • The user types another number
  • The user click on equal
  • In your equal Listener, you read the number you read the number on the screen, and depending on the flag (optel in the example), you calculate the result
  • you display the result

So indeed, the calculation is done when you press equal.

A small code example:

knopOptel.addActionListener((ActionEvent e) ->
{
    int invoerGetal = Integer.parseInt(invoerVak.getText()); // get the number
    calculate(invoerGetal); //sets totalNumber to what it should be by looking at the flags
    invoerVak.setText(totalNumber); // we write the temporary result
    additionFlag = true; // next number must be added
});

And your calculate function should just be something like:

private void calculate(int aInvoerGetal) {
    if (addition)
        totalNumber += aInvoerGetal;
    else if (substract)
        totalNumber -= aInvoerGetal;
    else if (divide)
        totalNumber /= aInvoerGetal;
    else if (multiply)
        totalNumber *= aInvoerGetal;

    resetFlags();
}

TO GO FURTHER:

Now, if you want to support multiple caculations (5+5+5+3), it's easy. When you click on +, -, *, /, you first call the equalActionListener.

This way, you get this kind of sequence:

  1. 5, + // ==> equal called ==> 5 (because the flags are all false) ==> flag + to true

  2. 10, + // ==> equal called ==> 15 because 5 in memory and + flag was on. + flag goes off, then on again (because you pressed + again)

  3. 4, = // ==> equal called ==> 19

Turtle
  • 1,626
  • 16
  • 26
  • This... makes a heap of sense! When I have time to program again (tomorrow probably) I'll be sure to incorporate what you said into my code and analyze it over and over again until I fully understand. It did already give me a 'eureka' moment though, haha. Thanks a lot! – Wesley Orth Aug 30 '17 at 14:01
  • @WesleyOrth No problem, glad I could help. Don't hesitate if you want me to add more precisions on this. If you consider that answered your question, you can mark it as accepted :D – Turtle Aug 30 '17 at 14:02
  • How do I call the equalActionListener from + or the other ones? Also, since I'm new to the whole 'think in classes' mindset, I'm pretty confused right now... That's the thing, I get it, but I have no idea HOW to do it... Could you help me, please? – Wesley Orth Sep 03 '17 at 13:21
  • Well, you don't have to make it an `actionListener` actually. Make it a global function, and call it at the start of your `plusListener`. – Turtle Sep 03 '17 at 17:02
  • @WesleyOrth The thing is, remember your calculations should be done **before** processing to the next one. So: `5 + 5` -> `5 + (= 5) 5 + (= 10) 5 = 15` – Turtle Sep 03 '17 at 17:04
  • I see. Thank you :) I'll see if I get it this time, hahaha. – Wesley Orth Sep 03 '17 at 21:15
-2

Wesley, did you think about what you wanted the calculator to do before you started coding? e.g. would it support brackets, sin/cos, memory. Did you think about how logically these functions would work and then think of how they could be implemented in Java? A few flow charts and some pesudocode can go a long way when you're starting out in a new language if only to help you comprehend what it is you are trying to do.

BTW I know it's tempting to start with the GUI code and move into the logic of the application but it is usually better to start with the logic and then move onto the GUI. You can hard code the values for inputs and see if the functionaly behaves as expected and then introduce parameters with values passed in from else where.

EDIT

I think I know why your + key is not working. The reset() method is setting getal and totalGetal to 0 before adding them. 0 + 0 is 0.

knopOptel = new JButton("+");
        knopOptel.addActionListener(new knopOptelHandler()); 


 class knopOptelHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            String invoer = invoerVak.getText();
            int invoerGetal = Integer.parseInt(invoer);
            rekenmachine.Optellen(invoerGetal);
            invoerVak.setText("");

        }
    }


     public int Optellen(int getal)
    {
        reset();

            public void reset()
            {
            optellen = false;
            aftrekken = false;
            delen = false;
            vermenigvuldigen = false;

            getal = 0;
            totaalGetal = 0;
            }

    optellen = true;
    totaalGetal += getal;
    getal = 0;
    return totaalGetal;
}
  • Hmm... yes I made one of those UML charts. However, when the code did not do what I wanted it to do, I started editing it, somewhere along the way it **might** have become a bit of a small mess haha...ha. – Wesley Orth Aug 30 '17 at 11:27
  • @user8537453 While your answer address some of the issues of the question, it doesn't answer it, it would be better as a comment :) – Turtle Aug 30 '17 at 15:13
  • My reputation is at 2 and it needs to be at least 50 before I can add a comment. I am a little reluctant to hand the code over on something that is obviously homework or part of a self taught course. Wesley would be better served by working on a solution and coming back with any new problems they encounter. – user8537453 Aug 30 '17 at 15:25
  • Thanks for the feedback though. – user8537453 Aug 30 '17 at 15:31
  • I agree, I wouldn't want the answer presented to me, just a new perspective or a course to take so to speak. – Wesley Orth Sep 03 '17 at 11:41