Hi, I'm building a calc but I can't seem to connect the dots with the events, I'm trying to make 2+2=4 work but I don't know how to use the events to use if statemtns and if the = sign is pressed, how will the program know what mathematical function was pressed before?
mengano fulano wrote:So for example, I have this to filter the math in the calculator:
but how do can I filter when clicked the = button which is sum and which is multiplication?
Thank you, I figured it out, now I'm trying to make the program decide whether it's a plus sign or a * sign, how can I do that? Should I post the whole code? It's not that long ^^
No, don't write that sort of thing. It is non‑object‑oriented and it will lead you to write horrible long methods with lots of if‑elses in. Exactly like what you are doing yourself. Give each button its own listener, and write a method for that button:-Now, that is the old way to do it with anonymous classes, so you can see that your code rapidly becomes verbose if you have multiple buttons:-You can also see what inelegant names I have for my methods. Now, if you look at EventHandler, you find it is marked @FunctionalInterface public interface EventHandler<T extends Event> extends EventListener and the documentation says,
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
You can now shorten that code to a λ and get rid of lots of boilerplate. Read the Java™ Tutorials about λ expressions. The compiler “knows” what kind of object you are using because setOnAction is not overloaded, and you can even infer the type of the event if you look carefully at the signature of that method. So we can start to delete code: the name of the class can vanish, along with its associated {}.So far, so good. Now, because EventHandler only has one methdo, the compiler “knows” which method to call, so we can delete its name. It also “knows” from the generic type of the call, that evt must be a particular type, so the type of the parameter can vanish, too:-Now, you replace the {} with the arrow token pronouced “goes to” and you have three valid λs:-That code will compile and run, but you may if you wish remove the () around evt:-And that is the correct way to write listener calls. Now all the code which was in those horrible if‑elses can go inside its own method.
Arturo Fern wrote:. . . Thank you, I figured it out
I am afraid you have not been given good advice.
now I'm trying to make the program decide whether it's a plus sign or a * sign, how can I do that? . . .
You write a calculator class which does not have a GUI, and you use that to distinguish the operators. You will find it very difficult to write such code in a GUI class, and it is indeed the wrong place to have a calculation. You can now write:-
I agree with you that each button should have its own listener that is the best way to write code. But if you have an array of buttons such as a 2D array one representing a 2D map or list buy buttons at a store, that are much easier when created with a for loop that .getSource(); method is useful especially if you are extending the button class and retrieving additional info from button such as map coordinates in the case of a 2d map of buttons. . But for calculator each button should have it's own listener method.
Even if you have a large array of buttons, you don't need to use getSource(). You apply some sort of object to each of the buttons and you can retrieve that object later on or apply it to the method called as an argument. Look what you can do with calculator buttons:-Now you have to work out how incrementNumber changes 12345 to 123456 if you push the 6 key. Or changes 12345 to 12345. when you push the decimal point key.
I was aware of lambda exp. , I read it no long ago in the book even though it was not consolidated, I understand to put a handler to each bottom and also we could put 1 handler for all of them like I had it (btw in terms of efficiency would it be better 1 handler for all buttons or one for each?)
Look, this is what I previously had:
and with that code I can definitely use 1 math operator, but when I try to use 2, how do I tell the program when clicked = which button was pressed before the = sign so it can adapt and calculate properly?
Let's say I write:
In order to substitude the 1 handler above, how can I let the calc know when I click = which math operation to use? Btw is the word .isArmed() correct above? lol I just stared looking into the suggestions to see what I could use and that one seem good.
You don't want to worry about efficiency; who cares about a 0.5μs delay going through a method when it might take 0.5s to click the buttons? But separate handlers will run slightly faster, because there is no need to go through mutliple if statements.
You can see that your switch statement has repeated code in; lines 18 and 27 are very similar. I think you should go back to a separate Calculator class without a GUI, so you can run it like this:-Each increment call from those arrays corresponds to pushing a number button once.
Now you can consider a method like this:-Create a data structure operatorButtons (maybe a List<Button>) and disarm every button in it; when you click a number, you can arm some buttons again. Which buttons are armed will vary from time to time as you go through the calculations.
Digression: read about enumerated types in the Java® Language Specification (=LJS). When you have read it, you might find something useful for writer of calculators.
Arturo Fern wrote:. . . I was aware of lambda exp.
Please look at the link I gave about λs in the first post I posted here.
. . . how can I let the calc know when I click = which math operation to use?
I think I answered that with setPlus().
Btw is the word .isArmed() correct above? . . .
Don't know. Have a look in the Button documentation and see whether you can find isArmed anywhere. If you do, that should give you all the information you require. If you can't understand it, ask again.
Hi Campbell, sorry but I'm not understanding it, I know I have to study more enhanced loops, I'm still in the old loop. Right now I'm doing my bachellor, this semester I'll take Data Structures, I'm mentioning it because you said it somewhere, I don't know if it has to do with that. And this is my first GUI programming, I don't know swing or the others.
I'm trying to understand that loop, but what exactly does myCalculator mean? Is that the name of the project? And when you say .setPlus(), are you refering to the button mas? (means plus in spanish). I tried writing it and it gives me errors
Campbell Ritchie wrote:
Campbell Ritchie wrote:
I thought for a second about the arming and disarming but it's not an efficient way to do it, imagine there are 1 million buttons, there is no way you can add a line, if this button is pressed, then arm it, if the other one is pressed, disarm that one and arm this one or is it how it's done?
I think I'm more confused that when I stared hahaha
Here is a link to a basic calculator I created in JavaFX, perhaps it will help you understanding if you study its implementation:
https://gist.github.com/jewelsea/4344564
Note, the calculator is very basic, it does not even handle things operator precedence. However it does give you an indication of how you can maintain some minimal state (a stack value to represent the last value entered, so that when an operation is performed it knows what the two operands to use are), and it does show how to respond to various button press events for the buttons in the calculator.
I'll leave the integration of the shunting yard algorithm with a JavaFX calculator UI as an exercise for the reader ;-) . . .
Also, using FXML for the calculator layout and a CSS stylesheet to style the app, is probably preferrable to doing that work in code as shown below.
Arturo Fern wrote:. . . . And this is my first GUI programming, I don't know swing or the others.
Sorry for not noticing this post earlier; maybe some of your points have been answered by somebody else already.
I wouldn't say there is any problem about whether you know Swing or not. As for the older GUI frameworks: well nobody uses AWT any more anyway.
. . . what exactly does myCalculator mean? . . .
Simply a name for a reference to an instance of the Calculator class. You don't appear to have a Calculator class separate from the GUI, but I believe you should.
And when you say .setPlus() . . .
I meant the setPlus method which my nonexistent Calculator class will have. I meant that I think you should have a Calculator object and that object has a setPlus method. It will also have setMinus methods, etc. You pass a number to it with a setNumber method, call setPlus, pass another number, call setEquals and either setEquals or getResult gives you the result.
Or something like that.
I thought for a second about the arming and disarming but it's not an efficient way to do it, imagine there are 1 million buttons, there is no way you can add a line, if this button is pressed, then arm it, if the other one is pressed, disarm that one and arm this one or is it how it's done? . . .
There won't be 1,000,000 buttons; that wouldn't be possible because the buttons would be too small to see.
You can create a List<Button> and iterate the List disarming every button on the List and then arm a few, or vice versa.
And who is worrying about efficiency? How long will it take to iterate a List and disarm 1,000,000 buttons? 0.01s? 0.1s? Remember you have to compare that speed with the speed the user can move the mouse. If it takes ½ second to push a button with the mouse, it will take the user much longer to move the mouse to a different button.
I am not sure whether arm() and disarm() are the right methods. I suggest you create a tiny GUI with only two or three buttons and see what happens.
John Damien Smith wrote:Here is a link to a basic calculator I created in JavaFX, perhaps it will help you understanding if you study its implementation:
https://gist.github.com/jewelsea/4344564
Thank you VERY MUCH for this, I'm learning it in my spare time, as soon as I finish to study I'll review the code. HOPES ARE BACK! hahah
You did say 1 million before. Was that a misspelling of 1 mille or similar?
I would have thought it possible to show 1,000 buttons on screen in a single GUI, but they would have to be small, not much larger than 30×20 px. Now, putting 1,000 ifs into one method, that will be really difficult.