import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Font;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
public class calculate
{
public static void main(String [] args)
{
calculatorframe frame = new calculatorframe();
frame.setSize(400,400);
frame.setLocation(300,200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//创建框架,自定义类calculatorframe包含了计算器的信息
}
}
class calculatorframe extends JFrame
{
public calculatorframe()
{
setTitle("CS-3107006697 计算器");
calculatorpanel panel = new calculatorpanel();
add(panel);
//对显示模版布局
}
}
class calculatorpanel extends JPanel
{
JPanel panel=new JPanel();//部件
boolean clean_sign=true;//需不需要清屏,true表示需要
String command_1;//{dy}运算符
String command_2;//第二运算符
boolean command_1_sign=false;//{dy}运算符存在标志
boolean command_2_sign=false;//第二运算符存在标志
boolean command_1_level;//{dy}运算符优先级
boolean command_2_level;//第二运算符优先级
JTextField display=new JTextField();//显示对象
double operand_1;//{dy}操作数,同时保存要显示的结果
double operand_2;//第二操作数
double operand_3;//第三操作数
double result;
public calculatorpanel()//构造函数
{
setLayout(new BorderLayout());
display.setFont(new Font(null,Font.BOLD,22));
display.setText("0");
display.setBackground(new Color(190,240,250));
add (display,BorderLayout.NORTH);//对display输出格式处理
panel.setLayout(new GridLayout(4,4));//4行4列
ActionListener operand = new operandListener();
ActionListener command = new commandListener();
//接下来增加按钮,同时设置按钮不同的监听处理
addButton("7",operand);
addButton("8",operand);
addButton("9",operand);
addButton("+",command);
addButton("4",operand);
addButton("5",operand);
addButton("6",operand);
addButton("-",command);
addButton("1",operand);
addButton("2",operand);
addButton("3",operand);
addButton("*",command);
addButton("清空",command);
addButton("0",operand);
addButton("=",command);
addButton("/",command);
add(panel,BorderLayout.CENTER);//把这个加到显示面板中间
}
private class operandListener implements ActionListener
{//对操作数的监听
public void actionPerformed(ActionEvent event)
{
String input = event.getActionCommand();
if(clean_sign)
{
display.setText("");
clean_sign=false;
}
display.setText(display.getText()+input);
}
}
private class commandListener implements ActionListener
{//对运算符及“清空”的监听
public void actionPerformed(ActionEvent event)
{
String command = event.getActionCommand();
if(command=="清空")
{//按下了“清空”键
clean_sign=true;
command_1_sign=false;
command_2_sign=false;
display.setText("0");
}
else if(command_1_sign&&!command_2_sign)
{//按下了运算符键,且已经按过运算符键
if(!clean_sign)
{//如果在它之前按的是数字键
clean_sign=true;
if(command=="="||command=="+"||command=="-"||command_1_level==true)
{//按下的第二运算符不是乘除,或者{dy}运算符是乘除,则可以产生运算
calculated(operand_1,command_1);
if(command=="=")command_1_sign=false;
else
{
command_1=command;
operand_1=result;
if(command=="+"||command=="-")command_1_level=false;//按下的是加减键
else command_1_level=true;//按下的是乘除键
}
}
else
{
command_2=command;
command_2_sign=true;
command_2_level=true;
operand_2=Double.parseDouble(display.getText());
}
}
else
{//如果按了多下运算键,不理会“=”键
if(command=="*"||command=="/")
{
command_1=command;
command_1_level=true;
}
else if(command=="+"||command=="-")
{
command_1=command;
command_1_level=false;
}
}
}
else if(command_1_sign&&command_2_sign)
{
if(!clean_sign)
{
clean_sign=true;
calculated(operand_2,command_2);
if(command=="="||command=="+"||command=="-")
{
command_2_sign=false;
calculated(operand_1,command_1);
if(command=="=")command_1_sign=false;
else
{
operand_1=result;
command_1=command;
}
}
else //按下的是乘除
{
command_2=command;
operand_2=result;
}
}
else command_2=command;//先算后面俩个数,结果一样,不做修改,例如1-2*+3,按下“+”,则会执行到这里,修改为1-(2+3),执行顺序变了,但结果是一样的,不做修改
}
else if(!command_1_sign&&command!="=")
{
clean_sign=true;
operand_1=Double.parseDouble(display.getText());
command_1_sign=true;
command_1=command;
if(command=="*"||command=="/")command_1_level=true;
else command_1_level=false;
}
}
public void calculated(Double label,String comm)
{//计算函数
Double label_2=Double.parseDouble(display.getText());
if(comm == "+") result = label + label_2;
else if(comm == "-") result = label - label_2;
else if(comm == "*") result = label * label_2;
else if(comm == "/") result = label / label_2;
display.setText(""+result);
}
}
public void addButton(String label,ActionListener listener)
{//增加按钮和监听
JButton ab=new JButton(label);//新按钮
ab.setFont(new Font(null, Font.BOLD, 30));
ab.addActionListener(listener);
panel.add(ab);
}
}
/*
经过一个下午的努力,终于把优先级加上去了,主要是在监听运算键那一部分做功夫,代码不算多,但我考虑了很久,高级语言的编程我真的很菜,不只是对java的各种类不熟悉,还没有形成面向对象的思维,那一大段的代码,if-else不断的判断,xx是汇编的思维,这就是代码的严重不足之处,写得很痛苦,看起来也很痛苦。如果不考虑重复按键,代码可以短很多。
试验例子:1+2*3/2=4;
1+2*3/*+-2=5;(在2之前的"/*+-"只算{zh1}一次按的"-")
1*2*3=6
1*2*3+4=10
跟之前的相比的优点:可以连续输入进行计算,加减乘除有优先级之分,连续多次按键不会产生多次运算。
也许可以采用封装的方法,用一个结构体记录按下的运算符是第几个运算符、是什么优先级、是什么运算符、还有它的两个操作数,显然需要两个这样的结构体对象。
建一个类,包含了这两个结构体对象,专门用来接收运算符,这个类依据两个机构体中的算符优先级做相应处理,处理包括:结构体中运算符的替换、操作数的替换、优先级的替换...总之所做就是对两个机构体的维护,当然每当有运算的时候要有输出,也就是显示结果。
*/
07计算机科学与技术8班 烛秋
09.11.18