一、总体实现方案
首先,在Java中先创建一个类Diceng,在Diceng类中编写计算器进行计算的底层逻辑(加减乘除),同时要实现加减乘除的四则运算,最后把Diceng类进行封装,编写一个shart方法来接收要计算的表达式。其次,创建BasicCaculater和ScientificCaculater两个类来实现计算器的标准型和计算器复合型的两个界面编写,并且设定事件监听,最后,编写一个CombinedCaculater类将BasicCaculater类和ScientificCaculater类进行整合,实现标准型和科学型计算器的自由切换。
二、系统结构功能图
三、代码
1、标准计算器页面类
package Caculater; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class BasicCaculater extends JFrame implements ActionListener { private String diyicishuruzhi=null; private String fuhao=null; @Override public void actionPerformed(ActionEvent e) { //按对应按钮后控制台反应 //System.out.println("收到事件"+e.getActionCommand()); //按对应按钮后文本框反应 //outtext.setText(e.getActionCommand()); String zhi=e.getActionCommand(); if(".0123456789-00+~*/-".indexOf(zhi)!=-1){ //JOptionPane.showMessageDialog(this,zhi); this.outtext.setText(outtext.getText()+zhi); this.outtext.setHorizontalAlignment(JTextField.RIGHT); } else if (zhi=="=") { try { if (outtext.getText().indexOf("/0")!=-1){ outtext.setText("除数不能为零"); } else { outtext.setText(Diceng.start(outtext.getText())); //调用Diceng类中的start方法把字符串传到底层进行计算 } }catch (Exception E){ System.out.println("文本框中没有内容"); } } else if (zhi=="<-") { diyicishuruzhi=this.outtext.getText(); try { String shanchuhoudezhi=diyicishuruzhi.substring(0,diyicishuruzhi.length()-1); this.outtext.setText(shanchuhoudezhi); }catch (Exception exception){ System.out.println("文本框中没有字符"); } } } //private static final long ser=1L; JTextField outtext=new JTextField(); JButton butt0=new JButton("0"); JButton butt1=new JButton("1"); JButton butt2=new JButton("2"); JButton butt3=new JButton("3"); JButton butt4=new JButton("4"); JButton butt5=new JButton("5"); JButton butt6=new JButton("6"); JButton butt7=new JButton("7"); JButton butt8=new JButton("8"); JButton butt9=new JButton("9"); JButton buttd=new JButton("."); JButton buttCE=new JButton("CE"); JButton buttDEN=new JButton("="); JButton buttfanghui=new JButton("<-"); JButton buttjiang=new JButton("~"); JButton buttjia=new JButton("+"); JButton buttcheng=new JButton("*"); JButton buttchu=new JButton("/"); JButton buttFH=new JButton("-"); JButton buttLL=new JButton("00"); public BasicCaculater(){ //设置主界面属性:无界面管理器、名字、位置、大小、关闭方法 setLayout(null); //设置主界面 setTitle("标准计算器"); //设置主界面在屏幕上的位置 setLocation(800,300); //设置主界面在屏幕上的大小 setSize(260,350); //设置主界面关闭方式为退出程序 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); outtext.setBounds(10,10,230,40); //设置文本框内容默认为0 outtext.setText(""); //禁止从键盘录入信息进文本框 outtext.setEditable(false); //设置各个按钮的位置大小 butt1.setBounds(10,195,50,40); butt2.setBounds(65,195,50,40); butt3.setBounds(120,195,50,40); buttjiang.setBounds(175,195,50,40); buttjia.setBounds(175,150,50,40); butt4.setBounds(10,150,50,40); butt5.setBounds(65,150,50,40); butt6.setBounds(120,150,50,40); buttchu.setBounds(175,105,50,40); butt7.setBounds(10,105,50,40); butt8.setBounds(65,105,50,40); butt9.setBounds(120,105,50,40); buttfanghui.setBounds(120,60,50,40); buttCE.setBounds(175,60,50,40); //CE按键设置事件,点击该按钮清空文本框 buttCE.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { outtext.setText(""); } }); buttDEN.setBounds(65,60,50,40); buttFH.setBounds(10,60,50,40); butt0.setBounds(65,240,50,40); buttd.setBounds(120,240,50,40); buttcheng.setBounds(175,240,50,40); buttLL.setBounds(10,240,50,40); //把各界面元素加入主界面 add(outtext); add(butt1); add(butt2); add(butt3); add(butt4); add(butt5); add(butt6); add(butt7); add(butt8); add(butt9); add(buttjia); add(buttjiang); add(buttcheng); add(buttchu); add(buttCE); add(buttDEN); add(buttfanghui); add(butt0); add(buttd); add(buttcheng); add(buttFH); add(buttLL); //为各按钮注册(鼠标左击)事件处理器 butt1.addActionListener(this); butt2.addActionListener(this); butt3.addActionListener(this); butt4.addActionListener(this); butt5.addActionListener(this); butt6.addActionListener(this); butt7.addActionListener(this); butt8.addActionListener(this); butt9.addActionListener(this); butt0.addActionListener(this); buttjia.addActionListener(this); buttjiang.addActionListener(this); buttcheng.addActionListener(this); buttchu.addActionListener(this); buttDEN.addActionListener(this); buttfanghui.addActionListener(this); buttCE.addActionListener(this); buttd.addActionListener(this); buttFH.addActionListener(this); buttLL.addActionListener(this); } // public static void main(String[] args) { // BasicCaculater basicCaculater=new BasicCaculater(); // basicCaculater.setVisible(true); // // } }
2、科学型计算器页面类
package Caculater; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class ScientificCaculater extends JFrame implements ActionListener { private String diyicishuruzhi=null; private String fuhao=null; @Override public void actionPerformed(ActionEvent e) { //按对应按钮后控制台反应 //System.out.println("收到事件"+e.getActionCommand()); //按对应按钮后文本框反应 //outtext.setText(e.getActionCommand()); String zhi=e.getActionCommand(); if(".0123456789-00+~*/-".indexOf(zhi)!=-1){ //JOptionPane.showMessageDialog(this,zhi); this.outtext.setText(outtext.getText()+zhi); this.outtext.setHorizontalAlignment(JTextField.RIGHT); } else if (zhi=="=") { try { if (outtext.getText().indexOf("/0")!=-1){ outtext.setText("除数不能为零"); } else { outtext.setText(Diceng.start(outtext.getText())); //调用Diceng类中的start方法把字符串传到底层进行计算 } }catch (Exception E){ System.out.println("文本框中没有内容"); } } else if (zhi=="<-") { diyicishuruzhi=this.outtext.getText(); try { String shanchuhoudezhi=diyicishuruzhi.substring(0,diyicishuruzhi.length()-1); this.outtext.setText(shanchuhoudezhi); }catch (Exception exception){ System.out.println("文本框中没有字符"); } } } // private static final long ser=1L; JTextField outtext=new JTextField(); JButton butt0=new JButton("0"); JButton butt1=new JButton("1"); JButton butt2=new JButton("2"); JButton butt3=new JButton("3"); JButton butt4=new JButton("4"); JButton butt5=new JButton("5"); JButton butt6=new JButton("6"); JButton butt7=new JButton("7"); JButton butt8=new JButton("8"); JButton butt9=new JButton("9"); JButton buttd=new JButton("."); JButton buttCE=new JButton("CE"); JButton buttDEN=new JButton("="); JButton buttfanghui=new JButton("<-"); JButton buttjiang=new JButton("~"); JButton buttjia=new JButton("+"); JButton buttcheng=new JButton("*"); JButton buttchu=new JButton("/"); JButton buttsin=new JButton("sin"); JButton buttcos=new JButton("cos"); JButton buttinv=new JButton("inv"); JButton buttsquare=new JButton("square"); JButton buttsqryt=new JButton("sqrt"); JButton buttFH=new JButton("-"); JButton buttLL=new JButton("00"); JButton butt2jinzhi=new JButton("二进制"); JButton butt8jinzhi=new JButton("八进制"); JButton butt16jinzhi=new JButton("十六进制"); JButton butttan=new JButton("tan"); public ScientificCaculater(){ //设置主界面属性:无界面管理器、名字、位置、大小、关闭方法 setLayout(null); //设置主界面 setTitle("科学计算器"); //设置主界面在屏幕上的位置 setLocation(800,300); //设置主界面在屏幕上的大小 setSize(335,420); //设置主界面关闭方式为退出程序 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); outtext.setBounds(10,10,300,40); //设置文本框内容默认为0 outtext.setText(""); //禁止从键盘录入信息进文本框 outtext.setEditable(false); //设置各个按钮的位置大小 butt1.setBounds(10,260,50,40); butt2.setBounds(65,260,50,40); butt3.setBounds(120,260,50,40); buttjiang.setBounds(175,260,50,40); buttjia.setBounds(175,210,50,40); butt4.setBounds(10,210,50,40); butt5.setBounds(65,210,50,40); butt6.setBounds(120,210,50,40); buttchu.setBounds(175,160,50,40); butt7.setBounds(10,160,50,40); butt8.setBounds(65,160,50,40); butt9.setBounds(120,160,50,40); buttfanghui.setBounds(120,110,50,40); buttCE.setBounds(175,110,50,40); //CE按键设置事件,点击该按钮清空文本框 buttCE.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { outtext.setText(""); } }); buttDEN.setBounds(65,110,50,40); buttFH.setBounds(10,110,50,40); butt0.setBounds(65,310,50,40); buttd.setBounds(120,310,50,40); buttcheng.setBounds(175,310,50,40); buttLL.setBounds(10,310,50,40); buttsin.setBounds(230,110,80,40); buttsin.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (outtext.getText().length()!=0){ Double a=Double.valueOf(outtext.getText()); double b=Math.sin(Math.toRadians(a)); String s=String.valueOf(b); outtext.setText(s); } else { System.out.println("输入框为空"); } } }); buttcos.setBounds(230,160,80,40); buttcos.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (outtext.getText().length()!=0){Double a=Double.valueOf(outtext.getText()); double b=Math.cos(Math.toRadians(a)); String s=String.valueOf(b); outtext.setText(s);} else { System.out.println("输入框为空"); } } }); buttinv.setBounds(230,210,80,40); buttinv.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (outtext.getText().length()!=0){ if (outtext.getText().matches("-?\\d+")){ int b=Integer.valueOf(outtext.getText()); if (b>0){ int num=-(b+1); String s=String.valueOf(num); outtext.setText(s); } else if (b<0) { int num=Math.abs(b)-1; String s=String.valueOf(num); outtext.setText(s); } else if (b==0) { int num=-1; String s=String.valueOf(num); outtext.setText(s); } }else { System.out.println("取反转换不能为小数"); outtext.setText("取反转换不能为小数"); } } else { System.out.println("输入框为空"); } } }); buttsquare.setBounds(230,260,80,40); buttsquare.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (outtext.getText().length()!=0){ Double a=Double.valueOf(outtext.getText()); double b=a*a; String s=String.valueOf(b); outtext.setText(s); }else { System.out.println("输入框为空"); } } }); buttsqryt.setBounds(230,310,80,40); buttsqryt.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(outtext.getText().length()!=0){ Double a=Double.valueOf(outtext.getText()); double b=Math.sqrt(a); String s=String.valueOf(b); outtext.setText(s);} else { System.out.println("输入框为空"); } } }); butttan.setBounds(255,60,55,40); butttan.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (outtext.getText().length()!=0){Double a=Double.valueOf(outtext.getText()); double b=Math.tan(Math.toRadians(a)); String s=String.valueOf(b); outtext.setText(s);} else { System.out.println("输入框为空"); } } }); butt2jinzhi.setBounds(175,60,90,40); butt2jinzhi.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (outtext.getText().length()!=0){ if (outtext.getText().matches("-?\\d+")){ int b=Integer.valueOf(outtext.getText()); String a=Integer.toBinaryString(b); outtext.setText(a); }else { System.out.println("进制转换不能为小数"); outtext.setText("进制转换不能为小数"); } } else { System.out.println("输入框为空"); } } }); butt8jinzhi.setBounds(95,60,90,40); butt8jinzhi.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (outtext.getText().length()!=0){ if (outtext.getText().matches("-?\\d+")){ int b=Integer.valueOf(outtext.getText()); String a=Integer.toOctalString(b); outtext.setText(a); }else { System.out.println("进制转换不能为小数"); outtext.setText("进制转换不能为小数"); } } else { System.out.println("输入框为空"); } } }); butt16jinzhi.setBounds(6,60,90,40); butt16jinzhi.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (outtext.getText().length()!=0){ if (outtext.getText().matches("-?\\d+")){ int b=Integer.valueOf(outtext.getText()); String a=Integer.toHexString(b); outtext.setText(a); }else { System.out.println("进制转换不能为小数"); outtext.setText("进制转换不能为小数"); } } else { System.out.println("输入框为空"); } } }); //把各界面元素加入主界面 add(outtext); add(butt1); add(butt2); add(butt3); add(butt4); add(butt5); add(butt6); add(butt7); add(butt8); add(butt9); add(buttjia); add(buttjiang); add(buttcheng); add(buttchu); add(buttCE); add(buttDEN); add(buttfanghui); add(butt0); add(buttd); add(buttcheng); add(buttsin); add(buttinv); add(buttcos); add(buttsqryt); add(buttsquare); add(buttFH); add(buttLL); add(butttan); add(butt2jinzhi); add(butt8jinzhi); add(butt16jinzhi); //为各按钮注册(鼠标左击)事件处理器 butt1.addActionListener(this); butt2.addActionListener(this); butt3.addActionListener(this); butt4.addActionListener(this); butt5.addActionListener(this); butt6.addActionListener(this); butt7.addActionListener(this); butt8.addActionListener(this); butt9.addActionListener(this); butt0.addActionListener(this); buttjia.addActionListener(this); buttjiang.addActionListener(this); buttcheng.addActionListener(this); buttchu.addActionListener(this); buttDEN.addActionListener(this); buttfanghui.addActionListener(this); //buttCE.addActionListener(this); buttd.addActionListener(this); //buttsin.addActionListener(this); //buttsqryt.addActionListener(this); //buttsquare.addActionListener(this); //buttinv.addActionListener(this); //buttcos.addActionListener(this); buttFH.addActionListener(this); buttLL.addActionListener(this); //butttan.addActionListener(this); //butt2jinzhi.addActionListener(this); //butt8jinzhi.addActionListener(this); //butt16jinzhi.addActionListener(this); } public static void main(String[] args) { ScientificCaculater basicCaculater= new ScientificCaculater(); basicCaculater.setVisible(true); } }
3、复合标准型和科学型界面类
package Caculater; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class CombinedCaculater implements ActionListener{ Caculater.ScientificCaculater sc=new ScientificCaculater(); Caculater.BasicCaculater bc=new BasicCaculater(); JMenuBar mb=new JMenuBar(); //创建菜单栏 JMenu chakan=new JMenu(); //创建查看菜单 JMenu bangzhu=new JMenu(); JMenuItem biaozhunxing=new JMenuItem("标准型"); JMenuItem shiyongshuoming=new JMenuItem("使用说明"); JMenuItem kexuexing=new JMenuItem("科学型"); JMenuItem guanbi=new JMenuItem("关闭"); public CombinedCaculater(){ bc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); sc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mb=caidangshixaing(); biaozhunxing.addActionListener(this); kexuexing.addActionListener(this); guanbi.addActionListener(this); shiyongshuoming.addActionListener(this); sc.setMenuBar(null); sc.setVisible(false); bc.setJMenuBar(mb); bc.setVisible(true); } private JMenuBar caidangshixaing(){ //实现菜单的创建 bangzhu=new JMenu("帮助"); bangzhu.add(shiyongshuoming); chakan = new JMenu("查看"); chakan.add(biaozhunxing); chakan.addSeparator(); chakan.add(kexuexing); chakan.addSeparator(); chakan.add(guanbi); mb.add(chakan); mb.add(bangzhu); return mb; } public void actionPerformed(ActionEvent e){ if (e.getActionCommand().equals("标准型")){ sc.setMenuBar(null); sc.setVisible(false); bc.setJMenuBar(mb); bc.setVisible(true); } else if (e.getActionCommand().equals("科学型")) { bc.setMenuBar(null); bc.setVisible(false); sc.setJMenuBar(mb); sc.setVisible(true); } else if (e.getActionCommand().equals("关闭")) { System.exit(0); } else if (e.getActionCommand().equals("使用说明")) { JOptionPane.showMessageDialog(null, "这是一个简单的复合型计算器程序,支持标准型和科学型,减号与负号是区分开来的," + "减号用”~“来表示,负号用”-“表示。同时不支持多则计算。", "帮助", JOptionPane.INFORMATION_MESSAGE); } } }
4、底层计算类
package Caculater; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Stack; public class Diceng { //对该类进行封装,输入一个表达式,输出一个结果 public static String start(String ex){ return jisuanjieguo(zhuanhuanhouzui(ex)); } //以下方法为将操作字符串进行拆分 private static List<String> chaifen(String ex) { ex=ex.replaceAll("\\s+","");//去除表达式中的空白符 List<String> list = new ArrayList<>(); int len = ex.length(); int start = 0; for (int i = 0; i < len; i++) {//获取当前字符 char tem = ex.charAt(i); if (isyunsuanfu(tem)) { // 如果是运算符 list.add(tem + ""); continue; }// 如果是数字或小数点 start = i;//记录起始位置 if(i+1<len){//判断是否会越界 char next = ex.charAt(i + 1);//查看下一个字符 while (!isyunsuanfu(next)) { i++; if (i+1>=len)break;//如果没有下一个字符,结束循环 next = ex.charAt(i + 1); } } String str = ex.substring(start, i + 1);//截取当前操作数 list.add(str);//将操作数加到list集合中 } return list; } // 判断表达式中的字符是否为运算符 private static boolean isyunsuanfu(char ch) { String Str = ch + ""; return Str.equals("+") || Str.equals("~") || Str.equals("*") || Str.equals("/") || Str.equals("(") || Str.equals(")"); } //方法重载,重新定义一个传入参数为字符串的判断方法 private static boolean isyunsuanfu(String Str) { return Str.equals("+") || Str.equals("~") || Str.equals("*") || Str.equals("/") || Str.equals("(") || Str.equals(")"); } //判断是否为数字 private static boolean isshuzi(char ch) { return ch >= '0' && ch <= '9'; } //以下方法为将中缀表达式转换为后缀表达式 private static List<String> zhuanhuanhouzui(String ex){ List<String> list=chaifen(ex); //调用上面自定义的拆分方法,获取表达式中的各个元素 List<String> exp=new ArrayList<>(list.size()); //用于保存后缀表达式 Stack<String> opcStack=new Stack<>(); //创建栈用来缓存操作符 for (String e:list){ if (!isyunsuanfu(e)){ //如果是操作数 exp.add(e); continue; } //如果是操作数 //1、栈为空,直接把操作符放入栈中 if (opcStack.isEmpty()){ opcStack.push(e); continue; } //2、栈不为空 //查看栈顶元素 String top=opcStack.peek(); //2.1、如果遇到的操作符比栈顶的操作符优先级高,把遇到的操作符直接入栈 if (panduanyouxainji(e,top)){ opcStack.push(e); continue; } //2.2、遇到的操作符优先级小于等于栈顶元素,将栈顶元素出栈并且追加到后缀表达式中, // 直到栈顶元素的优先级小于遇到的操作符或者栈为空时可以停止出栈,停止后将遇到的操作符入栈 while (!opcStack.isEmpty() && !panduanyouxainji(e,top)){ exp.add(top);//追加操作符到后缀表达式中 opcStack.pop();//将栈顶出栈 if (opcStack.size()>0){ top=opcStack.peek();//将栈顶元素更新 } } //将当前操作符入栈 opcStack.push(e); } //扫描完毕后,如果栈不为空,把栈里的元素依次出栈 while (!opcStack.isEmpty()){ exp.add(opcStack.pop()); } return exp; } //该方法用来判断优先级,opt1的优先级大于opt2,返回true,否则,opu1的优先级小于或等于opt2,则返回false private static boolean panduanyouxainji(String opt1 ,String opt2){ if (eq(opt1,"+","~")){//opt1为+,-,直接返回false return false; } //opt1为*,/的时候,opt2为+,—时,返回true if (eq(opt2,"+","~")){ return true; } //opt1为*,/的时候,opt2为*,/的时候,返回false return false; } //该方法用来判断strs中是否存在一个元素和src相等,相等返回ture private static boolean eq(String src,String...strs){ for (String str:strs){ if (src.equals(str))return true; } return false; } //根据后缀表达式计算结果 private static String jisuanjieguo(List<String> exp){ for (int i=0;i<exp.size();i++){ String val=exp.get(i);//获取当前元素 if (!isyunsuanfu(val)){//如果是数字 continue; } BigDecimal prev1=new BigDecimal(exp.get(i-1));//获取当前运算符的后一个数字 BigDecimal prev2=new BigDecimal(exp.get(i-2));//获取当前运算符的前一个数字 BigDecimal result=new BigDecimal(0); switch (val){ case "+": result=prev2.add(prev1); break; case "~": result=prev2.subtract(prev1); break; case "*": result=prev2.multiply(prev1); break; case "/": result=prev2.divide(prev1,2,BigDecimal.ROUND_CEILING); break; } exp.set(i,result.toString()); exp.remove(i-1); exp.remove(i-2); i-=2; } return exp.get(0); } }
5、运行类
package Caculater; public class test { public static void main(String[] args) { new CombinedCaculater(); } }
四、运行结果