1 import java.awt.BorderLayout;
2 import java.awt.GridLayout;
3 import java.awt.event.ActionListener;
4 import java.awt.event.ActionEvent;
5 import javax.swing.ButtonGroup;
6 import javax.swing.JButton;
7 import javax.swing.JCheckBox;
8 import javax.swing.JComboBox;
9 import javax.swing.JFrame;
10 import javax.swing.JPanel;
11 import javax.swing.JRadioButton;
12 import javax.swing.JLabel;
13 import javax.swing.border.EtchedBorder;
14 import javax.swing.border.TitledBorder;
15
16 /**
17 This frame contains a panel that displays buttons
18 for a calculator and a panel with a text fields to
19 specify the result of calculation.
20 */
21 public class CalculatorFrame extends JFrame
22 {
23 private JLabel display;
24 private JCheckBox radianCheckBox;
25 private JRadioButton baseeButton;
26 private JRadioButton base10Button;
27 private JRadioButton base2Button;
28 private JComboBox mathOpCombo;
29 private JButton mathOpButton;
30
31 private double lastValue;
32 private String lastOperator;
33 private boolean startNewValue;
34
35 private static final int FRAME_WIDTH = 400;
36 private static final int FRAME_HEIGHT = 300;
37
38 public CalculatorFrame()
39 {
40 createButtonPanel();
41 createControlPanel();
42
43 display = new JLabel("0");
44 add(display, BorderLayout.NORTH);
45
46 lastValue = 0;
47 lastOperator = "=";
48 startNewValue = true;
49
50 setSize(FRAME_WIDTH, FRAME_HEIGHT);
51 }
52
53 /**
54 Creates the control panel with the text field
55 and buttons on the frame.
56 */
57 private void createButtonPanel()
58 {
59 JPanel buttonPanel = new JPanel();
60 buttonPanel.setLayout(new GridLayout(4, 4));
61
62 buttonPanel.add(makeDigitButton("7"));
63 buttonPanel.add(makeDigitButton("8"));
64 buttonPanel.add(makeDigitButton("9"));
65 buttonPanel.add(makeOperatorButton("/"));
66 buttonPanel.add(makeDigitButton("4"));
67 buttonPanel.add(makeDigitButton("5"));
68 buttonPanel.add(makeDigitButton("6"));
69 buttonPanel.add(makeOperatorButton("*"));
70 buttonPanel.add(makeDigitButton("1"));
71 buttonPanel.add(makeDigitButton("2"));
72 buttonPanel.add(makeDigitButton("3"));
73 buttonPanel.add(makeOperatorButton("-"));
74 buttonPanel.add(makeDigitButton("0"));
75 buttonPanel.add(makeDigitButton("."));
76 buttonPanel.add(makeOperatorButton("="));
77 buttonPanel.add(makeOperatorButton("+"));
78
79 add(buttonPanel, BorderLayout.CENTER);
80 }
81
82 class MathOpListener implements ActionListener
83 {
84 public void actionPerformed(ActionEvent event)
85 {
86 double value = Double.parseDouble(display.getText());
87 String mathOp = (String) mathOpCombo.getSelectedItem();
88
89 double base = 10;
90 if (baseeButton.isSelected()) { base = Math.E; }
91 else if (base2Button.isSelected()) { base = 2; }
92
93 boolean radian = radianCheckBox.isSelected();
94 if (!radian && (mathOp.equals("sin")
95 || mathOp.equals("cos") || mathOp.equals("tan")))
96 {
97 value = Math.toRadians(value);
98 }
99
100 if (mathOp.equals("sin"))
101 {
102 value = Math.sin(value);
103 }
104 else if (mathOp.equals("cos"))
105 {
106 value = Math.cos(value);
107 }
108 else if (mathOp.equals("tan"))
109 {
110 value = Math.tan(value);
111 }
112 else if (mathOp.equals("log"))
113 {
114 value = Math.log(value) / Math.log(base);
115 }
116 else if (mathOp.equals("exp"))
117 {
118 value = Math.pow(base, value);
119 }
120 display.setText("" + value);
121
122 startNewValue = true;
123 }
124 }
125
126 private JPanel createBaseButtons()
127 {
128 baseeButton = new JRadioButton("e");
129 base10Button = new JRadioButton("10");
130 base2Button = new JRadioButton("2");
131
132 baseeButton.setSelected(true);
133
134 ButtonGroup group = new ButtonGroup();
135 group.add(baseeButton);
136 group.add(base10Button);
137 group.add(base2Button);
138
139 JPanel basePanel = new JPanel();
140 basePanel.add(baseeButton);
141 basePanel.add(base10Button);
142 basePanel.add(base2Button);
143 basePanel.setBorder(new TitledBorder(new EtchedBorder(), "Base"));
144
145 return basePanel;
146 }
147
148 private void createControlPanel()
149 {
150 radianCheckBox = new JCheckBox("Radian");
151 radianCheckBox.setSelected(true);
152
153 mathOpCombo = new JComboBox();
154 mathOpCombo.addItem("sin");
155 mathOpCombo.addItem("cos");
156 mathOpCombo.addItem("tan");
157 mathOpCombo.addItem("log");
158 mathOpCombo.addItem("exp");
159
160 mathOpButton = new JButton("Apply");
161 mathOpButton.addActionListener(new MathOpListener());
162
163 JPanel controlPanel = new JPanel();
164 controlPanel.add(radianCheckBox);
165 controlPanel.add(createBaseButtons());
166 controlPanel.add(mathOpCombo);
167 controlPanel.add(mathOpButton);
168
169 add(controlPanel, BorderLayout.SOUTH);
170 }
171
172 /**
173 Combines two values with an operator.
174 @param value1 the first value
175 @param value2 the second value
176 @param op an operator (+, -, *, /, or =)
177 */
178 public double calculate(double value1, double value2, String op)
179 {
180 if (op.equals("+"))
181 {
182 return value1 + value2;
183 }
184 else if (op.equals("-"))
185 {
186 return value1 - value2;
187 }
188 else if (op.equals("*"))
189 {
190 return value1 * value2;
191 }
192 else if (op.equals("/"))
193 {
194 return value1 / value2;
195 }
196 else // "="
197 {
198 return value2;
199 }
200 }
201
202 class DigitButtonListener implements ActionListener
203 {
204 private String digit;
205
206 /**
207 Constructs a listener whose actionPerformed method adds a digit
208 to the display.
209 @param aDigit the digit to add
210 */
211 public DigitButtonListener(String aDigit)
212 {
213 digit = aDigit;
214 }
215
216 public void actionPerformed(ActionEvent event)
217 {
218 if (startNewValue)
219 {
220 display.setText("");
221 startNewValue = false;
222 }
223 display.setText(display.getText() + digit);
224 }
225 }
226
227 /**
228 Makes a button representing a digit of a calculator.
229 @param digit the digit of the calculator
230 @return the button of the calculator
231 */
232 public JButton makeDigitButton(String digit)
233 {
234 JButton button = new JButton(digit);
235 ActionListener listener = new DigitButtonListener(digit);
236 button.addActionListener(listener);
237 return button;
238 }
239
240 class OperatorButtonListener implements ActionListener
241 {
242 private String operator;
243
244 /**
245 Constructs a listener whose actionPerformed method
246 schedules an operator for execution.
247 */
248 public OperatorButtonListener(String anOperator)
249 {
250 operator = anOperator;
251 }
252
253 public void actionPerformed(ActionEvent event)
254 {
255 if (!startNewValue)
256 {
257 double value = Double.parseDouble(display.getText());
258 lastValue = calculate(lastValue, value, lastOperator);
259 display.setText("" + lastValue);
260 startNewValue = true;
261 }
262
263 lastOperator = operator;
264 }
265 }
266
267 /**
268 Makes a button representing an operator of a calculator.
269 @param op the operator of the calculator
270 @return the button of the calculator
271 */
272 public JButton makeOperatorButton(String op)
273 {
274 JButton button = new JButton(op);
275 ActionListener listener = new OperatorButtonListener(op);
276 button.addActionListener(listener);
277 return button;
278 }
279 }