java实现简单计算器
断断续续的几天时间里,尝试着用java实现了一个简单的计算器。上一次的修复版增加了程序员界面
这是最初的界面:
这是最新界面:
增加了一个程序员界面(实则就是进制转化)
简单看一下项目结构:
5个java文件在一个lianxi包中。Caculator.java是主类来创建两个界面一个Programmer.java和一个std.java。ProgrammerC.java中包含程序员界面计算的一些操作函数。stdC.java是标准界面计算的一些函数。分别看一下源代码:
//Caculator.java package lianxi; import java.awt.*; import javax.swing.*; public class Caculator extends JFrame { JTabbedPane dbTabPane; //选项卡面板 JPanel inputPanel; // 标准面板; JPanel viewPanel; // 程序员面板; std stdPanel; Programmer ProgrammerPanel; public Caculator() { super("计算器"); setGUIComponent(); } public void setGUIComponent() { Container c = getContentPane(); dbTabPane = new JTabbedPane(); // 定义标准面板 inputPanel = new JPanel(); inputPanel.setLayout(null); stdPanel = new std(); inputPanel.add(stdPanel); dbTabPane.add(inputPanel,"标准" ); // 定义程序员面板 viewPanel = new JPanel(); viewPanel.setLayout(null); ProgrammerPanel=new Programmer(); viewPanel.add(ProgrammerPanel); dbTabPane.add(viewPanel,"程序员"); c.add(dbTabPane); } public static void main(String[] args) { Caculator sm = new Caculator(); stdC stdc=new stdC(); Programmer programmer=new Programmer(); sm.setSize(600, 230); sm.setVisible(true); sm.setResizable(false);//窗口大小不可改变 sm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
//Programmer.java package lianxi; import javax.swing.JButton; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.lang.Integer; import javax.swing.*; public class Programmer extends JPanel{ JTextField er_shi1=new JTextField(); JTextField er_shi2=new JTextField(); JTextField shi_er1=new JTextField(); JTextField shi_er2=new JTextField(); JTextField ba_shi1=new JTextField(); JTextField ba_shi2=new JTextField(); JTextField shi_ba1=new JTextField(); JTextField shi_ba2=new JTextField(); JTextField shiliu_shi1=new JTextField(); JTextField shiliu_shi2=new JTextField(); JTextField shi_shiliu1=new JTextField(); JTextField shi_shiliu2=new JTextField(); JLabel ershi=new JLabel("二进制—十进制"); JLabel shier=new JLabel("十进制—二进制"); JLabel bashi=new JLabel("八进制—十进制"); JLabel shiba=new JLabel("十进制—八进制"); JLabel shiliushi=new JLabel("十六进制—十进制"); JLabel shishiliu=new JLabel("十进制—十六进制"); JButton jbt1=new JButton("转化"); JButton jbt2=new JButton("转化"); JButton jbt3=new JButton("转化"); JButton jbt4=new JButton("转化"); JButton jbt5=new JButton("转化"); JButton jbt6=new JButton("转化"); JPanel Pjpanel=new JPanel(); JPanel panel=new JPanel(); ProgrammerC pro=new ProgrammerC(); String str1="",str2="",str3="",str4="",str5="",str6="",str7="",str8="",str9="",str10=""; public Programmer(){ panel.setLayout(new GridLayout(6,4)); panel.add(er_shi1);panel.add(ershi);panel.add(er_shi2);panel.add(jbt1); panel.add(shi_er1);panel.add(shier);panel.add(shi_er2);panel.add(jbt2); panel.add(ba_shi1);panel.add(bashi);panel.add(ba_shi2);panel.add(jbt3); panel.add(shi_ba1);panel.add(shiba);panel.add(shi_ba2);panel.add(jbt4); panel.add(shiliu_shi1);panel.add(shiliushi);panel.add(shiliu_shi2);panel.add(jbt5); panel.add(shi_shiliu1);panel.add(shishiliu);panel.add(shi_shiliu2);panel.add(jbt6); Pjpanel.setLayout(new BorderLayout()); Pjpanel.add(panel,BorderLayout.CENTER); add(Pjpanel); jbt1.addActionListener(new ActionListener() { // 按钮动作事件处理 public void actionPerformed(ActionEvent e) { //换成整数 int flag=0; str1=er_shi1.getText(); int [] zhengxing = new int[str1.length()]; char[] ans1 = str1.toCharArray(); //将字符串转化为字符数组 for(int i=0;i<ans1.length;i++) { if(ans1[i]!='0'&&ans1[i]!='1') flag=1; } if(flag==1) {JOptionPane.showMessageDialog(null, "请输入0或1!"); return; } for(int i=0; i<str1.length(); i++){// zhengxing[i] = Integer.parseInt(str1.charAt(i)+""); } str2=String.valueOf(pro.transform1(zhengxing,2)); er_shi2.setText(str2); } }); jbt2.addActionListener(new ActionListener() { // 按钮动作事件处理 public void actionPerformed(ActionEvent e) { str3=shi_er1.getText(); int flag=0; int [] zhengxing = new int[str3.length()]; char[] ans1 = str3.toCharArray(); //将字符串转化为字符数组 for(int i=0;i<ans1.length;i++) { if(ans1[i]<'0') flag=1; } if(flag==1) {JOptionPane.showMessageDialog(null, "请输入整数"); return; } shi_er2.setText(pro.transform2(str3,2)); } }); jbt3.addActionListener(new ActionListener() { // 按钮动作事件处理 public void actionPerformed(ActionEvent e) { int flag=0; str4=ba_shi1.getText(); int [] zhengxing = new int[str4.length()]; char[] ans1 = str4.toCharArray(); //将字符串转化为字符数组 for(int i=0;i<ans1.length;i++) { if(ans1[i]<'0'||ans1[i]>'7') flag=1; } if(flag==1) { JOptionPane.showMessageDialog(null, "请输入0-7之间的数!"); return; } for(int i=0; i<str4.length(); i++){// zhengxing[i] = Integer.parseInt(str4.charAt(i)+""); } str5=String.valueOf(pro.transform1(zhengxing,8)); ba_shi2.setText(str5); } }); jbt4.addActionListener(new ActionListener() { // 按钮动作事件处理 public void actionPerformed(ActionEvent e) { str6=shi_ba1.getText(); int flag=0; int [] zhengxing = new int[str6.length()]; char[] ans1 = str6.toCharArray(); //将字符串转化为字符数组 for(int i=0;i<ans1.length;i++) { if(ans1[i]<'0') flag=1; } if(flag==1) {JOptionPane.showMessageDialog(null, "请输入整数"); return; } shi_ba2.setText(pro.transform2(str6,8)); } }); jbt5.addActionListener(new ActionListener() { // 按钮动作事件处理 public void actionPerformed(ActionEvent e) { int flag=0; str7=shiliu_shi1.getText(); int [] zhengxing = new int[str7.length()]; char[] ans1 = str7.toCharArray(); //将字符串转化为字符数组 for(int i=0;i<ans1.length;i++) { if((ans1[i]<'0'||ans1[i]>'9')&&(ans1[i]<'A'||ans1[i]>'F')&&(ans1[i]<'a'||ans1[i]>'f')) flag=1; } if(flag==1) { JOptionPane.showMessageDialog(null, "请输入0-F之间的数!"); return; } for(int i=0; i<str7.length(); i++){// if(str7.charAt(i)=='A'||str7.charAt(i)=='B'||str7.charAt(i)=='C'||str7.charAt(i)=='D'||str7.charAt(i)=='E'||str7.charAt(i)=='F') { zhengxing[i]=str7.charAt(i)-55; }else if(str7.charAt(i)=='a'||str7.charAt(i)=='b'||str7.charAt(i)=='c'||str7.charAt(i)=='d'||str7.charAt(i)=='e'||str7.charAt(i)=='f'){ zhengxing[i]=str7.charAt(i)-87; }else zhengxing[i] = Integer.parseInt(str7.charAt(i)+""); } str8=String.valueOf(pro.transform1(zhengxing,16)); shiliu_shi2.setText(str8); } }); jbt6.addActionListener(new ActionListener() { // 按钮动作事件处理 public void actionPerformed(ActionEvent e) { str9=shi_shiliu1.getText(); int flag=0; int [] zhengxing = new int[str9.length()]; char[] ans1 = str9.toCharArray(); //将字符串转化为字符数组 for(int i=0;i<ans1.length;i++) { if(ans1[i]<'0') flag=1; } if(flag==1) {JOptionPane.showMessageDialog(null, "请输入整数"); return; } shi_shiliu2.setText(pro.transform2(str9,16)); } }); setVisible(true); setSize(600, 300); } }
//ProgrammerC.java package lianxi; //进制转化 //二进制——>十进制、 十进制——>二进制 //八进制——>十进制、 十进制——>八进制 //十六进制——>十进制、 十进制——>十六进制 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Iterator; import java.util.Vector; public class ProgrammerC { String str1=""; public int transform1(int[] er_shi,int k) {//k为要转化的进制数 int ans=0; for(int i=er_shi.length-1;i>=0;i--) { for(int j=0;j<er_shi.length-1-i;j++) er_shi[i]*=k; ans+=er_shi[i]; } return ans; } public String transform2(String s,int k) {//k为要转化的进制数 int ans = Integer.parseInt(s); int chushu; String s1=""; Vector b=new Vector(); chushu=ans; while(chushu!=0) { if(k!=16) { b.add(chushu%k); chushu=chushu/k; }else { if(chushu%k==10||chushu%k==11||chushu%k==12||chushu%k==13||chushu%k==14||chushu%k==15) { switch(chushu%k) { case 10:b.add("A");break; case 11:b.add("B");break; case 12:b.add("C");break; case 13:b.add("D");break; case 14:b.add("E");break; case 15:b.add("F");break; } }else b.add(chushu%k); chushu=chushu/k; } } for(int i=0;i<b.size();i++) { s1+=b.get(i); } return new StringBuffer(s1).reverse().toString();//将字符串反向输出 } }
//std.java package lianxi; import javax.swing.*; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.ArrayList; public class std extends JPanel{ String cs=" "; String input=""; String beifen=""; public JButton[] jbs = new JButton[20]; JButton save = new JButton("保存"); JButton copy = new JButton("复制"); JButton clear = new JButton("清除"); JTextField tf = new JTextField(); JTextArea text = new JTextArea(); JPanel panel1 = new JPanel(); StringBuffer strBuf = new StringBuffer(); JScrollPane js = new JScrollPane(text);// 滚动条 ArrayList<String> strArray = new ArrayList<String>(); public std() { setGUIComponent(); } public void setGUIComponent(){ //初始化组件 setLayout(null); tf.setHorizontalAlignment(JTextField.RIGHT);// 右对齐 // tf.setEditable(false);//文本框禁止编辑 tf.setBounds(0, 10, 350, 30); panel1.setLayout(new GridLayout(4, 5, 0, 0)); panel1.setBounds(0, 50, 350, 120); // text.setLineWrap(true);//自动换行 js.setBounds(360, 5, 200, 130); save.setBounds(360, 140, 60, 30); copy.setBounds(430, 140, 60, 30); clear.setBounds(500,140, 60, 30); strArray.add("1"); strArray.add("2"); strArray.add("3"); strArray.add("+"); strArray.add("c"); strArray.add("4"); strArray.add("5"); strArray.add("6"); strArray.add("-"); strArray.add("退格"); strArray.add("7"); strArray.add("8"); strArray.add("9"); strArray.add("*"); strArray.add("√");strArray.add("0"); strArray.add(".");strArray.add("%"); strArray.add("/"); strArray.add("="); for (int i = 0; i < jbs.length; i++) { jbs[i] = new JButton(strArray.get(i) + ""); jbs[i].setSize(70, 30); panel1.add(jbs[i]); jbs[i].addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub String s = arg0.getActionCommand(); //System.out.println("123"); if (s.equals("=") == false) {// 不为等于时全显示 cs += s; } if (s.equals("c")) { cs = " "; input = ""; beifen = ""; } if (s.equals("退格")) { int m = input.length(); int n = beifen.length(); int flag = 0; for (int i = 0; i < cs.length(); i++) { if (tf.getText().equals("") && cs.charAt(i) == '退') { flag = 1; cs = " "; return; } } if (flag == 0) { if (m == 1) { input = input.substring(0, 0);// 防止输入一个数字就退格 tf.setText(""); return; } if (input.charAt(m - 2) == '+' || input.charAt(m - 2) == '-' || input.charAt(m - 2) == '*' || input.charAt(m - 2) == '/' || input.charAt(m - 2) == '%' || input.charAt(m - 2) == '√') { input = input.substring(0, input.length() - 3); } else input = input.substring(0, input.length() - 1); cs = cs.substring(0, cs.length() - 3); } } tf.setText(cs); if (s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/") || s.equals("%")|| s.equals("√")) { input += " " + s + " "; } else if (s.equals("=")) { String input1 = ""; String show = ""; for (int i = 0; i < input.length(); i++) { if (input.charAt(i) != 'c') { input1 += input.charAt(i); } } show = input1 + "=" + " " +stdC.compute(input); strBuf.append(show + "\n"); text.setText(strBuf.toString()); } else if (s.equals("退格") == false) { /*这里如果改成if (s.equals("退格") == false||s.equals("c") == false) 的话,那么当输入"c"时逻辑判断第一个成立,逻辑短路,条件成立。那么就将"c"假如到了input 因此,在compute计算函数中才将"c"取出*/ input += s; } } }); } add(tf); add(js); add(panel1); add(save); add(copy); add(clear); save.addActionListener(new ActionListener() { // 按钮动作事件处理 public void actionPerformed(ActionEvent e) { BufferedWriter out = null; int flag=0; String Filename="d://writeFile.txt";//更改文件路径 File file = new File(Filename); try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true))); out.append(text.getText()); } catch (Exception e0) { e0.printStackTrace(); } finally { try { out.flush(); out.close(); } catch (IOException e1) { e1.printStackTrace(); } JOptionPane.showMessageDialog(null, "已保存在文件"+Filename+"中"); } } }); copy.addActionListener(new ActionListener() { // 按钮动作事件处理 public void actionPerformed(ActionEvent e) { text.copy(); } }); clear.addActionListener(new ActionListener() { // 按钮动作事件处理 public void actionPerformed(ActionEvent e) { text.setText(""); strBuf.setLength(0); // 清空strBuf中的数据 } }); setVisible(true); setSize(600, 300); } }
//stdC.java package lianxi; /*这里注意计算根号时,只能单个计算例如(根号9)不能计算带根号的表达式 * 因为根号没加入到栈里面,而是另外的函数 * */ import java.lang.Math; import java.math.BigDecimal; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Stack; import javax.swing.JButton; public class stdC { public stdC() { } public static int sq(int n){//求根函数1 if( n == 1){ return 1; } int tmp = 0; for(int i=1;i<=n/2+1;i++){ if(i*i == n){ tmp = i; break; } if(i*i > n){ tmp = i-1; break; } } return tmp; } public static double[] sc(int m){//求根函数2m==3保留三位小数 double[] arr = new double[m]; int num = 0; while(num != m){ double f = 1; for(int i=0;i<=num;i++){ f = f*10; } arr[num] = 1/f;//arr[0]=0.1 f==10、arr[1]=0.01 f==100、arr[2]=0.001 f==1000 num++; } return arr; } public static double sb(int n, double j, double[] arr){//求根函数3 double tmp = j; //2 for(int p=0;p<arr.length;p++){ if(p>0){ j = tmp;//计算过后的值(整数位+小数位的和,赋值给j,下面继续运算) } for(int i=1;i<=9;i++){//小数位只有九位{0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9} tmp = i*arr[p]+j;//i*arr[p],相当于每次加0.1,0.2 ... if(tmp*tmp == n){ return tmp; } if(tmp*tmp >n){ //避免丢失精度 BigDecimal c1 = new BigDecimal(Double.toString(tmp)); BigDecimal c2 = new BigDecimal(Double.toString(arr[p])); tmp = c1.subtract(c2).doubleValue(); break; } } } return tmp; } public static String compute(String input)// 即1237 的 样例 { String str[]; String inputnew = ""; double dou; for (int i = 0; i < input.length(); i++) { if (input.charAt(i) != 'c') { inputnew += input.charAt(i); } } str = inputnew.split(" ");// 以空格分隔 if (str[1].compareTo("√") == 0) {// 这里为什么是1 String str1 = ""; int tmp = 0; for (int j = 2; j < str.length; j++) { str1 += str[j]; } double ans1 = Double.parseDouble(str1);// 这里转化一下 if (ans1 == 0) return "false"; if (ans1 == 1) return String.valueOf(ans1); dou = sb((int) ans1, sq((int) ans1), sc(3)); String result1 = String.valueOf(dou); return result1; } //1+2+3 Stack<Double> s = new Stack<Double>(); double m = Double.parseDouble(str[0]);// 第一个为数字,奇数为运算符,偶数为操作数 s.push(m); for (int i = 1; i < str.length; i++) { if (i % 2 == 1) { if (str[i].compareTo("+") == 0) { double help = Double.parseDouble(str[i + 1]); s.push(help); } if (str[i].compareTo("-") == 0) { double help = Double.parseDouble(str[i + 1]); s.push(-help); } if (str[i].compareTo("*") == 0) {// 1*2 double help = Double.parseDouble(str[i + 1]); double ans = s.peek();// 取出栈顶元素 s.pop();// 消栈 ans *= help; s.push(ans); } if (str[i].compareTo("/") == 0) { double help = Double.parseDouble(str[i + 1]); double ans = s.peek(); s.pop(); ans /= help; s.push(ans); } if (str[i].compareTo("%") == 0) { double help = Double.parseDouble(str[i + 1]); double ans = s.peek(); s.pop(); ans %= help; s.push(ans); } } } double ans = 0d; while (!s.isEmpty()) { ans += s.peek(); s.pop(); } String result = String.valueOf(ans); return result; } }
在实现的过程中遇到很多问题:
1.文本域如何添加滚动条
2.写文件时如何在之前的基础上追加内容(即不覆盖之前的内容)
3.如何创建选项卡面板(即标准界面和程序员界面)
4.各种数据类型之间的转换
5.用堆栈实现加减乘除
6.根号的计算方法
7.进制之间的转化
8.可变长数组的使用以及vector
9.窗口属性
10.利用System.out.println()做调试
之后把这些问题的解决方法再写一下,第十点不算问题吧,只是觉得这样调试比较方便。