Java简单计算器界面及功能的实现

2022-08-03 09:29:39

实验要求

        编写计算器界面并实现其功能。

实验步骤

1.界面基本样式绘制

代码实现

import java.awt.*;
import javax.swing.*;
public class f_frame extends JFrame{
	public f_frame()
	{
		//创建界面,设置其大小为固定值,宽900,高650,使整个界面都可以正常显示
		JFrame f=new JFrame("计算器");
		f.setSize(900, 650);
		Container con=f.getContentPane();
		//创建1个底色为白色的JPanel,设置其格式为固定格式(即可以自定义的格式)
		JPanel p=new JPanel();
		p.setBackground(Color.white);
		p.setLayout(null);
		//新建名为text的JTextField文本框位置,用于点击是数字的实时变化显示以及最终的结果显示
		//并将其可编辑性设置为用户不可编辑,设置其长宽以及背景颜色。
		JTextField text=new JTextField("");
		text.setEditable(false);
		text.setBackground(new Color(221, 221, 221));  //背景色--灰色
		text.setBounds(100, 50, 700, 50);
		p.add(text);                                   //添加到JPanel中
		//创建JButton数组,包含界面从左到右、自上而下的所有按钮
		JButton[] buttongroup= {
			new JButton("7"), new JButton("8"), new JButton("9"), 
            new JButton("/"),new JButton("CE"),
			new JButton("4"), new JButton("5"), new JButton("6"), 
            new JButton("*"),new JButton("="),
			new JButton("1"), new JButton("2"), new JButton("3"), 
            new JButton("-"),
							  new JButton("0"), new JButton("."),
             new JButton("+")
		};
		//遍历JButton数组,设置每个按钮的颜色、字体字号以及具体位置
		for(int i=0; i<buttongroup.length; i++){
			JButton b1=buttongroup[i];
			b1.setBackground(new Color(204, 204, 255));
			b1.setFont(new Font("宋体", Font.BOLD, 25));
			//位置逻辑,“=”和“0”特判,占据空间略大,其余长宽一致,规律放置
			if(i<9){
				if(i<5) b1.setBounds(100+150*i, 150, 100, 50);
				else b1.setBounds(100+150*(i-5), 250, 100, 50);
			}
			else if(i==9)
				b1.setBounds(100+150*(i-5), 250, 100, 250);
			else if(i==14)
				b1.setBounds(100, 450, 250, 50);
			else {
				if(i<14) b1.setBounds(100+150*(i-10), 350, 100, 50);
				else b1.setBounds(100+150*(i-13), 450, 100, 50);
			}
			p.add(b1);
		}
		//待添加,单击事件
		//向界面中添加JPanel变量,并设置界面可见性为true
		con.add(p);
		f.setVisible(true);
//最后设置界面可见性,否则将会出现加载不到界面内容,必须有鼠标事件才能成功加载的现象发生。
	}
	//主函数,创建界面
	public static void main(String args[])
	{
		f_frame page=new f_frame();
	}
}

结果展示

 2.响应事件的添加以及计算功能的实现

代码实现

import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import javax.swing.*;
import javax.xml.soap.Text;

public class f_frame extends JFrame implements ActionListener{
	//由于text内容需要改变,下面会用到,因此需要拎出来
	//新建名为text的JTextField文本框位置,用于点击是数字的实时变化显示以及最终的结果显示
	JTextField text=new JTextField("");
	public f_frame()
	{
		//创建界面,设置其大小为固定值,宽900,高650,使整个界面都可以正常显示
		JFrame f=new JFrame("计算器");
		f.setSize(900, 650);
		Container con=f.getContentPane();
		//创建1个底色为白色的JPanel,设置其格式为固定格式(即可以自定义的格式)
		JPanel p=new JPanel();
		p.setBackground(Color.white);
		p.setLayout(null);
		//并将text可编辑性设置为用户不可编辑,设置其长宽以及背景颜色。
		text.setEditable(false);
		text.setBackground(new Color(221, 221, 221));  //背景色--灰色
		text.setBounds(100, 50, 700, 50);
		text.setFont(new Font("宋体", Font.BOLD, 25));
		text.setHorizontalAlignment(JTextField.RIGHT); //右对齐
		p.add(text);                                   //添加到JPanel中
		//创建JButton数组,包含界面从左到右、自上而下的所有按钮
		JButton[] buttongroup= {
			new JButton("7"), new JButton("8"), new JButton("9"), 
            new JButton("/"),new JButton("CE"),
			new JButton("4"), new JButton("5"), new JButton("6"), 
            new JButton("*"),new JButton("="),
			new JButton("1"), new JButton("2"), new JButton("3"), 
            new JButton("-"),
							  new JButton("0"), new JButton("."),
             new JButton("+")
		};
		//遍历JButton数组,设置每个按钮的颜色、字体字号以及具体位置
		for(int i=0; i<buttongroup.length; i++){
			JButton b1=buttongroup[i];
			b1.setBackground(new Color(204, 204, 255));
			b1.setFont(new Font("宋体", Font.BOLD, 25));
			b1.addActionListener(this);
			//位置逻辑,“=”和“0”特判,占据空间略大,其余长宽一致,规律放置
			if(i<9){
				if(i<5) b1.setBounds(100+150*i, 150, 100, 50);
				else b1.setBounds(100+150*(i-5), 250, 100, 50);
			}
			else if(i==9)
				b1.setBounds(100+150*(i-5), 250, 100, 250);
			else if(i==14)
				b1.setBounds(100, 450, 250, 50);
			else {
				if(i<14) b1.setBounds(100+150*(i-10), 350, 100, 50);
				else b1.setBounds(100+150*(i-13), 450, 100, 50);
			}
			p.add(b1);
		}
		//向界面中添加JPanel变量,并设置界面可见性为true
		con.add(p);
		f.setVisible(true);
		//最后设置界面可见性,否则将会出现加载不到界面内容,
        //必须有鼠标事件才能成功加载的现象发生。
	}
	//由于优先级的不同,算式中最多需要保留3个操作数,
    //分别按顺序记作num1, num2, num3,初始值为0
	//point变量存储当前按键
	double num1=0.0, num2=0.0, num3=0.0, point=1.0;
	//操作符用int型数据表1:+, 2:-, 3:*, 4:\
	//op存储上一操作符, op_now存储当前读入操作符,
    //op_greater存储优先级较高的后面的操作符
	int op=0, op_now=0, op_greater=0; 
	//标志设计
	Boolean flag_num=false;      //true:num1输入完毕 false:num2尚未输入完毕
	Boolean flag_point=false;    //true:当前数字有小数点 false:当前数字无小数点
	Boolean flag_mistake=false;  //true:输入存在错误 false:输入尚不存在错误
	Boolean flag_begin=false;    
    //true:从上一次输入符号(非等号)起,已经按下某(或某些)数字
	Boolean flag_greater=false;  //true:有较高的优先级计算须先处理
	Boolean flag_end=false;      //true:上一个按下的按键是"=",结束了一次计算
	//响应按钮事件的函数
	//采用按键实时计算的方式,考虑算符优先级的影响
	public void actionPerformed(ActionEvent e)
	{
		//捕获事件来源
		JButton btn=(JButton) e.getSource();
		//上一次按键出错,再次按键需更新错误信息。设置文本为空
		if(flag_mistake) 
		{
			flag_mistake=false;
			text.setText("");
		}
		//获取事件来源按键的内容,方便后续操作
		String s=btn.getText();
		switch(btn.getText())
		{
		case "CE":
			//按下清空键,设置各标志以及各项纪录数据为初始状态,设置文本框内容为空
			flag_point=flag_num=flag_mistake=flag_begin=flag_greater=flag_end=false;
			num1=num2=num3=0.0; point=1.0; op=0;
			text.setText("");
			break;
		case "0": case "1": case "2": case "3": case "4": 
		case "5": case "6": case "7": case "8": case "9":
			//按下数字键,首先已有数字键入,更新flag_begin标志
			flag_begin=true;
			//假设上一按下按键为"=",再次按下数字后,更新文本按下数字,恢复flag_end标志为0
			//假设不成立,则在文本框内容后附加该数字即可
			if(flag_end==true)
			{
				text.setText(btn.getText());
				flag_end=false;
			}
			else text.setText(text.getText()+btn.getText());
			//该数字已经输入小数点后,需要更新小数位数
			if(flag_point)
				point=0.1*point;
			//根据flag_greater、flag_num的信息更新存储的数字
			if(flag_greater) num3=num3*10+s.charAt(0)-'0';
			else if(!flag_num) num1=num1*10+s.charAt(0)-'0';
			else num2=num2*10+s.charAt(0)-'0';
//			System.out.print(num1+" "+num2+" "+num3+"\n");
			break;
		case ".":
			//在小数点前没有按下任何数字,则在前面补0
			if(flag_begin==false) text.setText("0");
			//跟新flag_point并向文本框中添加小数点
			if(!flag_point)  //条件是为了避免同一数字输入过多小数点
			{
				flag_point=true;
				text.setText(text.getText()+".");
			}
			break;
		default:
			//输入符号时,检查操作数是否足够,不够则报错并相应进行标志及存储数据的设置
			//然后对个存储数据进行小数化的处理,若有高优先级的运算须先进行,也在这里处理
			if(flag_begin==false) 
			{
				text.setText("mistack!need more number!");
				flag_mistake=true;
				flag_point=flag_num=flag_greater=flag_end=false;
				num1=num2=num3=0.0; point=1.0; op=0;
			}
			else
			{
				if(flag_greater) num3=point*num3;
				else if(!flag_num) num1=point*num1;
				else num2=point*num2;
				//恢复小数位数标定  设置数据num1以获取以及小数重新开始计的相关标志
				point=1.0;                      
				flag_num=true; flag_point=false;
				//计算需要先进行的高优先级计算段
				if(flag_greater) 
				{
					num2=mul(num2, num3, op_greater);
					num3=0.0;
					flag_greater=false;
				}
			}
		}
		if(flag_begin)
		{
			flag_begin=false;
			//若按键为"+" "-" "*"或"\"则记录当前操作符
			//若按键为"=",则完成最后一次计算并显示结果
			switch(btn.getText())
			{
			case "+":
				text.setText(text.getText()+"+");
				op_now=1; break;
			case "-":
				text.setText(text.getText()+"-");
				op_now=2; break;
			case "*":
				text.setText(text.getText()+"*");
				op_now=3;
				break;
			case "/":
				text.setText(text.getText()+"/");
				op_now=4;
				break;
			case "=":
//				System.out.println(num1+" "+num2+" ");
				if(op!=0)
				{
					num1=mul(num1, num2, op);
					num2=0.0;
				}
				if(!flag_mistake) 
					text.setText(String.valueOf(new DecimalFormat("0.0000").format(num1)));
				op=0; point=1.0;
				flag_end=true;
				break;
			default: flag_begin=true;
			//最终效果:+-*\=号,则flag_begin为false,否则为true
			}
			//进行优先级比较以及计算简化的操作
			if(!flag_begin&&btn.getText()!="=") 
			{
				if(op==0) op=op_now; //第一个算符不需要任何多余操作,存下来就行了
				else if(op_now>=3&&op<3)
				{
					//若当前算符优先级大于前一算符,
					op_greater=op_now;
					flag_greater=true;
				}
				else
				{
					//否则,完成前一算符的计算,将结果更新到num1,设置num2为0,更新算符
					num1=mul(num1, num2, op);
					num2=0.0;
					op=op_now;
					flag_greater=false;
				}
			}
		}
	}
	//真正进行计算的模块
	//传参:a为第一操作数,b为第二操作数,operator为算符(1:+, 2:-, 3:*, 4:\)
	public double mul(double a, double b, int operator)
	{
//		System.out.print(a+" "+b+"\n"); 
		double ans=0.0;    //ans用于存储要返回的计算结果
		switch(operator)
		{
		case 1: ans=a+b; break;
		case 2: ans=a-b; break;
		case 3: ans=a*b; break;
		case 4: 
			//除法党除数为0时进行报错,设置相应的标志以及状态为恢复初始状态
			if(b!=0) ans=a/b;
			else
			{
				System.out.println("mistake accoure");
				text.setText("mistack!devise 0!");
				flag_mistake=true;
				flag_point=flag_num=flag_begin=flag_greater=flag_end=false;
				num1=num2=num3=0.0; point=1.0; op=0;
			}
		}
		return ans;
	}
	//主函数,创建界面
	public static void main(String args[])
	{
		f_frame page=new f_frame();
	}
}

测试过程及结果

测试点1:除0处理:
算式设计:23+4/0-2=
依次按下”2”、”3”、”+”、”4”、”/”、”0”均正常。如下图所示:

当按下”-”号时,文本框显示报错信息:

测试点2:未按数字,直接按算符键,或连续按下两次算符键
算式设计:+
按下+号,显示结果为:

测试点3:正常的不涉及优先级及小数的运算:
算式设计:5+168-189=
显示结果:

测试点4:正常的涉及优先级以及小数的运算:
算式设计:78+69*3/2-77.25=
显示结果:

 测试点5:
CE键的使用(涉及小数,优先级)
算式设计:在上述测试点4的基础上按下“CE”键。
结果显示:

 测试结论:

        代码执行正常,可正常完成各项计算工作。

  • 作者:emandora
  • 原文链接:https://blog.csdn.net/qq_45720855/article/details/122395014
    更新时间:2022-08-03 09:29:39