|
@@ -3,8 +3,6 @@ package rocks.zipcode.calcskin;
|
3
|
3
|
import javafx.application.Application;
|
4
|
4
|
import javafx.beans.binding.Bindings;
|
5
|
5
|
import javafx.beans.property.*;
|
6
|
|
-import javafx.event.ActionEvent;
|
7
|
|
-import javafx.event.EventHandler;
|
8
|
6
|
import javafx.geometry.Pos;
|
9
|
7
|
import javafx.scene.Scene;
|
10
|
8
|
import javafx.scene.control.*;
|
|
@@ -12,7 +10,6 @@ import javafx.scene.input.KeyEvent;
|
12
|
10
|
import javafx.scene.layout.*;
|
13
|
11
|
import javafx.stage.Stage;
|
14
|
12
|
import javafx.stage.StageStyle;
|
15
|
|
-import rocks.zipcode.calcskin.CalcEngine;
|
16
|
13
|
|
17
|
14
|
import java.util.HashMap;
|
18
|
15
|
import java.util.Map;
|
|
@@ -20,23 +17,30 @@ import java.util.Map;
|
20
|
17
|
// a simple JavaFX calculator.
|
21
|
18
|
public class CalcSkin extends Application {
|
22
|
19
|
|
|
20
|
+
|
23
|
21
|
public static void main(String[] args){
|
24
|
22
|
launch(args);
|
25
|
23
|
}
|
|
24
|
+
|
26
|
25
|
private static final String[][] template = {
|
27
|
|
- { "7", "8", "9", "/" },
|
28
|
|
- { "4", "5", "6", "*" },
|
29
|
|
- { "1", "2", "3", "-" },
|
30
|
|
- { "0", "c", "=", "+" }
|
|
26
|
+ {"tan","cos","sin", "\u221A"},
|
|
27
|
+ { "M+", "MC", "MRC","!"},
|
|
28
|
+ {"+/-", "x\u00B2","x^y", "1/x"},
|
|
29
|
+ {"7", "8", "9", "/"},
|
|
30
|
+ {"4", "5", "6", "*"},
|
|
31
|
+ {"1","2", "3", "-"},
|
|
32
|
+ { "0", "c", "=", "+"}
|
31
|
33
|
};
|
32
|
34
|
|
33
|
35
|
private final Map<String, Button> accelerators = new HashMap<>();
|
34
|
36
|
|
35
|
37
|
private DoubleProperty previousValue = new SimpleDoubleProperty();
|
36
|
38
|
private DoubleProperty currentValue = new SimpleDoubleProperty();
|
37
|
|
- private CalcEngine calcEngine = new CalcEngine();
|
|
39
|
+ private Calculator calc = new Calculator();
|
38
|
40
|
|
39
|
|
- private enum Op { NOOP, ADD, SUBTRACT, MULTIPLY, DIVIDE }
|
|
41
|
+ private enum Op { NOOP, ADD, SUBTRACT, MULTIPLY, DIVIDE,
|
|
42
|
+ SIGN, SQUARE, EXPONENT, INVERT, MEMORY, MEMCLEAR,
|
|
43
|
+ MEMRECALL, FACTORIAL, TANGENT, COSINE, SINE, SQRT }
|
40
|
44
|
|
41
|
45
|
private Op curOp = Op.NOOP;
|
42
|
46
|
private Op stackOp = Op.NOOP;
|
|
@@ -68,13 +72,10 @@ public class CalcSkin extends Application {
|
68
|
72
|
}
|
69
|
73
|
|
70
|
74
|
private void handleAccelerators(VBox layout) {
|
71
|
|
- layout.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
|
72
|
|
- @Override
|
73
|
|
- public void handle(KeyEvent keyEvent) {
|
74
|
|
- Button activated = accelerators.get(keyEvent.getText());
|
75
|
|
- if (activated != null) {
|
76
|
|
- activated.fire();
|
77
|
|
- }
|
|
75
|
+ layout.addEventFilter(KeyEvent.KEY_PRESSED, keyEvent -> {
|
|
76
|
+ Button activated = accelerators.get(keyEvent.getText());
|
|
77
|
+ if (activated != null) {
|
|
78
|
+ activated.fire();
|
78
|
79
|
}
|
79
|
80
|
});
|
80
|
81
|
}
|
|
@@ -84,7 +85,7 @@ public class CalcSkin extends Application {
|
84
|
85
|
screen.setStyle("-fx-background-color: aquamarine;");
|
85
|
86
|
screen.setAlignment(Pos.CENTER_RIGHT);
|
86
|
87
|
screen.setEditable(false);
|
87
|
|
- screen.textProperty().bind(Bindings.format("%.0f", currentValue));
|
|
88
|
+ screen.textProperty().bind(Bindings.format("%.2f", currentValue));
|
88
|
89
|
return screen;
|
89
|
90
|
}
|
90
|
91
|
|
|
@@ -127,20 +128,43 @@ public class CalcSkin extends Application {
|
127
|
128
|
case "-": triggerOp.set(Op.SUBTRACT); break;
|
128
|
129
|
case "*": triggerOp.set(Op.MULTIPLY); break;
|
129
|
130
|
case "/": triggerOp.set(Op.DIVIDE); break;
|
|
131
|
+ case "+/-": triggerOp.set(Op.SIGN); break;
|
|
132
|
+ case "x\u00B2": triggerOp.set(Op.SQUARE); break;
|
|
133
|
+ case "x^y": triggerOp.set(Op.EXPONENT); break;
|
|
134
|
+ case "1/x": triggerOp.set(Op.INVERT); break;
|
|
135
|
+ case "M+": triggerOp.set(Op.MEMORY); break;
|
|
136
|
+ case "MC": triggerOp.set(Op.MEMCLEAR); break;
|
|
137
|
+ case "MRC": triggerOp.set(Op.MEMRECALL); break;
|
|
138
|
+ case "!": triggerOp.set(Op.FACTORIAL); break;
|
|
139
|
+ case "tan": triggerOp.set(Op.TANGENT); break;
|
|
140
|
+ case "cos": triggerOp.set(Op.COSINE); break;
|
|
141
|
+ case "sin": triggerOp.set(Op.SINE); break;
|
|
142
|
+ case "\u221A": triggerOp.set(Op.SQRT); break;
|
130
|
143
|
}
|
131
|
144
|
return triggerOp;
|
132
|
145
|
}
|
133
|
146
|
|
134
|
147
|
private void makeOperandButton(Button button, final ObjectProperty<Op> triggerOp) {
|
135
|
148
|
button.setStyle("-fx-base: lightgray;");
|
136
|
|
- button.setOnAction(new EventHandler<ActionEvent>() {
|
137
|
|
- @Override
|
138
|
|
- public void handle(ActionEvent actionEvent) {
|
139
|
|
- curOp = triggerOp.get();
|
140
|
|
- }
|
|
149
|
+ button.setOnAction(actionEvent -> {
|
|
150
|
+ curOp = triggerOp.get();
|
|
151
|
+ switch (curOp) {
|
|
152
|
+ case SIGN: currentValue.set(calc.changeSign(currentValue.get())); break;
|
|
153
|
+ case SQUARE: currentValue.set(calc.square(currentValue.get())); break;
|
|
154
|
+ case SQRT: currentValue.set(calc.squareRoot(currentValue.get())); break;
|
|
155
|
+ case MEMORY: calc.storeMemory(currentValue.get()); break;
|
|
156
|
+ case MEMCLEAR: calc.clearMemory(); break;
|
|
157
|
+ case MEMRECALL: currentValue.set(calc.getMemory()); break;
|
|
158
|
+ case FACTORIAL: currentValue.set(calc.factorial(currentValue.get())); break;
|
|
159
|
+ case INVERT: currentValue.set(calc.invert(currentValue.get())); break;
|
|
160
|
+ case TANGENT: currentValue.set(TrigFunctions.tangent(currentValue.get())); break;
|
|
161
|
+ case COSINE: currentValue.set(TrigFunctions.cosine(currentValue.get())); break;
|
|
162
|
+ case SINE: currentValue.set(TrigFunctions.sin(currentValue.get())); break;
|
|
163
|
+ }
|
141
|
164
|
});
|
142
|
165
|
}
|
143
|
166
|
|
|
167
|
+
|
144
|
168
|
private Button makeStandardButton(String s) {
|
145
|
169
|
Button button = new Button(s);
|
146
|
170
|
button.setStyle("-fx-base: beige;");
|
|
@@ -150,42 +174,32 @@ public class CalcSkin extends Application {
|
150
|
174
|
}
|
151
|
175
|
|
152
|
176
|
private void makeNumericButton(final String s, Button button) {
|
153
|
|
- button.setOnAction(new EventHandler<ActionEvent>() {
|
154
|
|
- @Override
|
155
|
|
- public void handle(ActionEvent actionEvent) {
|
156
|
|
- if (curOp == Op.NOOP) {
|
157
|
|
- currentValue.set(currentValue.get() * 10 + Integer.parseInt(s));
|
158
|
|
- } else {
|
159
|
|
- previousValue.set(currentValue.get());
|
160
|
|
- currentValue.set(Integer.parseInt(s));
|
161
|
|
- stackOp = curOp;
|
162
|
|
- curOp = Op.NOOP;
|
163
|
|
- }
|
|
177
|
+ button.setOnAction(actionEvent -> {
|
|
178
|
+ if (curOp == Op.NOOP) {
|
|
179
|
+ currentValue.set(currentValue.get() * 10 + Double.parseDouble(s));
|
|
180
|
+ } else {
|
|
181
|
+ previousValue.set(currentValue.get());
|
|
182
|
+ currentValue.set(Integer.parseInt(s));
|
|
183
|
+ stackOp = curOp;
|
|
184
|
+ curOp = Op.NOOP;
|
164
|
185
|
}
|
165
|
186
|
});
|
166
|
187
|
}
|
167
|
188
|
|
168
|
189
|
private void makeClearButton(Button button) {
|
169
|
190
|
button.setStyle("-fx-base: mistyrose;");
|
170
|
|
- button.setOnAction(new EventHandler<ActionEvent>() {
|
171
|
|
- @Override
|
172
|
|
- public void handle(ActionEvent actionEvent) {
|
173
|
|
- currentValue.set(0);
|
174
|
|
- }
|
175
|
|
- });
|
|
191
|
+ button.setOnAction(actionEvent -> currentValue.set(0));
|
176
|
192
|
}
|
177
|
193
|
|
178
|
194
|
private void makeEqualsButton(Button button) {
|
179
|
195
|
button.setStyle("-fx-base: ghostwhite;");
|
180
|
|
- button.setOnAction(new EventHandler<ActionEvent>() {
|
181
|
|
- @Override
|
182
|
|
- public void handle(ActionEvent actionEvent) {
|
183
|
|
- switch (stackOp) {
|
184
|
|
- case ADD: currentValue.set(calcEngine.add(previousValue.get(), currentValue.get())); break;
|
185
|
|
- case SUBTRACT: currentValue.set(calcEngine.subtract(previousValue.get(), currentValue.get())); break;
|
186
|
|
- case MULTIPLY: currentValue.set(calcEngine.multiply(previousValue.get(), currentValue.get())); break;
|
187
|
|
- case DIVIDE: currentValue.set(calcEngine.divide(previousValue.get(), currentValue.get())); break;
|
188
|
|
- }
|
|
196
|
+ button.setOnAction(actionEvent -> {
|
|
197
|
+ switch (stackOp) {
|
|
198
|
+ case ADD: currentValue.set(calc.add(previousValue.get(), currentValue.get())); break;
|
|
199
|
+ case SUBTRACT: currentValue.set(calc.subtract(previousValue.get(), currentValue.get())); break;
|
|
200
|
+ case MULTIPLY: currentValue.set(calc.multiply(previousValue.get(), currentValue.get())); break;
|
|
201
|
+ case DIVIDE: currentValue.set(calc.divide(previousValue.get(), currentValue.get())); break;
|
|
202
|
+ case EXPONENT: currentValue.set(calc.exponent(previousValue.get(), currentValue.get())); break;
|
189
|
203
|
}
|
190
|
204
|
});
|
191
|
205
|
}
|