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()做调试
之后把这些问题的解决方法再写一下,第十点不算问题吧,只是觉得这样调试比较方便。
欢迎关注: