考虑到要实现实际生活中的计算器模型,这次实验我选择采用java中的GUI图形用户界面来完成计算器的设计。
简单计算器的实现
整体设计
简单计算器的实现 JFrame画板布局和美观化事件监听 监听功能实现 最终效果实现通过对java中图形用户界面基础学习来实现基础的计算器。
学习途径链接:/video/BV1DJ411B75F?from=search&seid=3391209457460119964
创建包和类名后,我们插入实现我们想要的计算器图形界面所需要的组件。
package mysolution;import java.awt.BorderLayout;import java.awt.Color;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JTextField;
JFrame画板
然后我们再来进行计算器的设计。
模拟计算器所用到的按键,对其进行定义和布局。
public class counter extends JFrame implements ActionListener {/** 计算器上的操作键的显示 */private final String[] KEYS = {"7", "8", "9", "/", "sqrt", "4", "5", "6","*", "%", "1", "2", "3", "-", "1/x", "0", "+/-", ".", "+", "=" };/** 计算器上的功能键的显示 */private final String[] COMMAND = {"(",")","Back", "CE", "C" };/** 计算器上边的M功能键的显示 */private final String[] M = {" ", "MC", "MR", "MS", "M+" };/** 定义计算器操作键的按钮长度 */private JButton keys[] = new JButton[KEYS.length];/** 定义计算器功能键的按钮长度 */private JButton commands[] = new JButton[COMMAND.length];/** 定义计算器M功能键的按钮长度 */private JButton m[] = new JButton[M.length];/** 计算结果文本框 */private JTextField resultText = new JTextField("0");
定义运算中的中间变量。
private boolean firstDigit = true;// 计算的中间结果。private double resultNum = 0.0;// 当前运算的运算符private String operator = "=";// 操作是否合法private boolean operateValidFlag = true;
现在开始整体计算器框架界面的实现。
public counter() {super();// 初始化计算器init();// 设置计算器的背景颜色this.setBackground(Color.GRAY);this.setTitle("计算器");// 在屏幕(800, 140)坐标处显示计算器this.setLocation(800, 140);// 不允许修改计算器的大小this.setResizable(false);// 设定计算器中各组件大小this.setSize(450,500);}//用画板划分区块组件JPanel panel1 = new JPanel();// 采用边界布局管理器,画板里组件之间的水平和垂直方向上间隔都为5panel1.setLayout(new BorderLayout(5, 5));panel1.add("North", commandsPanel);panel1.add("Center", calckeysPanel);// 建立一个画板放文本框JPanel top = new JPanel();top.setLayout(new BorderLayout());top.add("Center", resultText);// 整体布局各区块位置getContentPane().setLayout(new BorderLayout(3, 5));getContentPane().add("North", top);getContentPane().add("Center", panel1);getContentPane().add("West", calmsPanel);
布局和美观化
完成了外部的框架,可以开始着手各区块内部元素的具体调控使其有一定的美观性。
private void init() {// 文本框中的内容采用右对齐方式resultText.setHorizontalAlignment(JTextField.RIGHT);// 不允许修改结果文本框resultText.setEditable(false);// 设置文本框背景颜色为亮灰色resultText.setBackground(Color.LIGHT_GRAY);// 初始化计算器上键的按钮,将键放在一个画板内JPanel calckeysPanel = new JPanel();// 用网格布局器,制作4行,5列的网格,网格之间的水平方向间隔为5,垂直方向间隔为3calckeysPanel.setLayout(new GridLayout(4, 5, 5, 3));for (int i = 0; i < KEYS.length; i++) {keys[i] = new JButton(KEYS[i]);calckeysPanel.add(keys[i]);keys[i].setForeground(Color.MAGENTA);}// 运算符键用黑色标示,其他键用蓝色标示keys[3].setForeground(Color.BLACK);keys[8].setForeground(Color.BLACK);keys[13].setForeground(Color.BLACK);keys[18].setForeground(Color.BLACK);keys[19].setForeground(Color.BLACK);keys[4].setForeground(Color.blue);keys[9].setForeground(Color.blue);keys[14].setForeground(Color.blue);// 初始化功能键,都用红色标示。将功能键放在一个画板内JPanel commandsPanel = new JPanel();// 用网格布局器,制作 1行,5列的网格,网格之间的水平方向间隔为5,垂直方向间隔为3commandsPanel.setLayout(new GridLayout(1, 5, 5, 3));for (int i = 0; i < COMMAND.length; i++) {commands[i] = new JButton(COMMAND[i]);commandsPanel.add(commands[i]);commands[i].setForeground(Color.red);}// 初始化M键,用红色标示,并放在一个画板内JPanel calmsPanel = new JPanel();// 用网格布局管理器,制作5行,1列的网格,网格之间的水平方向间隔为3,垂直方向间隔为3calmsPanel.setLayout(new GridLayout(5, 1, 3, 3));for (int i = 0; i < M.length; i++) {m[i] = new JButton(M[i]);calmsPanel.add(m[i]);m[i].setForeground(Color.red);}
事件监听
完成了各按键的设定,接下来我们需要设置事件监听器来实现对操作员的每次操作的监听,然后反映到计算器中。
// 为各按钮添加事件侦听器// 都使用同一个事件侦听器。本类的声明中有implements ActionListenerfor (int i = 0; i < KEYS.length; i++) {keys[i].addActionListener(this);}for (int i = 0; i < COMMAND.length; i++) {commands[i].addActionListener(this);}for (int i = 0; i < M.length; i++) {m[i].addActionListener(this);}}
对每次输入的按键都能做出相应的响应。
public void actionPerformed(ActionEvent e) {// 获取输入的事件源String label = e.getActionCommand();//用户按了"("键if (label.equals(COMMAND[0])) {handlelift();}else if (label.equals(COMMAND[1])) {//用户按了")"键 handleright();}else if (label.equals(COMMAND[2])) {// 用户按了"Back"键handleBack();} else if (label.equals(COMMAND[3])) {// 用户按了"CE"键resultText.setText(" ");} else if (label.equals(COMMAND[4])) {// 用户按了"C"键handleC();} else if ("0123456789.".indexOf(label) >= 0) {// 用户按了数字键或者小数点键handleNumber(label);} else {// 用户按了运算符键handleOperator(label);}}
监听功能实现
接下来是需要具体实现上层的每一个功能。
COMMAND区:
//处理左括号private void handlelift() {}//处理右括号private void handleright() {}/*处理Back键被按下的事件*/private void handleBack() {String text = resultText.getText();int i = text.length();if (i > 0) {// 退格,将文本最后一个字符去掉text = text.substring(0, i - 1);if (text.length() == 0) {// 如果文本没有了内容,则初始化计算器的各种值resultText.setText("0");firstDigit = true;operator = "=";} else {// 显示新的文本resultText.setText(text);}}}
对数字区块功能的实现
KEYS区:
/*处理数字键被按下的事件*/private void handleNumber(String key) {if (firstDigit) {// 输入的第一个数字resultText.setText(key);} else if ((key.equals(".")) && (resultText.getText().indexOf(".") < 0)) {// 输入的是小数点,并且之前没有小数点,则将小数点附在结果文本框的后面resultText.setText(resultText.getText() + ".");} else if (!key.equals(".")) {// 如果输入的不是小数点,则将数字附在结果文本框的后面resultText.setText(resultText.getText() + key);}// 以后输入的肯定不是第一个数字了firstDigit = false;}/*** 处理C键被按下的事件*/private void handleC() {// 初始化计算器的各种值resultText.setText("0");firstDigit = true;operator = "=";}/*处理运算符键被按下的事件 */private void handleOperator(String key) {if (operator.equals("/")) {// 除法运算// 如果当前结果文本框中的值等于0if (getNumberFromText() == 0.0) {// 操作不合法operateValidFlag = false;resultText.setText("除数不能为零");} else {resultNum /= getNumberFromText();}} else if (operator.equals("1/x")) {// 倒数运算if (resultNum == 0.0) {// 操作不合法operateValidFlag = false;resultText.setText("零没有倒数");} else {resultNum = 1 / resultNum;}} else if (operator.equals("+")) {// 加法运算resultNum += getNumberFromText();} else if (operator.equals("-")) {// 减法运算resultNum -= getNumberFromText();} else if (operator.equals("*")) {// 乘法运算resultNum *= getNumberFromText();} else if (operator.equals("sqrt")) {// 平方根运算resultNum = Math.sqrt(resultNum);} else if (operator.equals("%")) {// 百分号运算,除以100resultNum = resultNum / 100;} else if (operator.equals("+/-")) {// 正数负数运算resultNum = resultNum * (-1);} else if (operator.equals("=")) {// 赋值运算resultNum = getNumberFromText();}if (operateValidFlag) {// 双精度浮点数的运算long t1;double t2;t1 = (long) resultNum;t2 = resultNum - t1;if (t2 == 0) {resultText.setText(String.valueOf(t1));} else {resultText.setText(String.valueOf(resultNum));}}// 运算符等于用户按的按钮operator = key;firstDigit = true;operateValidFlag = true;}
最终效果实现
最终计算结果的获取和显示。
/*从结果文本框中获取数字*/private double getNumberFromText() {double result = 0;try {result = Double.valueOf(resultText.getText()).doubleValue();} catch (NumberFormatException e) {}return result;}
main函数对计算器的启动。
public static void main(String args[]) {counter calculator1 = new counter();calculator1.setVisible(true);calculator1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}}
最终运行代码得到的计算器如下图: