参考蓝桥实验楼的计算器代码,构建一个简易的计算器
前言
实现的功能
(1)一般的计算,先乘除后加减,如2+3-4/2=3
(2)对0为除数的情况(6/0=)、只输入一个操作数一个符号就计算的情况(6+=)作出提示
(3)对当前的计算进行清零
(4)计算出结果后可以把当前结果作为一个数,加入到下一步的计算(3+3= ==》 6 ==》 6+3= ==》 9)
一、UI界面。
1.swing布局介绍
BorderLayout(边框布局管理器)是 Window、JFrame 和 JDialog 的默认布局管理器。边框布局管理器将窗口分为 5 个区域:North、South、East、West 和 Center。其中,North 表示北,将占据面板的上方;South 表示南,将占据面板的下方;East表示东,将占据面板的右侧;West 表示西,将占据面板的左侧;中间区域 Center 是在东、南、西、北都填满后剩下的区域,如图 1 所示:
GridLayout(网格布局管理器)为组件的放置位置提供了更大的灵活性。它将区域分割成行数(rows)和列数(columns)的网格状布局,组件按照由左至右、由上而下的次序排列填充到各个单元格中。
2.本计算器布局
代码如下:
JFrame frame=new JFrame("Calculator by happyday");//窗口标题
frame.setLocation(300, 400);//出现的位置
frame.setResizable(false);//不可调整窗体大小
/*结果文本区面板*/
JPanel panelAbove=new JPanel();
//指定文本信息和列数
JTextField areaShow=new JTextField(show,20);
// 设置文本框为右对齐,使输入和结果都靠右显示
areaShow.setHorizontalAlignment(JTextField.RIGHT);
//清除按钮
JButton btnClear=new JButton("clear");
//使用border布局把组件加入面板
panelAbove.add(areaShow,new BorderLayout().WEST);
panelAbove.add(btnClear,new BorderLayout().EAST);
/*数字符号面板,设置为4行4列的格子,自动调整大小*/
JPanel panelCentor=new JPanel(new GridLayout(4,4,5,5));
//边距
panelCentor.setBorder(new EmptyBorder(10,10,10,10));
panelCentor.add(btn7);
panelCentor.add(btn8);
panelCentor.add(btn9);
panelCentor.add(btnDiv);
panelCentor.add(btn4);
panelCentor.add(btn5);
panelCentor.add(btn6);
panelCentor.add(btnMul);
panelCentor.add(btn1);
panelCentor.add(btn2);
panelCentor.add(btn3);
panelCentor.add(btnSub);
panelCentor.add(btnPoint);
panelCentor.add(btn0);
panelCentor.add(btnEquals);
panelCentor.add(btnAdd);
/*括号面板*/
JPanel panelBelow=new JPanel(new GridLayout(1,2,5,5));
panelBelow.setBorder(new EmptyBorder(0,10,10,10));
JButton btnKuohao1=new JButton("(");
JButton btnKuohao2=new JButton(")");
//面板添加按键
panelBelow.add(btnKuohao1);
panelBelow.add(btnKuohao2);
/*把面板加入窗体*/
frame.add(panelAbove,new BorderLayout().NORTH);
frame.add(panelCentor,new BorderLayout().CENTER);
frame.add(panelBelow,new BorderLayout().SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//自动调整组件大小
frame.pack();
//设置组件可见
frame.setVisible(true);
构造出来的界面如下:
二、实现组件的监听
新建内部类,在内部类中implements ActionListener,在要实现的方法中添加触发按键之后的处理逻辑,然后将组件与实现了ActionListener的内部类相联系,就能使组件的触发符合预期。
class ListenerNumber implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
//获取事件源文字
String numberStr=((JButton)e.getSource()).getText();
//除数为零,提示并退出逻辑
if(show.equals("除数不能为零")) return;
if(str.equals("0")) {
//刚打开面板就输入数字,输入的数字覆盖当前显示的0
str=numberStr;
show=numberStr;
}
else {
//一般情况,把数字追加到之前的字符串中,并更新当前输入的数字
show=show+numberStr;
str=str+numberStr;
}
isMoreSign=isMoreSign+numberStr;
areaShow.setText(show);
}
}
//按键组件添加监听
ListenerNumber ln=new ListenerNumber();
btn1.addActionListener(ln);
三、编写触发组件后的逻辑。
(1)点击数字按键的处理逻辑
(2)点击运算符号(+-*/)按键的处理逻辑
(3)点击“=”按键的处理逻辑
(4)点击“clear”按键的处理逻辑
将使用过的变量/数组全部清零
(5)计算逻辑
把输入的算式中乘除的式子替换为计算结果,然后遍历一遍累加得到结果。
(6)遇到的问题
1.使用double计算和存储计算结果,八位数以上自动使用科学计数法==>把double转换为BigDecimal类型
2.使用double类型,计算的结果为整数也仍然带有小数点==》数字四舍五入的结果一样,把结果的小数点及后面的
数字截断。
3.使用BigDecimal类型数字计算除法10/3等有无穷小数的算式得不到结果==》写成temp=(new BigDecimal(Double.toString(d1)).divide(new BigDecimal(d2),10,RoundingMode.HALF_DOWN));
4.计算器中使用括号的功能没有实现