本文讲述Java图形用户界面的编写,重点讲述一个简单计算器的实现。

文中程序的运行环境为Windows10 ,编译环境为MyEclipse 8.5。

一个简单的计算器主要实现一下功能和要求:

一:输入,输出

①输入:允许输入带有括号的完整计算式(例 6*(3+5)-5÷2)

②输出:输出Double类型的结果

二:功能

①:基本的加,减,乘,除,四则运算

②:平方运算

③:开方运算

最终界面如下图:

除了常规的数字按钮和运算符,还有两个常数e,π

主要思想:

一:输入,以及运算的实现

要实现完整计算式的输入并运算,就得用到计算后缀表达式的算法,和将中缀表达式转换为后缀表达式的算法(这里不再赘述中缀表达式和后缀表达式,以及之后有关栈的知识也不再多说,有兴趣可以阅读数据结构中关于栈的相关章节),这里重点讲解以上两个算法。

算法1(中缀表达式转后缀表达式):

因为计算式要在计算器的文本编辑框中显示,所以计算式用字符串记录(定义为字符串)

规则:从左向右遍历中缀表达式

①:遇到数字字符,直接加入后缀表达式

②:遇到高优先级运算符,若栈为空直接入栈,若栈不为空,则将当前运算符与栈顶元素比较

比较1(栈顶元素也为高优先级运算符):栈顶元素出栈加入后缀表达式,当前运算符入栈。这样的操作使得栈                                                                                     中不会出现连续的高优先级运算符

比较2(栈顶元素为'('左括号):将当前元素入栈

比较3(栈顶元素为低优先级运算符):将当前元素入栈

③:遇到'('左括号,将左括号入栈

④:遇到')'右括号,将栈顶元素顺序出栈,直到栈顶元素为左括号,此时删去栈顶的左括号

⑤:遇到低优先级运算符,若栈为空直接入栈,若栈不为空,则将当前运算符与栈顶元素比较

比较1(栈顶元素也为低优先级运算符):栈顶元素出栈加入后缀表达式,当前运算符入栈。这样的操作使得栈中                                                                                   不会出现连续的低优先级运算符

比较2(栈顶元素为'('左括号):将当前运算符入栈

比较③(栈顶元素为高优先级运算符):栈顶元素出栈加入后缀表达式,当前运算符入栈

程序段如下(代码段中的注释根据上述讲解过程书写,可以根据步骤阅读)

代码段中用到的某些函数注释:

indexof():String.indexof()方法搜索在该字符串上是否出现了作为参数传递的字符串,若找到字符串,则返回字符                                     串首字母的位置(0代表第一个位置),在下面的代码段中,为了判断字符类型用到了该方法。

String.valueof():将double类型的浮点数转换为字符串

Double.parseDouble():将字符串转化为double类型的浮点数

private String[] yunsuan(String str)
    {
        String s="";//用于承接多位数的字符串
        char a[]=new char[100];//静态的栈
        String jieguo[]=new String[100];//后缀表达式字符串数组,为了将多位数存储为独立的字符串
        int top=-1,j=0;//静态指针top,控制变量j
        for (int i=0;i<str.length();i++)//遍历中缀表达式
        {
            if ("0123456789.".indexOf(str.charAt(i))>=0)//indexof函数见上方注释,遇到数字字符的情况
            {
                s="";//作为承接的字符串,每次开始都要清空for (;i<str.length()&&"0123456789.".indexOf(str.charAt(i))>=0;i++)//将多位数存储在一个字符串中{s=s+str.charAt(i);}i--;jieguo[j]=s;//数字字符直接加入后缀表达式j++;
            }
            else if ("(".indexOf(str.charAt(i))>=0)//遇到左括号
            {
                top++;
                a[top]=str.charAt(i);//左括号入栈
            }
            else if (")".indexOf(str.charAt(i))>=0)//遇到右括号
            {
                for (;;)//栈顶元素循环出栈,直到找到左括号为止
                {
                    if (a[top]!='(')//栈顶元素不是左括号
                    {
                        jieguo[j]=a[top]+"";//栈顶元素出栈
                        j++;
                        top--;
                    }
                    else//找到栈顶元素是左括号
                    {
                        top--;//删除栈顶的左括号
                        break;//循环结束
                    }
                }
            }
            else if ("*%÷".indexOf(str.charAt(i))>=0)//遇到高优先级运算符
            {
                if (top==-1)//若栈为空直接入栈
                {
                    top++;
                    a[top]=str.charAt(i);
                }
                else//栈不为空
                {
                    if ("*%÷".indexOf(a[top])>=0)//栈顶元素也为高优先级运算符
                    {
                        jieguo[j]=a[top]+"";//栈顶元素出栈进入后缀表达式
                        j++;
                        a[top]=str.charAt(i);//当前运算符入栈
                    }
                    else if ("(".indexOf(a[top])>=0)//栈顶元素为左括号,当前运算符入栈
                    {
                        top++;
                        a[top]=str.charAt(i);
                    }
                    else if ("+-".indexOf(a[top])>=0)//栈顶元素为低优先级运算符,当前运算符入栈
                    {
                        top++;
                        a[top]=str.charAt(i);
                    }
                }
            }
            else if ("+-".indexOf(str.charAt(i))>=0)//遇到低优先级运算符
            {
                if (top==-1)//栈为空直接入栈
                {
                    top++;
                    a[top]=str.charAt(i);
                }
                else//栈不为空
                {
                    if ("%*÷".indexOf(a[top])>=0)//栈顶元素为高优先级运算符
                    {
                        jieguo[j]=a[top]+"";//栈顶元素出栈加入后缀表达式
                        j++;
                        a[top]=str.charAt(i);//当前运算符入栈
                    }
                    else if ("(".indexOf(a[top])>=0)//栈顶元素为左括号
                    {
                        top++;
                        a[top]=str.charAt(i);//当前运算符入栈
                    }
                    else if ("+-".indexOf(a[top])>=0)//栈顶元素也为低优先级运算符
                    {
                        jieguo[j]=a[top]+"";//栈顶元素出栈进入后缀表达式
                        j++;
                        a[top]=str.charAt(i);//当前元素入栈
                    }
                }
            }
        }
        for (;top!=-1;)//遍历结束后将栈中剩余元素依次出栈进入后缀表达式
        {
            jieguo[j]=a[top]+"";
            j++;
            top--;
        }
        return jieguo;
    }

算法2:计算后缀表达式

计算后缀表达式依然借助栈来实现

运算规则:遍历后缀表达式

①:遇到数字字符,直接入栈

②:遇到运算符,顺序出栈两个元素(数字),进行运算,将运算结果入栈

循环以上步骤最终栈中剩下的那个数字就是最终答案

程序段如下:
 public String Result(String str[]){String Result[]=new String[100];//顺序存储的栈,数据类型为字符串int Top=-1;//静态指针Topfor (int i=0;str[i]!=null;i++)//遍历后缀表达式{if ("+-*%÷".indexOf(str[i])<0)//遇到数字字符进栈{Top++;Result[Top]=str[i];}if ("+-*%÷".indexOf(str[i])>=0)//遇到运算符{double x,y,n;x=Double.parseDouble(Result[Top]);//顺序出栈两个数字字符串,并转换为double类型的数字Top--;y=Double.parseDouble(Result[Top]);//顺序出栈两个数字字符串,并转换为double类型的数字Top--;if ("-".indexOf(str[i])>=0)//一下步骤根据运算符来进行运算{n=y-x;Top++;Result[Top]=String.valueOf(n);//将运算结果重新入栈}if ("+".indexOf(str[i])>=0){n=y+x;Top++;Result[Top]=String.valueOf(n);}if ("*".indexOf(str[i])>=0){n=y*x;Top++;Result[Top]=String.valueOf(n);}if ("÷".indexOf(str[i])>=0){if (x==0)//不允许被除数为0{String s="ERROR";return s;}else{n=y/x;Top++;Result[Top]=String.valueOf(n);}}if ("%".indexOf(str[i])>=0){if (x==0)//不允许被除数为0{String s="ERROR";return s;}else{n=y%x;Top++;Result[Top]=String.valueOf(n);}}}}return Result[Top];//返回最终结果}

算法3:开方运算

程序段如下(调用了Math.sqrt()函数实现)
public String yunsuan2(String str){String result="";double a=Double.parseDouble(str),b=0;b=Math.sqrt(a);result=String.valueOf(b);return result;}

算法4:平方运算

程序段如下(调用了Math.pow()函数实现)
public String yunsuan3(String str){String result="";double a=Double.parseDouble(str),b=0;b=Math.pow(a, 2);result=String.valueOf(b);return result;}

界面设计:

一:框架

本计算器是基于Swing组建的图形用户界面,采用JFrame框架作为主窗口

public class Calculator extends JFrame implements ActionListener

类名Calculator(计算器),继承JFrame框架,实现事件监听器接口

二:文本行,按钮

整个计算器界面,可以随意发挥,我编写的界面最终的样子在文章开头有图片

计算器类中,定义的成员有:

①private String[] KEYS={"7","8","9","*","4","5","6","-","1","2","3","+","0","e","π","÷","c","%",".","=","(",")","sqr","x*x"};
    ② private JButton keys[]=new JButton[KEYS.length];
    ③private JTextField resultText = new JTextField("0.0");
    ④private String b="";

①:按钮标签字符串

②:定义按钮数组

③:定义文本行

④:用于存放计算式

构造方法代码段如下(计算器的整体界面完成)

public Calculator(){super("计算器");this.setLayout(null);//未采用任何类型的布局,后面的文本框和按钮显示位置都是自己计算好的位置resultText.setBounds(20, 5, 255, 40);//设置文本框大小resultText.setHorizontalAlignment(JTextField.RIGHT);//文本框内容右对齐resultText.setEditable(false);//文本框不允许修改结果this.add(resultText);//新建文本框int x=20,y=55;for (int i=0;i<KEYS.length;i++)//放置按钮{keys[i] = new JButton();keys[i].setText(KEYS[i]);keys[i].setBounds(x, y, 60, 40);if(x<215){x+=65;}else{x = 20;y+=45;}this.add(keys[i]);}for (int i = 0; i <KEYS.length; i++) //每个按钮都注册事件监听器{keys[i].addActionListener(this);}this.setResizable(false);this.setBounds(500, 200, 300, 400);this.setDefaultCloseOperation(EXIT_ON_CLOSE);this.setVisible(true);}

事件处理(以下代码用同一个字符串来记录计算式和结果,保证了计算式可以连续计算)

public void actionPerformed(ActionEvent e)//处理事件{String label = e.getActionCommand(); //获得事件源的标签if (label=="c"||label=="=")//按钮C清空文本框,消除前面所有的输入和结果{if(label=="=")//按钮=得出最终结果,调用计算方法{String s[]=yunsuan(this.b);String result=Result(s);this.b=result+"";resultText.setText(this.b);//更新文本框,当前结果在字符串b中,并未删除,下一次输入是接着这个结果的,这样可以实现连续运算}else{this.b="";resultText.setText("0");//更新文本域的显示,显示初始值}}else if (label=="sqr")//sqr 按钮计算开方{String n=yunsuan2(this.b);resultText.setText(n);this.b=n;}else if(label=="x*x")//x*x按钮实现某个数的平方{String m=yunsuan3(this.b);resultText.setText(m);this.b=m;}else if(label=="e"||label=="π"){if (label=="e")//常数e{String m=String.valueOf(2.71828);this.b=this.b+m;resultText.setText(this.b);}if (label=="π")//常数π{String m=String.valueOf(3.14159265);this.b=this.b+m;resultText.setText(this.b);}}else{this.b=this.b+label;resultText.setText(this.b);}}

计算器已经完成,完整代码如下:

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Calculator extends JFrame implements ActionListener
{private String[] KEYS={"7","8","9","*","4","5","6","-","1","2","3","+","0","e","π","÷","c","%",".","=","(",")","sqr","x*x"};private JButton keys[]=new JButton[KEYS.length];private JTextField resultText = new JTextField("0.0");private String b="";public Calculator(){super("计算器");this.setLayout(null);resultText.setBounds(20, 5, 255, 40);resultText.setHorizontalAlignment(JTextField.RIGHT);resultText.setEditable(false);this.add(resultText);int x=20,y=55;for (int i=0;i<KEYS.length;i++){keys[i] = new JButton();keys[i].setText(KEYS[i]);keys[i].setBounds(x, y, 60, 40);if(x<215){x+=65;}else{x = 20;y+=45;}this.add(keys[i]);}for (int i = 0; i <KEYS.length; i++) {keys[i].addActionListener(this);}this.setResizable(false);this.setBounds(500, 200, 300, 400);this.setDefaultCloseOperation(EXIT_ON_CLOSE);this.setVisible(true);}public void actionPerformed(ActionEvent e){String label = e.getActionCommand(); if (label=="c"||label=="="){if(label=="="){String s[]=yunsuan(this.b);String result=Result(s);this.b=result+"";resultText.setText(this.b);}else{this.b="";resultText.setText("0");}}else if (label=="sqr"){String n=yunsuan2(this.b);resultText.setText(n);this.b=n;}else if(label=="x*x"){String m=yunsuan3(this.b);resultText.setText(m);this.b=m;}else if(label=="e"||label=="π"){if (label=="e"){String m=String.valueOf(2.71828);this.b=this.b+m;resultText.setText(this.b);}if (label=="π"){String m=String.valueOf(3.14159265);this.b=this.b+m;resultText.setText(this.b);}}else{this.b=this.b+label;resultText.setText(this.b);}}private String[] yunsuan(String str){String s="";char a[]=new char[100];String jieguo[]=new String[100];int top=-1,j=0;for (int i=0;i<str.length();i++){if ("0123456789.".indexOf(str.charAt(i))>=0){s="";for (;i<str.length()&&"0123456789.".indexOf(str.charAt(i))>=0;i++){s=s+str.charAt(i);}i--;jieguo[j]=s;j++;}else if ("(".indexOf(str.charAt(i))>=0){top++;a[top]=str.charAt(i);}else if (")".indexOf(str.charAt(i))>=0){for (;;){if (a[top]!='('){jieguo[j]=a[top]+"";j++;top--;}else{top--;break;}}}else if ("*%÷".indexOf(str.charAt(i))>=0){if (top==-1){top++;a[top]=str.charAt(i);}else{if ("*%÷".indexOf(a[top])>=0){jieguo[j]=a[top]+"";j++;a[top]=str.charAt(i);}else if ("(".indexOf(a[top])>=0){top++;a[top]=str.charAt(i);}else if ("+-".indexOf(a[top])>=0){top++;a[top]=str.charAt(i);}}}else if ("+-".indexOf(str.charAt(i))>=0){if (top==-1){top++;a[top]=str.charAt(i);}else{if ("%*÷".indexOf(a[top])>=0){jieguo[j]=a[top]+"";j++;a[top]=str.charAt(i);}else if ("(".indexOf(a[top])>=0){top++;a[top]=str.charAt(i);}else if ("+-".indexOf(a[top])>=0){jieguo[j]=a[top]+"";j++;a[top]=str.charAt(i);}}}}for (;top!=-1;){jieguo[j]=a[top]+"";j++;top--;}return jieguo;}public String yunsuan2(String str){String result="";double a=Double.parseDouble(str),b=0;b=Math.sqrt(a);result=String.valueOf(b);return result;}public String yunsuan3(String str){String result="";double a=Double.parseDouble(str),b=0;b=Math.pow(a, 2);result=String.valueOf(b);return result;}public String Result(String str[]){String Result[]=new String[100];int Top=-1;for (int i=0;str[i]!=null;i++){if ("+-*%÷".indexOf(str[i])<0){Top++;Result[Top]=str[i];}if ("+-*%÷".indexOf(str[i])>=0){double x,y,n;x=Double.parseDouble(Result[Top]);Top--;y=Double.parseDouble(Result[Top]);Top--;if ("-".indexOf(str[i])>=0){n=y-x;Top++;Result[Top]=String.valueOf(n);}if ("+".indexOf(str[i])>=0){n=y+x;Top++;Result[Top]=String.valueOf(n);}if ("*".indexOf(str[i])>=0){n=y*x;Top++;Result[Top]=String.valueOf(n);}if ("÷".indexOf(str[i])>=0){if (x==0){String s="ERROR";return s;}else{n=y/x;Top++;Result[Top]=String.valueOf(n);}}if ("%".indexOf(str[i])>=0){if (x==0){String s="ERROR";return s;}else{n=y%x;Top++;Result[Top]=String.valueOf(n);}}}}return Result[Top];}public static void main(String arg[]){Calculator a=new Calculator();}
}

该计算器功能有限,只限于日常生活的使用,可以改进的方向很多

一:实现带符号数的运算,例如:-6-6

二:实现复数运算

三:实现多次方的运算

四:实现一元一次方程的运算

五:实现一元二次方程的运算

以上改进方向只是一小部分,对于有一些编程基础的人,可以尝试一下,对于大神这就是小儿科了。

欢迎读者评论,共同交流,共同进步。

Java语言编写计算器相关推荐

  1. java语言编写计算器_第二次作业利用java语言编写计算器进行四则运算

    随着第一次作业的完成,助教 牛老师又布置了第二次作业:用java语言编写一个程序然后进行四则运算用户用键盘输入一个字符来结束程序显示统计结果.一开始看到这个题目我也着实吓了一跳 因为不知道如何下手而且 ...

  2. java写便签_如何编写一个便签程序(用Java语言编写)

    如何编写一个便签程序(用Java语言编写) 热度:336   发布时间:2011-02-18 11:44:16 如何编写一个便签程序(用Java语言编写) 因为以前没有好好学习Java,都搞忘了,请大 ...

  3. jdbc是java语言编写的类和接口_JDBC——Java语言连接数据库的标准

    JDBC概述 API JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Jav ...

  4. 用Java语言编写的随机彩色验证码

    在制作网页过程中,免不了在登录注册页面增加一个验证码来延长数据提交时间,以免大量用户过快连接数据库读取,写入数据导致服务器崩溃.以下是用Java语言编写的彩色验证码,可用于jsp.html文件. 源代 ...

  5. 使用Java语言编写一个五子棋UI界面并实现网络对战功能(非局域网)

    使用Java语言编写一个五子棋UI界面并实现网络对战功能(非局域网) 一,前期准备 1,Java IDE(Eclipse)与JDK的安装与配置 jdk-15.0.1-免配置路径版 提取码:earu 免 ...

  6. 利用Java语言编写一个猜数字游戏(有次数限制)

    猜数字小游戏. 利用Java语言编写. 题目: 用代码模拟猜数字的小游戏. 思路: 1.首先需要产生一个随机数字,并且一旦产生不再变化.用Random的nextInt方法 2.需要键盘输入,所以用到了 ...

  7. java语言开发手机游戏_手机上的JAVA游戏和JAVA软件,是电脑上的JAVA语言编写的吗?他们之间有什么联系...

    手机上的JAVA游戏和JAVA软件,是电脑上的JAVA语言编写的吗?他们之间有什么联系以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起 ...

  8. 用java语言编写程序计算九宫图

    前言 对于程序员来说,用程序解决数学问题是最有趣的事情之一.本人研究了一个能够轻易计算九宫图的算法,并且用java语言编写程序得以实现.现将算法和代码公布,欢迎广大程序爱好者前来阅读.交流. 九宫图简 ...

  9. java开发的图片管理系统,一个使用Java语言编写的Web本地照片管理系统

    jAlbum 这是一个使用Java语言编写的本地照片管理系统.使用BS架构.服务端采用Servlet提供RESTful风格接口和动态页面供浏览器直接访问,集成照片Exif信息处理.视频流信息处理和人像 ...

最新文章

  1. 在互联网公司说女生备孕,就像跟你女朋友说你不行一个性质!
  2. 谷歌最新财报:平均每天入账5个亿,还是不及预期;皮猜:未来靠云+AI
  3. 中国平安:杀进智能合约,你怕不怕?
  4. 在Xcode6中添加prefix.pch文件
  5. GacUI基本概念(二)——排版(2)
  6. ajax c 提交form,使用ajax提交form表单,包括ajax文件上传
  7. mysql用大白话解释_Java基础--2021Java面试题系列教程--大白话解读
  8. NOIP2017年11月9日赛前模拟
  9. 【数据库题型大总结】简答题总结
  10. Swift-EasingAnimation
  11. nginx 根据目录指定root_CentOS(7.6)基本操作与Nginx配置
  12. php判断搜索引擎来路,php实现判断访问来路是否为搜索引擎机器人的方法
  13. 【2019杭电多校第八场1011=HDU6667】Roundgod and Milk Tea(贪心)
  14. bzoj2442codevs4654[Usaco2011 Open]修剪草坪
  15. CNN结构:色彩特征提取-色彩属性HSV空间(色彩冷暖初始)
  16. 我们写APP和小程序或者H5用的前端UI--ColorUI
  17. 显卡驱动与cuda、cudnn之间的关系
  18. 史上最简SLAM零基础解读(7) - Jacobian matrix(雅可比矩阵) → 理论分析与应用详解(Bundle Adjustment)
  19. 我参加了资金盘培训,get了这些“知识点”
  20. kali安装步骤失败 选择并安装软件_PhotoShop CC2015软件下载+安装详细步骤

热门文章

  1. Word2016查找和替换通配符(完全版)
  2. 整理:对开发者有用的英文网站合集
  3. 突发!微软亚研CV大牛王井东离职,或将加入百度
  4. revit中在三维视图下显示房间文字和“房间集成”
  5. photoshop插画插件_一键生成2.5D风格插画的PS插件
  6. 用C语言编辑得到的利息,存款利息的计算 有1000元,想存5年,可按以下5种办法存:...
  7. Summary of Statistics for Interview
  8. canvas画布的基础用法
  9. 蓝桥杯每日一练专栏导读
  10. 实车采集的数据重建场景_苹果地图经过新一轮数据采集,重建后的它会颠覆果粉想象吗?...