Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì)
本文實(shí)例為大家分享了Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì)的具體代碼,供大家參考,具體內(nèi)容如下
需求分析
- 目的是實(shí)現(xiàn)一個(gè)基于Java的可以求解帶括號(hào)加減乘除表達(dá)式的帶界面的計(jì)算器。
- 需要知道的Java技術(shù):Java Swing(Java圖形界面設(shè)計(jì))、Java集合(棧)、lambda表達(dá)式、Java基礎(chǔ)等。
設(shè)計(jì)思路
1、實(shí)現(xiàn)一個(gè)Java計(jì)算器界面類
2、實(shí)現(xiàn)一個(gè)Java計(jì)算帶括號(hào)加減乘除表達(dá)式的類
3、實(shí)現(xiàn)主函數(shù)調(diào)用
設(shè)計(jì)實(shí)現(xiàn)
Java計(jì)算器項(xiàng)目結(jié)構(gòu):
Calculator類為計(jì)算器界面設(shè)計(jì)、Calculate類為計(jì)算帶括號(hào)加減乘除表達(dá)式的類,Main函數(shù)為項(xiàng)目程序入口。
Java計(jì)算器界面設(shè)計(jì)實(shí)現(xiàn)代碼:
package Calculator; 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.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; private int count=0; public Calculator() { this.setSize(330,399); this.setTitle("計(jì)算器"); init(); // this.pack(); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void init() {//初始化界面 this.setLayout(new BorderLayout()); //總體布局為邊框式布局 /* * 總體邊框式布局north放置文本框 */ JTextField textField=new JTextField(); textField.disable(); textField.setPreferredSize(new Dimension(this.getWidth(),50)); this.add(textField,BorderLayout.NORTH); /* * 總體邊框式布局center放置@panel(邊框式布局) * @panel邊框式布局north放置@panelN(網(wǎng)格布局) * @panel邊框式布局center放置@panelC(卡片式布局) * @panelC卡片來(lái)切換@panel0(標(biāo)準(zhǔn))和@panel1(科學(xué))兩種模式 * @panel0,@panel1均為網(wǎng)格布局 */ JPanel panel=new JPanel(); panel.setLayout(new BorderLayout()); this.add(panel, BorderLayout.CENTER); JPanel panelN=new JPanel(); panelN.setLayout(new GridLayout(1,6)); JButton MC=new JButton("MC"); JButton MR=new JButton("MR"); JButton M0=new JButton("M+"); JButton M1=new JButton("M-"); JButton MS=new JButton("MS"); JButton M=new JButton("M"); panelN.add(MC);panelN.add(MR);panelN.add(M0); panelN.add(M1);panelN.add(MS);panelN.add(M); panel.add(panelN,BorderLayout.NORTH); CardLayout cardLayout=new CardLayout(); JPanel panelC=new JPanel(); panelC.setLayout(cardLayout); JPanel panel0=new JPanel(); panel0.setLayout(new GridLayout(6,4)); JButton[] standredButton=new JButton[24]; String str[]={"%","√","x²","1/x", "CE","C","×","/", "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() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(text.equals("CE")||text.equals("C")) { textField.setText(""); } else if(text.equals("=")) { String expression=textField.getText(); Calculate cal=new Calculate(); textField.setText(cal.evaluateExpression(expression)+""); } else if(text.equals("%")) { } else if(text.equals("√")) { result=Double.parseDouble(textField.getText()); result=Math.sqrt(result); textField.setText(result+""); } else if(text.equals("x²")) { result=Double.parseDouble(textField.getText()); result*=result; textField.setText(result+""); } else if(text.equals("1/x")) { result=Double.parseDouble(textField.getText()); result=1/result; textField.setText(result+""); } else if(text.equals("±")) { if(count==0) { textField.setText(textField.getText()+"-"); count=1; } else { textField.setText(textField.getText()+"+"); count=0; } } else if(text.equals("×")) { textField.setText(textField.getText().substring(0, textField.getText().length()-1)); } else { textField.setText(textField.getText()+text); } } } ); panel0.add(standredButton[i]); } panelC.add(panel0); JPanel panel1=new JPanel(); panel1.setLayout(new GridLayout(7,5)); JButton scienceButton[]=new JButton[35]; String str1[]= { "x²","x^y","sin","cos","tan", "√","10^x","log","Exp","Mod", "↑","CE","C","×","/", "π","7","8","9","*", "n!","4","5","6","-", "±","1","2","3","+", "(",")","0",".","=" }; for(int i=0;i<str1.length;i++) { scienceButton[i]=new JButton(str1[i]); //scienceButton[i].addActionListener(); panel1.add(scienceButton[i]); } panelC.add(panel1); panel.add(panelC,BorderLayout.CENTER); /* * 菜單 */ JMenuBar menuBar=new JMenuBar(); this.setJMenuBar(menuBar); JMenu modelMenu=new JMenu("模式"); menuBar.add(modelMenu); JMenuItem standred=new JMenuItem("標(biāo)準(zhǔn)"); standred.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub cardLayout.first(panelC); } }); modelMenu.add(standred); JMenuItem science=new JMenuItem("科學(xué)"); science.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub cardLayout.last(panelC); } }); modelMenu.add(science); } /* private class ButtonAction implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub } } */ }
Java計(jì)算帶括號(hào)加減乘除表達(dá)式類的實(shí)現(xiàn):
package Calculator; import java.util.*; /* *使用此類直接調(diào)用evaluateExpression方法即可,傳入需計(jì)算的表達(dá)式,返回計(jì)算結(jié)果 */ public class Calculate { //這個(gè)函數(shù)的作用就是使用空格分割字符串,以便后面使用分割函數(shù)使得將字符串分割成數(shù)組 public String insetBlanks(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) == '/') result += " " + s.charAt(i) + " "; else result += s.charAt(i); } return result; } public double evaluateExpression(String expression) { Stack<Double> operandStack = new Stack<>(); Stack<Character> operatorStack = new Stack<>(); expression = insetBlanks(expression); String[] tokens = expression.split(" "); for (String token : tokens) { if (token.length() == 0) //如果是空格的話就繼續(xù)循環(huán),什么也不操作 continue; //如果是加減的話,因?yàn)榧訙p的優(yōu)先級(jí)最低,因此這里的只要遇到加減號(hào),無(wú)論操作符棧中的是什么運(yùn)算符都要運(yùn)算 else if (token.charAt(0) == '+' || token.charAt(0) == '-') { //當(dāng)棧不是空的,并且棧中最上面的一個(gè)元素是加減乘除的人任意一個(gè) while (!operatorStack.isEmpty()&&(operatorStack.peek() == '-' || operatorStack.peek() == '+' || operatorStack.peek() == '/' || operatorStack.peek() == '*')) { processAnOperator(operandStack, operatorStack); //開(kāi)始運(yùn)算 } operatorStack.push(token.charAt(0)); //運(yùn)算完之后將當(dāng)前的運(yùn)算符入棧 } //當(dāng)前運(yùn)算符是乘除的時(shí)候,因?yàn)閮?yōu)先級(jí)高于加減,因此要判斷最上面的是否是乘除,如果是乘除就運(yùn)算,否則的話直接入棧 else if (token.charAt(0) == '*' || token.charAt(0) == '/') { while (!operatorStack.isEmpty()&&(operatorStack.peek() == '/' || operatorStack.peek() == '*')) { processAnOperator(operandStack, operatorStack); } operatorStack.push(token.charAt(0)); //將當(dāng)前操作符入棧 } //如果是左括號(hào)的話直接入棧,什么也不用操作,trim()函數(shù)是用來(lái)去除空格的,由于上面的分割操作可能會(huì)令操作符帶有空格 else if (token.trim().charAt(0) == '(') { operatorStack.push('('); } //如果是右括號(hào)的話,清除棧中的運(yùn)算符直至左括號(hào) else if (token.trim().charAt(0) == ')') { while (operatorStack.peek() != '(') { processAnOperator(operandStack, operatorStack); //開(kāi)始運(yùn)算 } operatorStack.pop(); //這里的是運(yùn)算完之后清除左括號(hào) } //這里如果是數(shù)字的話直接如數(shù)據(jù)的棧 else { operandStack.push(Double.parseDouble(token)); //將數(shù)字字符串轉(zhuǎn)換成數(shù)字然后壓入棧中 } } //最后當(dāng)棧中不是空的時(shí)候繼續(xù)運(yùn)算,知道棧中為空即可 while (!operatorStack.isEmpty()) { processAnOperator(operandStack, operatorStack); } return operandStack.pop(); //此時(shí)數(shù)據(jù)棧中的數(shù)據(jù)就是運(yùn)算的結(jié)果 } //這個(gè)函數(shù)的作用就是處理?xiàng)V械膬蓚€(gè)數(shù)據(jù),然后將棧中的兩個(gè)數(shù)據(jù)運(yùn)算之后將結(jié)果存儲(chǔ)在棧中 public void processAnOperator(Stack<Double> operandStack, Stack<Character> operatorStack) { char op = operatorStack.pop(); //彈出一個(gè)操作符 Double op1 = operandStack.pop(); //從存儲(chǔ)數(shù)據(jù)的棧中彈出連個(gè)兩個(gè)數(shù)用來(lái)和操作符op運(yùn)算 Double op2 = operandStack.pop(); if (op == '+') //如果操作符為+就執(zhí)行加運(yùn)算 operandStack.push(op1 + op2); else if (op == '-') operandStack.push(op2 - op1); //因?yàn)檫@個(gè)是棧的結(jié)構(gòu),自然是上面的數(shù)字是后面的,因此用op2-op1 else if (op == '*') operandStack.push(op1 * op2); else if (op == '/') operandStack.push(op2 / op1); } }
主函數(shù):
package Calculator; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Calculator calculator=new Calculator(); } }
設(shè)計(jì)實(shí)現(xiàn)展示
可以隨意縮小放大界面,界面部件會(huì)跟隨界面大小自適應(yīng)調(diào)整。
其他功能
目前實(shí)現(xiàn)了標(biāo)準(zhǔn)型計(jì)算,科學(xué)型計(jì)算更加復(fù)雜,實(shí)現(xiàn)了界面,沒(méi)有計(jì)算功能,后續(xù)可能會(huì)繼續(xù)開(kāi)發(fā),敬請(qǐng)期待。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Spring MVC攔截器實(shí)現(xiàn)session控制
這篇文章主要介紹了詳解Spring MVC攔截器實(shí)現(xiàn)session控制,使用session監(jiān)聽(tīng),重復(fù)登錄后,強(qiáng)制之前登錄的session過(guò)期。有興趣的可以了解一下。2017-01-01Springboot解決no main manifest attribute錯(cuò)誤
在開(kāi)發(fā)Springboot項(xiàng)目時(shí),使用java -jar命令運(yùn)行jar包可能出現(xiàn)no main manifest attribute錯(cuò)誤,本文就來(lái)介紹一下該錯(cuò)誤的解決方法,感興趣的可以了解一下2024-09-09FeignClientFactoryBean創(chuàng)建動(dòng)態(tài)代理詳細(xì)解讀
這篇文章主要介紹了FeignClientFactoryBean創(chuàng)建動(dòng)態(tài)代理詳細(xì)解讀,當(dāng)直接進(jìn)去注冊(cè)的方法中,一步步放下走,都是直接放bean的定義信息中放入值,然后轉(zhuǎn)成BeanDefinitionHolder,最后在注冊(cè)到IOC容器中,需要的朋友可以參考下2023-11-11Springboot整合GateWay+Nacos實(shí)現(xiàn)動(dòng)態(tài)路由
本文主要介紹了Springboot整合GateWay+Nacos實(shí)現(xiàn)動(dòng)態(tài)路由,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08Spring根據(jù)URL參數(shù)進(jìn)行路由的方法詳解
這篇文章主要給大家介紹了關(guān)于Spring根據(jù)URL參數(shù)進(jìn)行路由的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起來(lái)看看吧。2017-12-12解決創(chuàng)建springboot后啟動(dòng)報(bào)錯(cuò):Failed?to?bind?properties?under‘spri
在Spring?Boot項(xiàng)目中,application.properties和application.yml是用于配置參數(shù)的兩種文件格式,properties格式簡(jiǎn)潔但不支持層次結(jié)構(gòu),而yml格式支持層次性,可讀性更好,在yml文件中,要注意細(xì)節(jié),比如冒號(hào)后面需要空格2024-10-10