主题:
编写一个计算器工具
要求:
编写一个计算器工具,能够实现windows附件中科学型计算器的功能。
教学模式:
理解并分析题目需求,查找资料,设计数据结构和算法,选择最优算法和编程工具。
知识点:
线性结构的使用,栈和队列的使用,多项式计算
能力:
能够掌握线性结构的概念、基本操作,选择合理的结构存储数据,选择适当的工具编写程序,掌握多项式运算算法,编写程序实现题目要求。
项目介绍:
小学期课设作业,基于Java swing,在Eclipse环境下即可运行。印象中退格键有一点bug,但是问题不大,演示时尽量不要使用就好(可用清除键代替)。数字部分导入过字体,如果报错可以删除那行。完整项目下载链接在文末Github链接处获取。
项目截图:
完整代码实现:
class 1: CalcFunc
package view;
import java.text.DecimalFormat;
import java.util.Stack;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class CalcFunc {
private JLabel jLabel = null;
private JTextField jTextField = null;
private JTextField jLeft = null;
private JTextField textM = null;
private double op1=0,op2=0;
public double memory=0;
public int m_Left=0;
public int m_Bits=0;
public double m_Operand=0;
public double m_Accum=0;
public boolean m_Operable=false;
public boolean m_Dot=false;
public String Str;
//定义栈结构来存储运算符和计算数
Stack<Double> m_Stack=null;
Stack<Operator> o_Stack=null;
private enum Operator { OpNone,OpLeft,OpAdd,OpSub,OpFang,OpMod,OpMul,OpDiv,OpExp,OpRight};
public Operator m_Operator=Operator.OpNone;
//构造函数
public CalcFunc(JLabel jL,JTextField jF,JTextField jTL,JTextField jM)
{
this.jLabel=jL;
this.jTextField=jF;
this.jLeft=jTL;
this.textM = jM;
m_Stack=new Stack<Double>();
o_Stack=new Stack<Operator>();
Clear();
}
/**
* 判断double是否是整数
* @param obj
* @return
*/
public static boolean isIntegerForDouble(double obj) {
double eps = 1e-10; // 精度范围
if(obj <1) {
return false;
}
return obj-Math.floor(obj) < eps;
}
public void Input(String str)
{
if(str.equals("."))
{
if(m_Dot) {
this.m_Dot=true;
this.m_Operable=true;
return;
}
else {
this.m_Dot=true;
this.m_Operable=true;
jTextField.setText(jTextField.getText()+str);
return;
}
}
if(str.equals("mod")) {
this.m_Operable=false;
this.m_Operator=Operator.OpMod;
Run();
return;
}
if(str.equals("Exp")) {
this.m_Operable=false;
this.m_Operator=Operator.OpExp;
Run();
return;
}
if(str.equals("x^y")) {
this.m_Operable=false;
this.m_Operator=Operator.OpFang;
Run();
return;
}
if(str.equals("+"))
{
this.m_Operable=false;
this.m_Operator=Operator.OpAdd;
Run();
return;
}
if(str.equals("-"))
{
this.m_Operable=false;
this.m_Operator=Operator.OpSub;
Run();
return;
}
if(str.equals("×"))
{
this.m_Operable=false;
this.m_Operator=Operator.OpMul;
Run();
return;
}
if(str.equals("÷")){
this.m_Operable=false;
this.m_Operator=Operator.OpDiv;
Run();
return;
}
if(str.equals("π")) {
this.m_Operand=Math.PI;
this.m_Operable=true;
Disp2();
return;
}
else if(str.equals("e")) {
this.m_Operand=Math.E;
this.m_Operable=true;
Disp2();
return;
}
if(!this.m_Operable)
{
this.m_Operand=0;
this.m_Dot=false;
this.m_Bits=0;
}
if(this.m_Dot)
{
this.m_Bits++;
this.m_Operand=this.m_Operand+Integer.parseInt(str)/Math.pow(10,this.m_Bits);
}
else {
//System.out.println(m_Operand);
this.m_Operand=this.m_Operand*10+Integer.parseInt(str);
//System.out.println(m_Operand);
}
this.m_Operable=true;
Disp();
}
public void Delete() {
String str = jTextField.getText();
System.out.println("hello"+str);
if(Double.parseDouble(str) > 0){
if(str.length() > 1){
if((str.charAt(str.length()-1))=='.')
this.m_Dot=true;
m_Operand=Double.valueOf(str.substring(0, str.length()-1));
//使用退格删除最后一位字符
jTextField.setText(str.substring(0, str.length()-1));
}else{
jTextField.setText("0");
m_Operand = 0;
}
}else{
if(str.length() > 2){
if((str.charAt(str.length()-1))=='.')
this.m_Dot=true;
jTextField.setText(str.substring(0,str.length() - 1));
m_Operand=Double.valueOf(str.substring(0, str.length()-1));
}else{
jTextField.setText("0");
m_Operand = 0;
}
}
}
public void Disp()
{
double lVal=(m_Operable) ? m_Operand:m_Accum;
System.out.println(lVal);
DecimalFormat df = new DecimalFormat("#.####");
String temp = df.format(lVal);
//System.out.println(temp);
//Str=String.valueOf(lVal);
Str=temp;
if(Str.equals("Infinity"))
{
this.jLabel.setText("超过运算范围!");
Str="0";
}
jTextField.setText(Str);
m_Operand=Double.valueOf(Str);
}
public void Disp2()
{
double lVal=(m_Operable) ? m_Operand:m_Accum;
System.out.println(lVal);
Str=String.valueOf(lVal);
if(Str.equals("Infinity"))
{
this.jLabel.setText("超过运算范围!");
Str="0";
}
jTextField.setText(Str);
m_Operand=Double.valueOf(Str);
}
public void Sqrt()
{
this.m_Operable=false;
this.m_Operand=Math.sqrt(this.m_Operand);
this.m_Accum=this.m_Operand;
Disp();
}
public void Sin()
{
this.m_Operand=this.m_Operand/180*Math.PI;
this.m_Operand=Math.sin(this.m_Operand);
this.m_Accum=this.m_Operand;
this.m_Operable=false;
Disp();
}
public void Cos()
{
this.m_Operand=this.m_Operand/180*Math.PI;
this.m_Operand=Math.cos(this.m_Operand);
this.m_Accum=this.m_Operand;
this.m_Operable=false;
Disp();
}
public void Tan()
{
this.m_Operand=this.m_Operand/180*Math.PI;
this.m_Operand=Math.tan(this.m_Operand);
this.m_Accum=this.m_Operand;
this.m_Operable=false;
Disp();
}
public void jiechen() {
if(isIntegerForDouble(this.m_Operand)) {
int n = (int) this.m_Operand;
System.out.println(n);
if(n>100)
this.jLabel.setText("超过运算范围!");
else
this.m_Operand=fac(n);
Disp();
}
}
//递归计算阶乘
public int fac(int number) {
if (number <= 1)
return 1;
else
return number * fac(number - 1);
}
public void Log()
{
this.m_Operand=Math.log(this.m_Operand);
Disp();
}
public void Left()
{
this.m_Left++;
this.jLeft.setText("( "+String.valueOf(this.m_Left));
this.m_Operator=Operator.OpLeft;
this.m_Operable=false;
Run();
}
public void Right()
{
if(this.m_Left!=0)
{
this.m_Operator=Operator.OpRight;
this.m_Operable=false;
this.m_Left--;
if(this.m_Left!=0)
this.jLeft.setText("( "+String.valueOf(this.m_Left));
else
this.jLeft.setText("");
this.m_Stack.push(this.m_Operand);
Operator Op;
while(this.o_Stack.peek()!=Operator.OpLeft)
{
Op=this.o_Stack.pop();
Compute(Op);
}
this.m_Operand=this.m_Accum=this.m_Stack.peek();
Disp();
this.o_Stack.pop();
this.m_Stack.pop();
}
}
public void X2()
{
this.m_Operable=false;
this.m_Operand=this.m_Operand*this.m_Operand;
this.m_Accum=this.m_Operand;
Disp();
}
public void X3() {
this.m_Operable=false;
this.m_Operand=this.m_Operand*this.m_Operand*this.m_Operand;;
this.m_Accum=this.m_Operand;
Disp();
}
public void X1()
{
this.m_Operable=false;
if(this.m_Operand==0)
{
this.jLabel.setText("除数不能为零!");
}else
this.m_Operand=1/this.m_Operand;
this.m_Accum=this.m_Operand;
Disp();
}
//清空初始化
public void Clear()
{
this.m_Accum=0;
this.m_Left=0;
this.m_Operable=false;
this.m_Operand=0;
this.Str="";
this.jTextField.setText("0");
this.m_Dot=false;
this.m_Stack.clear();
this.o_Stack.clear();
this.jLeft.setText("");
this.op1=0;
this.op2=0;
this.m_Operator=Operator.OpNone;
this.jLabel.setText("科学计算器");
}
public void As()
{
this.m_Operable=false;
this.m_Operand=this.m_Accum=(-1)*this.m_Operand;
Disp();
}
public void Run()
{
Operator Go;
if(this.o_Stack.empty()||(this.m_Operator==Operator.OpLeft)
||this.m_Operator.ordinal()>this.o_Stack.peek().ordinal())
{
if(this.m_Operator==Operator.OpLeft)
this.o_Stack.push(this.m_Operator);
else
{
this.o_Stack.push(this.m_Operator);
this.m_Stack.push(this.m_Operand);
}
}else
{
this.m_Stack.push(this.m_Operand);
while(!this.o_Stack.empty() && this.m_Operator.ordinal()<=this.o_Stack.peek().ordinal())
{
Go=this.o_Stack.pop();
Compute(Go);
}
this.o_Stack.push(this.m_Operator);
}
if(!this.m_Stack.empty())
{
this.m_Operand=this.m_Accum=this.m_Stack.peek();
Disp();
}
if(this.m_Operator==Operator.OpNone)
{
this.o_Stack.clear();
this.m_Stack.clear();
}
}
public void Compute(Operator Opp)
{
int result;
result=GetTwo();
if(result==1)
{
System.out.println("op1"+op1+" op2"+op2);
switch(Opp)
{
case OpAdd: this.m_Stack.push(op1+op2);break;
case OpMul:this.m_Stack.push(op1*op2);break;
case OpFang:this.m_Stack.push(Math.pow(op2,op1));break;
case OpMod:this.m_Stack.push(op2%op1);break;
case OpSub:this.m_Stack.push(op2-op1);break;
case OpDiv:
if(op1==0)
this.jLabel.setText("除数不能为零!");
else
this.m_Stack.push(op2/op1);
break;
case OpExp:
this.m_Stack.push(op2*Math.pow(10, op1));
break;
default:
break;
}
}else
{
this.m_Stack.clear();
this.o_Stack.clear();
}
this.m_Operable=false;
}
private int GetTwo()
{
if(this.m_Stack.empty()) return 0;
op1=this.m_Stack.pop();
if(this.m_Stack.empty()) return 0;
op2=this.m_Stack.pop();
return 1;
}
public void Be()
{
this.m_Operable=false;
this.m_Operator=Operator.OpNone;
Run();
}
public void MS() {
textM.setText("M");
memory = Double.valueOf(jTextField.getText());
}
public void MC() {
textM.setText("");
memory = 0;
}
public void Madd() {
memory+=Double.valueOf(jTextField.getText());
}
public void Mminus() {
memory-=Double.valueOf(jTextField.getText());
}
public void MR() {
jTextField.setText(String.valueOf(memory));
}
}
界面class 2 :calculate
package view;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.util.Stack;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextField;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.SwingConstants;
import java.awt.Font;
public class calculate extends JFrame {
private CalcFunc Func=null;
private JPanel contentPane;
private JTextField jTextField;
private double op1=0,op2=0;
public double PI=3.141592655358989323846264;
public int m_Left=0;
public int m_Bits=0;
public double m_Operand=0;
public double m_Accum=0;
public boolean m_Operable=false;
public boolean m_Dot=false;
public String Str;
Stack<Double> m_Stack=null;
Stack<Operator> o_Stack=null;
private enum Operator { OpNone,OpLeft,OpAdd,OpSub,OpMul,OpDiv,OpRight};
public Operator m_Operator=Operator.OpNone;
private JTextField jLeft;
private JTextField textM;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
calculate frame = new calculate();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public calculate() {
setTitle("科学计算器@ChenHsing");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 494, 472);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
/**
* 文本域,即为计算器的屏幕显示区域
*/
jTextField = new JTextField();
jTextField.setFont(new Font("Digital-7", Font.PLAIN, 40));
jTextField.setBounds(6, 29, 446, 51);
contentPane.add(jTextField);
jTextField.setColumns(10);
jTextField.setEditable(false);//文本区域不可编辑
jTextField.setBackground(Color.white);//文本区域的背景色
jTextField.setHorizontalAlignment(JTextField.RIGHT);//文字右对齐
jTextField.setText("0");
jLeft = new JTextField();
jLeft.setBounds(390, 93, 62, 24);
contentPane.add(jLeft);
jLeft.setColumns(10);
JLabel jLabel = new JLabel("New label");
jLabel.setFont(new Font("宋体", Font.PLAIN, 18));
jLabel.setBounds(177, 0, 197, 27);
contentPane.add(jLabel);
textM = new JTextField();
textM.setBounds(6, 29, 28, 24);
contentPane.add(textM);
textM.setColumns(10);
Func=new CalcFunc(jLabel,this.jTextField,this.jLeft,textM);
JButton Buttonsign = new JButton("±");
Buttonsign.setBounds(84, 340, 62, 27);
contentPane.add(Buttonsign);
JButton Buttonpoint = new JButton(".");
Buttonpoint.setBounds(236, 340, 62, 27);
contentPane.add(Buttonpoint);
JButton Button0 = new JButton("0");
Button0.setBounds(160, 340, 62, 27);
contentPane.add(Button0);
JButton Button1 = new JButton("1");
Button1.setBounds(84, 300, 62, 27);
contentPane.add(Button1);
JButton Button2 = new JButton("2");
Button2.setBounds(160, 300, 62, 27);
contentPane.add(Button2);
JButton Button3 = new JButton("3");
Button3.setBounds(236, 300, 62, 27);
contentPane.add(Button3);
JButton Button4 = new JButton("4");
Button4.setBounds(84, 254, 62, 27);
contentPane.add(Button4);
JButton Button5 = new JButton("5");
Button5.setBounds(160, 254, 62, 27);
contentPane.add(Button5);
JButton Button6 = new JButton("6");
Button6.setBounds(236, 254, 62, 27);
contentPane.add(Button6);
JButton Button7 = new JButton("7");
Button7.setBounds(84, 211, 62, 27);
contentPane.add(Button7);
JButton Button8 = new JButton("8");
Button8.setBounds(160, 211, 62, 27);
contentPane.add(Button8);
JButton Button9 = new JButton("9");
Button9.setBounds(236, 211, 62, 27);
contentPane.add(Button9);
JButton Buttonjia = new JButton("+");
Buttonjia.setBounds(312, 340, 62, 27);
contentPane.add(Buttonjia);
JButton Buttonjian = new JButton("-");
Buttonjian.setBounds(312, 300, 62, 27);
contentPane.add(Buttonjian);
JButton Buttonchen = new JButton("×");
Buttonchen.setBounds(312, 254, 62, 27);
contentPane.add(Buttonchen);
JButton Buttonchu = new JButton("÷");
Buttonchu.setBounds(312, 211, 62, 27);
contentPane.add(Buttonchu);
JButton Buttonsin = new JButton("sin");
Buttonsin.setBounds(84, 171, 62, 27);
contentPane.add(Buttonsin);
JButton Buttoncos = new JButton("cos");
Buttoncos.setBounds(160, 171, 62, 27);
contentPane.add(Buttoncos);
JButton Buttontan = new JButton("tan");
Buttontan.setBounds(236, 171, 62, 27);
contentPane.add(Buttontan);
JButton Buttondelete = new JButton("←");
Buttondelete.setBounds(312, 131, 64, 27);
contentPane.add(Buttondelete);
JButton ButtonC = new JButton("C");
ButtonC.setBounds(388, 131, 64, 27);
contentPane.add(ButtonC);
JButton Buttonx2 = new JButton("x²");
Buttonx2.setBounds(388, 211, 62, 27);
contentPane.add(Buttonx2);
JButton Buttonxy = new JButton("x^y");
Buttonxy.setBounds(388, 254, 62, 27);
contentPane.add(Buttonxy);
JButton Buttonans = new JButton("=");
Buttonans.setBounds(388, 300, 62, 67);
contentPane.add(Buttonans);
JButton Buttonlog = new JButton("log");
Buttonlog.setBounds(84, 131, 62, 27);
contentPane.add(Buttonlog);
JButton Buttonexp = new JButton("Exp");
Buttonexp.setBounds(160, 131, 62, 27);
contentPane.add(Buttonexp);
JButton Buttonmod = new JButton("mod");
Buttonmod.setBounds(236, 131, 62, 27);
contentPane.add(Buttonmod);
JButton Buttonn = new JButton("n!");
Buttonn.setBounds(312, 171, 62, 27);
contentPane.add(Buttonn);
JButton Buttonsqr = new JButton("√");
Buttonsqr.setBounds(388, 171, 62, 27);
contentPane.add(Buttonsqr);
JButton ButtonMadd = new JButton("M+");
ButtonMadd.setBounds(236, 93, 64, 27);
contentPane.add(ButtonMadd);
JButton ButtonMjian = new JButton("M-");
ButtonMjian.setBounds(312, 93, 64, 27);
contentPane.add(ButtonMjian);
JButton Buttonleft = new JButton("(");
Buttonleft.setBounds(6, 300, 64, 27);
contentPane.add(Buttonleft);
JButton Buttonright = new JButton(")");
Buttonright.setBounds(6, 340, 64, 27);
contentPane.add(Buttonright);
JButton Buttonpai = new JButton("π");
Buttonpai.setBounds(6, 211, 62, 27);
contentPane.add(Buttonpai);
JButton Buttone = new JButton("e");
Buttone.setBounds(6, 254, 62, 27);
contentPane.add(Buttone);
JButton ButtonMS = new JButton("MS");
ButtonMS.setBounds(158, 92, 64, 27);
contentPane.add(ButtonMS);
JButton ButtonMR = new JButton("MR");
ButtonMR.setBounds(84, 93, 62, 27);
contentPane.add(ButtonMR);
JButton ButtonMC = new JButton("MC");
ButtonMC.setBounds(6, 93, 62, 27);
contentPane.add(ButtonMC);
JButton Buttondaoshu = new JButton("1/x");
Buttondaoshu.setBounds(8, 131, 62, 27);
contentPane.add(Buttondaoshu);
JButton Buttonx3 = new JButton("x³");
Buttonx3.setBounds(6, 171, 64, 27);
contentPane.add(Buttonx3);
//为记忆功能按钮增加监听事件
ButtonMS.addActionListener(new Action());
ButtonMR.addActionListener(new Action());
ButtonMC.addActionListener(new Action());
ButtonMadd.addActionListener(new Action());
ButtonMjian.addActionListener(new Action());
//为数字按钮增加监听事件
Button0.addActionListener(new Action());
Button1.addActionListener(new Action());
Button2.addActionListener(new Action());
Button3.addActionListener(new Action());
Button4.addActionListener(new Action());
Button5.addActionListener(new Action());
Button6.addActionListener(new Action());
Button7.addActionListener(new Action());
Button8.addActionListener(new Action());
Button9.addActionListener(new Action());
Buttonpai.addActionListener(new Action());
Buttone.addActionListener(new Action());
//为归零和退格键以及符号键设置监听
Buttondelete.addActionListener(new Action());
ButtonC.addActionListener(new Action());
Buttonsign.addActionListener(new Action());
//为运算符设置监听事件
Buttonjia.addActionListener(new Action());
Buttonjian.addActionListener(new Action());
Buttonchen.addActionListener(new Action());
Buttonchu.addActionListener(new Action());
Buttonsin.addActionListener(new Action());
Buttoncos.addActionListener(new Action());
Buttontan.addActionListener(new Action());
Buttonlog.addActionListener(new Action());
Buttonx2.addActionListener(new Action());
Buttonx3.addActionListener(new Action());
Buttonxy.addActionListener(new Action());
Buttonn.addActionListener(new Action());
Buttonexp.addActionListener(new Action());
Buttonmod.addActionListener(new Action());
Buttonsqr.addActionListener(new Action());
Buttonans.addActionListener(new Action());
Buttonleft.addActionListener(new Action());
Buttonright.addActionListener(new Action());
Buttondaoshu.addActionListener(new Action());
//为小数点设置监听事件
Buttonpoint.addActionListener(new Action());
}
/**
* 清除按钮的事件监听
*/
class Action implements ActionListener{
public void actionPerformed(ActionEvent e) {
/*
* 用ActionEvent对象的getActionCommand()方法
* 取得与引发事件对象相关的字符串
*/
String Command=e.getActionCommand();
//this.jLabel.setText("输入...");
if(Command.equals("sin"))
Func.Sin();
else if(Command.equals("cos"))
Func.Cos();
else if(Command.equals("tan"))
Func.Tan();
else if(Command.equals("log"))
Func.Log();
else if(Command.equals("x²"))
Func.X2();
else if(Command.equals("x³"))
Func.X3();
else if(Command.equals("n!"))
Func.jiechen();
else if(Command.equals("1/x"))
Func.X1();
else if(Command.equals("("))
Func.Left();
else if(Command.equals(")"))
Func.Right();
else if(Command.equals("√"))
Func.Sqrt();
else if(Command.equals("C"))
Func.Clear();
else if(Command.equals("←"))
Func.Delete();
//System.exit(0);
else if(Command.equals("="))
Func.Be();
else if(Command.equals("±"))
Func.As();
else if(Command.equals("MS"))
Func.MS();
else if(Command.equals("MR"))
Func.MR();
else if(Command.equals("MC"))
Func.MC();
else if(Command.equals("M+"))
Func.Madd();
else if(Command.equals("M-"))
Func.Mminus();
else
Func.Input(Command);
}
}
}
Github链接:
完整项目下载:点此获取
或许有帮到你的话可以点个Star么~