实验要求
编写计算器界面并实现其功能。
实验步骤
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”键。
结果显示:
测试结论:
代码执行正常,可正常完成各项计算工作。