仿windows系统计算器的设计
一、设计要求
参考Windows 2000/XP系统提供的计算器,设计实现一个计算器软件,具体实现以下几个功能:
(1)提供以下运算:+、-、*、/、sqrt、1/x、xn、n!、log、ln、PI、sin、cos、exp及 ( )等运算。
(2)设置标准运算界面和科学运算界面,合理组织每个界面中的运算符。
(3)要求界面美观大方、功能实现完整。
二、设计指标
(1) 实现+、-、*、/等基本运算和sin、cos、exp等函数运算。
(2) 实现标准运算界面和科学运算界面,其中包括运算按钮、计算结果显示区域以及标准运算界面和科学运算界面的界面转换菜单。
三、UML图
四、代码
//Calculator.java
package Ex;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Calculator extends JFrame{
private double result=0;
public Calculator() {
this.setSize(550,700);
this.setTitle("计算器");
init();
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void init() {
this.setLayout(new BorderLayout());
//总体布局为 BorderLayout
JTextArea textArea=new JTextArea(8,6);
this.add(textArea,BorderLayout.NORTH);
//总体布局north放置文本框
JPanel panel=new JPanel();
//面板panel
panel.setLayout(new BorderLayout());
this.add(panel, BorderLayout.CENTER);
//面板panel放在总体布局BorderLayout的CENTER位置
//JPanel panelN=new JPanel();
CardLayout cardLayout=new CardLayout();
//CardLayout布局用于切换科学与标准界面
JPanel panelC=new JPanel() ;
panelC.setLayout(cardLayout);
//面板panelC为CardLayout布局
JPanel panel0=new JPanel();
//面板panel0设置为网格布局,里面放置标准计算用的按钮
panel0.setLayout(new GridLayout(6,4));
JButton[] standredButton=new JButton[24];
String str[]={
"%","CE","C","del",
"1/x","x^2","sqrt","/",
"7","8","9","*",
"4","5","6","-",
"1","2","3","+",
"+/-","0",".","="
};
for(int i=0;i<standredButton.length;i++) {
standredButton[i]=new JButton(str[i]);
String text=standredButton[i].getText();
standredButton[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(text.equals("CE")||text.equals("C")) {
textArea.setText("");
}
else if(text.equals("=")) {
String s=textArea.getText();
Calculate cal=new Calculate();
textArea.setText(cal.pushandoperate(s)+"");
}
else if(text.equals("del")) {
textArea.setText(textArea.getText().substring(0, textArea.getText().length()-1));
}
else if(text.equals("sqrt")) {
result=Double.parseDouble(textArea.getText());
result=Math.sqrt(result);
textArea.setText(result+"");
}
else if(text.equals("x^2")) {
result=Double.parseDouble(textArea.getText());
result*=result;
textArea.setText(result+"");
}
else if(text.equals("1/x")) {
result=Double.parseDouble(textArea.getText());
result=1/result;
textArea.setText(result+"");
}
else if(text.equals("+/-")) {
result=Double.parseDouble(textArea.getText());
result=-1*result;
textArea.setText(result+"");
}
else {
textArea.setText(textArea.getText()+text);
}
}
}
);
panel0.add(standredButton[i]);
}
panelC.add(panel0);
//将panel0添加到panelC中
JPanel panel1=new JPanel();
//面板panel1设置为网格布局,里面放置科学计算用的按钮
panel1.setLayout(new GridLayout(5,6));
JButton scienceButton[]=new JButton[30];
String str1[]= {
"n!","^","1/x","sqrt","/","clear",
"log","7","8","9","*","(",
"ln","4","5","6","-",")",
"PI","1","2","3","+","exp",
"sin","+/-","0",".","=","cos"
};
for(int i=0;i<scienceButton.length;i++) {
scienceButton[i]=new JButton(str1[i]);
String text=scienceButton[i].getText();
scienceButton[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(text.equals("clear")) {
textArea.setText("");
}
else if(text.equals("=")) {
String s=textArea.getText();
Calculate cal=new Calculate();
textArea.setText(cal.pushandoperate(s)+"");
}
else if(text.equals("PI")) {
result=3.1415926;
textArea.setText(result+"");
}
else if(text.equals("sqrt")) {
result=Double.parseDouble(textArea.getText());
result=Math.sqrt(result);
textArea.setText(result+"");
}
else if(text.equals("1/x")) {
result=Double.parseDouble(textArea.getText());
result=1/result;
textArea.setText(result+"");
}
else if(text.equals("+/-")) {
result=Double.parseDouble(textArea.getText());
result=-1.0*result;
textArea.setText(result+"");
}
else if(text.equals("cos")) {
result=Double.parseDouble(textArea.getText());
result=Math.cos(result);
textArea.setText(result+"");
}
else if(text.equals("sin")) {
result=Double.parseDouble(textArea.getText());
result=Math.sin(result);
textArea.setText(result+"");
}
else if(text.equals("exp")) {
result=Double.parseDouble(textArea.getText());
result=Math.exp(result);
textArea.setText(result+"");
}
else if(text.equals("sqrt")) {
result=Double.parseDouble(textArea.getText());
result=Math.sqrt(result);
textArea.setText(result+"");
}
else if(text.equals("ln")) {
result=Double.parseDouble(textArea.getText());
result=Math.log(result);
textArea.setText(result+"");
}
else if(text.equals("log")) {
result=Double.parseDouble(textArea.getText());
result=Math.log10(result);
textArea.setText(result+"");
}
else if(text.equals("n!")) {
result=Double.parseDouble(textArea.getText());
if(result<0.0) {
textArea.setText("error!"+""); }
else if(result==0.0||result==1.0) {
result=1.0;
textArea.setText(result+""); }
else {
int res=(int)(result);
while(res>1.0) {
result*=(res-1);
res--;
}
textArea.setText(result+"");
}
}
else {
textArea.setText(textArea.getText()+text);
}
}
}
);
panel1.add(scienceButton[i]);
//将科学计算按钮添加到panel1面板中
}
panelC.add(panel1);
//将panel1面板添加到panelC中
panel.add(panelC,BorderLayout.CENTER);
//菜单
JMenuBar menuBar=new JMenuBar();
this.setJMenuBar(menuBar);
JMenu modelMenu=new JMenu("菜单");
menuBar.add(modelMenu);
JMenuItem standred=new JMenuItem("标准");
standred.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cardLayout.first(panelC);
}
});
modelMenu.add(standred);
JMenuItem science=new JMenuItem("科学");
science.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cardLayout.last(panelC);
}
});
modelMenu.add(science);
}
}
//Calculate.java
package Ex;
import java.util.*;
public class Calculate {
//使用空格分割字符串
public String Blanks(String s) {
String result = "";
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(' || s.charAt(i) == ')' ||
s.charAt(i) == '+' || s.charAt(i) == '-'
|| s.charAt(i) == '*' || s.charAt(i) == '/'|| s.charAt(i) == '^'|| s.charAt(i) == '%')
result += " " + s.charAt(i) + " ";
else
result += s.charAt(i);
}
return result;
}
public double pushandoperate(String s) {
Stack<Double> caozuosu= new Stack<>();
Stack<Character> symbol = new Stack<>();
//插入空格
s = Blanks(s);
String[] string = s.split(" ");
//根据空格分割字符串,并且存到数组string中
for (String str : string) {
//如果是空格的话就继续循环
if (str.length() == 0)
continue;
else if (str.charAt(0) == '+' || str.charAt(0) == '-') {
//当栈不空时
//并且栈中最上面的一个元素是加减乘除中任意一个
while (!symbol.isEmpty()&&(symbol.peek() == '-' || symbol.peek() == '+' || symbol.peek() == '/' || symbol.peek() == '*'|| symbol.peek() == '^'|| symbol.peek() =='%')) {
//开始运算
yunsuan(caozuosu, symbol);
}
symbol.push(str.charAt(0)); //运算完之后将当前的运算符入栈
}
//运算符是乘除时,优先级高于加减,因此要判断最上面的是否是乘除,如果是乘除就运算,否则的话直接入栈
else if (str.charAt(0) == '*' || str.charAt(0) == '/' || str.charAt(0) =='^'|| str.charAt(0) =='%') {
while (!symbol.isEmpty()&&(symbol.peek() == '/' || symbol.peek() == '*'|| symbol.peek() == '^'|| symbol.peek() =='%')) {
yunsuan(caozuosu, symbol);
}
symbol.push(str.charAt(0));
//将当前操作符入栈
}
//左括号直接入栈
else if (str.trim().charAt(0) == '(') {
symbol.push('(');
}
//如果是右括号的话,清除栈中的运算符直至左括号
else if (str.trim().charAt(0) == ')') {
while (symbol.peek() != '(') {
yunsuan(caozuosu, symbol);
}
//运算完之后清除左括号
symbol.pop();
}
//如果是数字的话直接入栈
else {
caozuosu.push(Double.parseDouble(str));
}
}
//最后当栈中不是空的时候继续运算,直到栈为空即可
while (!symbol.isEmpty()) {
yunsuan(caozuosu, symbol);
}
return caozuosu.pop(); //此时数据栈中的数据就是运算的结果
}
//处理栈中的两个数据,然后将运算结果存储在栈中
public void yunsuan(Stack<Double> caozuosu, Stack<Character> symbol) {
//从存储操作数的栈中出栈两个数
//从存储符号的栈中出栈操作符
char op = symbol.pop();
Double op1 = caozuosu.pop();
Double op2 = caozuosu.pop();
if (op == '+')
caozuosu.push(op1 + op2);
else if (op == '-')
caozuosu.push(op2 - op1);
else if (op == '*')
caozuosu.push(op1 * op2);
else if (op == '/')
caozuosu.push(op2 / op1);
else if (op == '^')
caozuosu.push(Math.pow(op2,op1));
else if (op == '%')
caozuosu.push(op2%op1);
}
}
//Main.java
package Ex;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Calculator calculator=new Calculator();
}
}
五、运行效果图
注:程序中代码有参考如下链接https://blog.csdn.net/Just_learn_more/article/details/90732604