文章目录
- 一、计算器界面
- 二、已实现功能
- 三、准备工作和思路搭建
- 四、代码与注释(已尽力做到条条代码条条注释了)
- 六、下载
- 七、写在后面
一、计算器界面
二、已实现功能
- BackSpace:实现退格键
- CE:清空文本框
- C:清空并还原
- +、-、*、/:加减乘除运算
- +/-:取相反数
- 1/x:取倒数
- %:百分号
- sqrt:平方根
三、准备工作和思路搭建
- 界面布置
- 界面具体步骤
上述表格中:
标号为1的是一个单独的JPanel面板,面板实行边界布局管理器------>这一步标记为①
标号为2的是一个单独的JPanel面板,面板实行网格布局管理器------>这一步标记为②
标号为3的是一个单独的JPanel面板,面板实行网格布局管理器------>这一步标记为③
标号为4的是一个单独的JPanel面板,面板实行网格布局管理器------>这一步标记为④
创建一个新的JPanel面板,将②和③合为一起,实行边界布局管理器,②置为北边,③置为中央------>这一步标记为⑤
此后便剩下①、⑤、④,所以使用JFrame这个大容器自身面板,创建新的边界布局管理器,①置为北边,④置为西边,⑤置为中央
- 之后实行事件处理
代码注释很详细了
四、代码与注释(已尽力做到条条代码条条注释了)
package calculator;
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;
public class Calculator2 extends JFrame implements ActionListener {
// 准备好东西
// 显示计算机上4行5列区域的按键
private String[] Keys = { "7", "8", "9", "/", "sqrt", "4", "5", "6", "*", "%", "1", "2", "3", "-", "1/x", "0",
"+/-", ".", "+", "=" };
// 定义5行1列的存储M键的按钮
private String[] M = { "", "MC", "MR", "MS", "M+" };
// 定义1行3列的命令行按钮
private String[] Cmd = { "BackSpace", "CE", "C" };
// 定义4行5列键的按钮
private JButton[] keys = new JButton[Keys.length];
// 定义5行1列M键的按钮
private JButton[] m = new JButton[M.length];
// 定义1行3列的功能命令按钮
private JButton[] cmd = new JButton[Cmd.length];
// 计算结果的文本框
private JTextField resultText = new JTextField("0");
// 第一个数字和运算符后的第一个数字的标识
private boolean firstDigit = true;
// 当前运算的运算符
private String operator = "=";
// 操作合法的标识
private boolean operatorFlag = true;
// 运算的中间结果
private double resultMid = 0.0;
public Calculator2() {
super();
init();
// 设置计算器的背景颜色
this.setBackground(Color.LIGHT_GRAY);
this.setTitle("计算器");
// 在屏幕中间位置显示计算器
this.setLocationRelativeTo(null);
// 不许修改计算器的大小,即不可拉伸
this.setResizable(false);
// 设置可见性
this.setVisible(true);
//设置默认关闭
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 使计算器中各组件大小合适
this.pack();
this.setLocationRelativeTo(null);
}
/*
* 进行整个计算器的初始化工作 即整个界面的布置
*/
private void init() {
// 创建面板1来放置4行5列,并设置其布局管理器为网格布局,四行5列.且每一个格子的间距为3
JPanel KEYS = new JPanel();
KEYS.setLayout(new GridLayout(4, 5, 3, 3));
// 实行放置,即实例化,并设置前景色
for (int i = 0; i < Keys.length; i++) {
keys[i] = new JButton(Keys[i]);
// 设置按钮背景颜色
if (i == 3 || i == 8 || i == 13 || i == 18 || i == 19) {
keys[i].setForeground(Color.red);// 这些功能键为红色
} else {
keys[i].setForeground(Color.blue);// 其余的为红色
}
KEYS.add(keys[i]);
}
// 创建面板2用来放置M键,并设置前景色为红色
JPanel Mm = new JPanel();
Mm.setLayout(new GridLayout(5, 1, 3, 3));
for (int i = 0; i < M.length; i++) {
m[i] = new JButton(M[i]);
m[i].setForeground(Color.red);
Mm.add(m[i]);
}
// 创建面板3用来放置1行3列的命令行按钮按键
JPanel CMD = new JPanel();
CMD.setLayout(new GridLayout(1, 3, 3, 3));
for (int i = 0; i < Cmd.length; i++) {
cmd[i] = new JButton(Cmd[i]);
cmd[i].setForeground(Color.red);
CMD.add(cmd[i]);
}
// 创建面板4放置文本框,并设置布局管理器为边界布局
JPanel text = new JPanel();
text.setLayout(new BorderLayout());
// 先对文本框进行设置
// 1.设置文本框为不可编辑
resultText.setEditable(false);
// 2.设置背景色为白色
resultText.setBackground(Color.white);
// 3.设置文本框的内容向右对齐,参数为静态属性
resultText.setHorizontalAlignment(JTextField.RIGHT);
// 将文本框放置面板中
text.add(resultText, "Center");
//创建面板5将1行3列命令行功能键和4行5列按键放置一个大的面板中结为一起,采用边界布局,间距为3像素
JPanel big = new JPanel();
big.setLayout(new BorderLayout(3,3));
big.add(CMD,"North");
big.add(KEYS,"Center");
//进行整体布局
//虽然默认JFrame的布局管理器为边界布局,但是要设置其边距为3,故重新new一个
this.setLayout(new BorderLayout(3,3));
this.add(big,"Center");
this.add(Mm,"West");
this.add(text,"North");
//所有按钮添加事件监听器
for(int i=0;i<Keys.length;i++) {
keys[i].addActionListener(this);
}
for(int j=0;j<M.length;j++) {
m[j].addActionListener(this);
}
for(int i=0;i<Cmd.length;i++) {
cmd[i].addActionListener(this);
}
}
//进行事件处理,以按钮中的字符串内容为区分切入点
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String content = e.getActionCommand();
if(content.equals(Cmd[0])) {
//如果用户按下了退格键,执行BackSpace()函数操作
BackSpace();
firstDigit=true;
}else if(content.equals(Cmd[1])) {
//如果用户按下了CE键,还原文本框,其余不变
resultText.setText("0");
firstDigit=true;
}else if(content.equals(Cmd[2])) {
//如果用户按下了C键,即还原计算器初始状态
resultText.setText("0");
// 当前运算的运算符
operator = "=";
// 操作合法的标识
firstDigit = true;
}else if("0123456789.".indexOf(content)>=0){//从该content内容是否包含在"0123456789."中,从而判断用户按下的是数字或小数点
process(content);//按键数字处理的是文本框中的显示数据
}else {//运算符处理
//前面都不满足时执行这条语句,很巧妙
handOperator(content);//当按下的按钮内容是运算符时
}
}
//处理BackSpace键,这是计算器中的退格键,需要判断两个点,如果结果文本款中没有数字时则还原初始化计算器本身状态,如果有内容,则退去最后一个字符
public void BackSpace() {
String str = resultText.getText();//获取文本框的内容
//进行判断内容情况
if(str.length()>0) {
str = str.substring(0, str.length()-1);//将最后一个字符去掉
//去掉最后一个字符后如果新的文本框字符串中没有了字符则初始化计算器
if(str.length()==0) {
resultText.setText("0");
// 当前运算的运算符
operator = "=";
// 操作合法的标识
operatorFlag = true;
}else {
resultText.setText(str);
}
}
}
//process,进行数字和小数点的处理
public void process(String s) {
if(firstDigit) {//判断是否是键入键盘的第一个数,便于将文本的初始0去掉
resultText.setText(s);
}else if((s.equals("."))&&(resultText.getText().indexOf("."))<0) {//如果第一个键入的数字是小数点
resultText.setText(resultText.getText()+".");
}else if(!(s.equals("."))) {//如果键入的不是小数点
resultText.setText(resultText.getText()+s);
}
//此函数的代码执行到这里最后输入之后的数字便不再是第一个数字了。改变标志
firstDigit=false;
}
//处理用户按下的是运算符的操作
public void handOperator(String c) {
if(operator.equals("/")) {//除法操作的运算符时
if(getDoubleNum()==0.0) {//如果分母为0时
operatorFlag=false;//操作不合法
resultText.setText("分母不能为0");
}else {
resultMid /= getDoubleNum();//使用的结果赋值给中间值,因为初始默认是‘=’操作时,就把中间值赋值为第一个数字了
}
}else if(operator.equals("1/x")) {//如果按的是倒数运算符
if(getDoubleNum()==0.0) {//如果分母为0时
operatorFlag=false;//操作不合法
resultText.setText("0没有倒数");
}else {
resultMid = 1/resultMid;//使用的结果赋值给中间值,因为初始默认是‘=’操作时,就把中间值赋值为第一个数字了
}
}else if(operator.equals("+")) {//如果是加法操作
resultMid += getDoubleNum();
}else if(operator.equals("*")) {//乘法
resultMid *= getDoubleNum();
}else if(operator.equals("sqrt")) {
resultMid=Math.sqrt(getDoubleNum());
}else if(operator.equals("%")) {
//百分号操作
resultMid=resultMid/100;
}else if (operator.equals("+/-")) {
// 正数负数运算
resultMid = resultMid * (-1);
} else if (operator.equals("=")) {
// 赋值运算
resultMid = getDoubleNum();
}else if(operator.equals("-")) {
resultMid -= getDoubleNum();
}
//判断合法后将结果存储在结果文本框中
if (operatorFlag) {
// 双精度浮点数的运算
long t1;
double t2;
t1 = (long) resultMid;//转化为long后,其后面的小数点会没有
t2 = resultMid - t1;//double-long
if (t2 == 0) {//说明此时resultMid是整数
resultText.setText(String.valueOf(t1));
} else {//double类型
resultText.setText(String.valueOf(resultMid));
}
}
//运算符等于用户按下的按钮
operator=c;
firstDigit = true;
operatorFlag = true;
}
//获取结果框中的数字字符串,并转化为double类型
public double getDoubleNum() {
try {
return Double.valueOf(resultText.getText()).doubleValue();
}catch(NumberFormatException e) {
return 0;
}
}
public static void main(String[] args) {
new Calculator2();
}
}
六、写在后面
上述文章如有出错的地方,欢迎读者朋友们评论指正,谢谢。