2022-1-2

【图形界面程序----计算器】

1. 设计任务

1.1设计题目的描述

设计一个计算器应用程序,基于AWT,可以完成加法、减法、乘法、除法和取余运算。

1.2设计要求

使用布局管理器设计一个计算器的界面,练习使用事件***处理数据的输入,并完成加法、减法、乘法、除法和取余运算。

2. 设计方案说明

2.1 整体设计思路

使用AWT编程,Frame B o r d e r L a y o u t . N O R T H BorderLayout.NORTH BorderLayout.NORTH 区域放置TextField组件,将指定为5行4列 GridLayout 布局管理器的 Panel 放置于 Frame B o r d e r L a y o u t . C E N T E R BorderLayout.CENTER BorderLayout.CENTER 区域,其中填充操作符和操作数按钮。

2.2 Calulation类的数据成员

double number1, number2;  							//记录参与运算的两个数字
String operator;									//记录运算符
boolean unfinishedReading;  						//记录是否读数完成
Frame frame = new Frame("高齐勉的计算器!");			// frame窗口对象
TextField inputBox = new TextField(30);				// inputBox 文本框对象
Button[] button = new Button[20];					//创建一组按钮

2.3 Calulation类的构造方法

2.3.1设置文本框的位置

设置窗口的打开位置以及窗口的长和宽

frame.setBounds(200, 200, 400, 320);

将文本框添加在窗口北部区域

frame.add(inputBox, BorderLayout.NORTH);

2.3.2 设置按钮布局

Panel panel = new Panel();
panel.setLayout(new GridLayout(5, 4, 3, 3));

Panel是内嵌式容器,必须内嵌在其它容器中使用,不能独立存在。其默认使用FlowLayout布局管理器。但我使用的是GridLayout网式布局管理器,可以将区域划分为 row*col 个小区域,GridLayout构造方法GridLayout(rows,cols,hgap,vgap)四个参数分别指定了要划分的行、列、水平间距和垂直间距。

2.3.3 设置按钮

String[] s = {
   "sqrt", "<-", "AC","%", 
				"7", "8", "9", "+", 
				"4", "5", "6", "-",
				"1", "2", "3", "*",
				"0", ".", "=", "/"};
for (int i = 0; i < s.length; i++) {
   
     button[i] = new Button(s[i]);//设置按钮上的字符
     button[i].addActionListener(new ActionListen());//设置按钮监听
     panel.add(button[i]);//将按钮放入Panel容器中
}

2.3.4 设置窗口可见,注册窗口监听

将panel设置在中部区域

frame.add(panel,BorderLayout.CENTER);

设置窗口可见

frame.setVisible(true);

窗口***,注册监听,可以关闭窗口

frame.addWindowListener(new WindowAdapter() {
   	//匿名内部类
//窗口***,注册监听,可以关闭窗口
    @Override
    public void windowClosing(WindowEvent e) {
   
        System.exit(0);			//关闭程序
    }
});

WindowAdapter适配器实现了所有的接口方法,以空方法的形式,在其子类中只要重写需要的就行,也是一种设计模式,适配器模式:因为如果要实现所有接口实在太多,不方变,采用这种过渡类.

2.4 ActionListen类实现ActionListener接口

2.4.1 public void actionPerformed(ActionEvent e)

这是接口 ActionListener 里面定义的一个抽象方法,所有实现这个接口的类都要重写这个方法。一般情况下,这是在编写GUI程序时,组件发生“有意义”的事件时会调用这个方法,比如按钮被按下,文本框内输入回车时都会触发这个事件,然后调用你编写的事件处理程序。实现过程大体如下:编写一个 ActionListener 类的***,组件注册该***,***内部要编写这个 actionPerformed 方法。

2.4.2 动作事件(ActionEvent e)

ActionEvent包含一个事件,该事件为执行动作事件ACTION_PERFORMED.触发这个事件的动作为:
• 点击按钮。
• 双击列表中选项。
• 选择菜单项。
• 在文本框中输入回车。

常用方法如下:
public String getActionCommand()
返回引发某个事件的命令按钮的名字,如果名字为空,那么返回标签值。
public void setActionCommand(String command)
设置引发事件的按钮的名字,默认设置为按钮的标签。

2.4.3 number1 = Double.parseDouble(inputBox.getText())

Double.parseDouble方法是把数字类型的字符串,转换成double类型。

parseDouble方法得到的数据类型不能继续编译,因为这个方法得到的是 double ,是Java的基本数据类型

valueOf 方法得到的数据类型可以继续往下编,因为这个方法得到的是 Double,是对象,属于Java的引用数据类型。

2.4.4 inputBox.getText() & inputBox.setText()

获得文本框的内容和设置文本框的内容

2.4.5 expression = expression.substring(0, expression.length() - 1);

public String substring (int beginIndex, int endIndex);

这个方法截取的字符串从 beginIndex 开始,到字符串索引的 endIndex - 1 结束,即截取的字符串不包括 endIndex 这个索引对应的字符,所以 endIndex 的最大值为整个字符串的长度,所以使用这个方法的时候需要特别注意容易发生字符串截取越界的问题

3. 设计题目代码清单

3.1 Java版本:

java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)

3.2 IDE:

IntelliJ IDEA 2021.2.1

3.3 完整代码

package Calculator;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Calculation{
   
    double number1, number2;//记录运算的两个数字
    String operator;
    boolean unfinishedReading;
    Frame frame = new Frame("高齐勉的计算器!");
    TextField inputBox = new TextField(30);
    Button[] button = new Button[20];

    Calculation() {
   
        //设置输入文本框位置
        frame.setBounds(200, 200, 400, 320);
        frame.add(inputBox, BorderLayout.NORTH);
        //设置按钮布局
        Panel panel = new Panel();
        panel.setLayout(new GridLayout(5, 4, 3, 3));
        //设置按钮,并将按钮加入panel
        String[] s = {
   "sqrt", "<-", "AC","%", "7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", "0", ".", "=", "/"};
        for (int i = 0; i < s.length; i++) {
   
            button[i] = new Button(s[i]);
            button[i].addActionListener(new ActionListen());
            panel.add(button[i]);
        }
        frame.add(panel,BorderLayout.CENTER);//将panel设置在中部区域
        frame.setVisible(true);//设置窗口可见
        frame.addWindowListener(new WindowAdapter() {
   //窗口***,注册监听,可以关闭窗口
            @Override
            public void windowClosing(WindowEvent e) {
   
                System.exit(0);
            }
        });
    }
    public class ActionListen implements ActionListener{
   
        @Override
        public void actionPerformed(ActionEvent e) {
   //获取事件源的标签
            String label = e.getActionCommand();
            if (label.equals("=")) {
   
                number2 = Double.parseDouble(inputBox.getText());
                unfinishedReading = true;
                switch (operator) {
   
                    case "+":
                        inputBox.setText(number1 + number2 + "");
                        break;
                    case "-":
                        inputBox.setText(number1 - number2 + "");
                        break;
                    case "*":
                        inputBox.setText(number1 * number2 + "");
                        break;
                    case "/":
                        if (number2 != 0)
                            inputBox.setText(number1 / number2 + "");
                        else
                            inputBox.setText("inf");
                        break;
                    case "%":
                        inputBox.setText(number1 % number2 + "");
                        break;
                    case "sqrt":
                        inputBox.setText( Math.sqrt(number1) + "");
                        break;
                    case "^2":
                        inputBox.setText(number2 * number2 + "");
                        break;
                }
            } else if (label.equals("+") || label.equals("*") || label.equals("/") || label.equals("%") || label.equals("sqrt")) {
   
                number1 = Double.parseDouble(inputBox.getText());
                operator = e.getActionCommand();
                unfinishedReading = false;
            } else if (label.equals("-")) {
   
                if (!unfinishedReading) {
   
                    inputBox.setText("-");
                    unfinishedReading = true;
                } else {
   
                    number1 = Double.parseDouble(inputBox.getText());
                    operator = e.getActionCommand();
                    unfinishedReading = false;
                }
            } else if (label.equals("<-")) {
   
                String expression = inputBox.getText();
                if (expression.length() != 0) {
   
                    expression = expression.substring(0, expression.length() - 1);
                    inputBox.setText(expression);
                } else if (expression.length() == 0 && inputBox.getText().length() != 0)
                    // 对于计算结果后避免删除键不能清楚结果显示
                    inputBox.setText(expression);
            } else if (label.equals("AC")) {
   
                inputBox.setText("");
                unfinishedReading = false;
            } else {
   
                String s = inputBox.getText();
                if (!unfinishedReading)
                    inputBox.setText(label);
                else
                    inputBox.setText(s + label);
                unfinishedReading = true;
            }
        }
    }
    public static void main(String[] args) {
   
        new Calculation();
    }
}

4. 程序测试

4.1运行程序,出现计算器:

4.2加法运算(1+2):

4.3减法运算(2-1):

4.4乘法运算(1*2):

4.5除法运算(4/3):

4.6取余运算(15%4):

5. 课程设计总结

Java语言是计算机程序设计的重要理论基础,在我们今后的学习生活中都有着十分重要的地位。要学好Java语言,仅仅通过课本上的知识是远远不够的,我们要经常动手,锻炼实践能力。

只有多动手,多去实现程序功能开发,才能发现我们的一些问题,不断提高我们的学习能力,改进完善自己的知识体系,在我独立完成这个项目的过程中,我也遇到了一些之前不懂的知识点,特别是图形界面设计实现操作,由于之前对图形界面知识的欠缺,导致一开始根本无从下手,通过这个课程设计也锻炼了我自主学习的能力,经过老师的讲解和网上资料的阅读学习,我基本上掌握了图形界面的创建,设计,添加***,输出结果,通过本次项目的应用,我进一步熟悉面向对象编程中图形界面的流程,为以后的程序开发打下基础,也培养了自己开发一个程序的思维,从功能构思,到伪代码设计,再到程序实现,最后的调试运行修改。

通过一周的学习和不断完善,开发的计算器完美实现项目要求,通过测试,各模块功能正常,感谢老师对我的指导,使我能够用这一周的时间开发出我自己的第一个Java语言程序。我相信,有了这第一个程序的经验积累,今后一定能写出更加高效简洁的程序。

6. 参考文献

[1] 赵莉,孙喁喁,潘煜,徐飞,Java程序设计教程(第二版),西安:西安电子科技大学出版社,2019
[2] Cay s.Horstman Gary Cornell,Java核心技术 卷Ⅰ 基础知识(原书第11版),林琪,苏钰涵,译. 北京:机械工业出版社,2019
[3] 柴田望洋,明解Java,侯振龙,译,北京:人民邮电出版社,2018