【Java】Java使用Swing实现一个模拟计算器(有源码)

  📝个人主页:哈__

期待您的关注 

今天翻了翻之前写的代码,发现自己之前还写了一个计算器,今天把我之前写的代码分享出来。

 我记得那会儿刚学不会写,写的乱七八糟,但拿来当期末作业还是不错的哈哈。

直接上源码,后上讲解。

一、源码

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import java.util.function.ToDoubleBiFunction;public class MyCalculator  {private JFrame frame=new JFrame("CSDN--哈__");private String[] keys = {"%","C","CE","Back","1⁄x","X²","√x","÷","7","8","9","X","4","5","6","-","1","2","3","+","+/-","0",".","="};//计算器的功能键保存private JButton [] buttons=new JButton[keys.length];//创建按钮private JTextField resultText=new JTextField("0");//结果保存用于在计算器上显示private double resultNum =0.0000;//用于保存运算的结果private boolean firstDigit=true;//判断是否是第一个输入的数字,或者是运算符后第一个数字private String operate ="=";//记录当前的运算符private boolean opearteValidFlag =true;//判断当前输入是否合法//构造函数public MyCalculator(){frame.setLocation(300,200);frame.setSize(new Dimension(366,439));frame.setVisible(true);frame.setResizable(true);//窗口大小可修改//这里采用awt组件来关闭窗口  事件监听frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosed(WindowEvent e) {System.exit(0);}});}public void init(){//先定义三种颜色 用于背景板的填充  数值为网上查找Color c1=new Color(181,181,181);Color c2=new Color(126,192,238);Color c3=new Color(232,232,232);//计算器功能面板初始化JPanel pText =new JPanel();//用于保存文本域JPanel pKey =new JPanel();//用于保存功能按键//对文本域进行初始化pText.setLayout(new BorderLayout());pText.add(resultText);resultText.setFont(new Font("楷体",Font.BOLD,43));//设置文本框中字体的格式resultText.setHorizontalAlignment(JTextField.RIGHT);//文本框默认右对齐resultText.setEditable(false);//文本域不可编辑resultText.setBorder(null);//设置边框为无resultText.setBackground(c1);//对功能案件进行初始化pKey.setLayout(new GridLayout(6,4,2,2)); //六行四列,相邻两个按钮上下间隔均为两个像素//开始在按键区加入前八个功能键for (int i = 0; i < 8; i++) {buttons[i]=new JButton(keys[i]);pKey.add(buttons[i]);buttons[i].setBackground(c3);buttons[i].setForeground(Color.BLACK);buttons[i].setFont(new Font(Font.SERIF,Font.PLAIN,18));buttons[i].setBorderPainted(false);//设置无边框buttons[i].addActionListener(myActionListener);//添加监听器}for (int i = 8; i < keys.length; i++) {buttons[i]=new JButton(keys[i]);pKey.add(buttons[i]);if((i+1)%4==0)  buttons[i].setBackground(c3);else buttons[i].setBackground(Color.white);buttons[i].setForeground(Color.BLACK);buttons[i].setFont(new Font(Font.SERIF,Font.PLAIN,18));buttons[i].setBorderPainted(false);//设置无边框buttons[i].addActionListener(myActionListener);//添加监听器}//最后将=号的背景色改为蓝色,也就是c2buttons[keys.length-1].setBackground(c2);pKey.setBackground(c1);frame.add(pText,BorderLayout.NORTH);frame.add(pKey);/* pText.setBorder(BorderFactory.createMatteBorder(25,3,1,3,c1));pKey.setBorder(BorderFactory.createMatteBorder(6,3,3,3,c1));*/}public class MyActionListener implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {String key = e.getActionCommand();//对于具有清除删除功能按键的处理(CE C BACK)if(key.equals(keys[1])||key.equals(keys[2])||key.equals(keys[3])){doDeleteKey(key);}//对只需要一个数值的按键处理(% 1/x x² √x  +/-  )else if(key.equals(keys[0])||key.equals(keys[4])||key.equals(keys[5])||key.equals(keys[6])||key.equals(keys[20])){doOperator1(key);}//对需要两个数值的按键的处理(÷ X - += )else if(key.equals(keys[7])||key.equals(keys[11])||key.equals(keys[15])||key.equals(keys[19])||key.equals(keys[23])){doOperator2(key);}//对数字按键进行处理(1 2 3 4 5 6 7 8 9 .)else{doNumberKey(key);}}}private void doDeleteKey(String key){if(key.equals("CE")){resultText.setText("0");}else if(key.equals("C")){resultText.setText("0");resultNum=0.0000;firstDigit=true;opearteValidFlag=true;operate="=";}else{String text=resultText.getText();if(text.length()>1){resultText.setText(text.substring(0,text.length()-1)); //如果内容长度大于1,那么直接删掉最后一个字符}else{//内容长度等于1resultText.setText("0");firstDigit=true;}}}private void doOperator1(String key){//对只需要一个数值的按键处理(% 1/x x² √x  +/-  )operate=key;if(operate.equals("%")){resultNum=getNumFromText()/100;}else if(operate.equals("1⁄x")){if(getNumFromText()==0){//System.out.println("0没有倒数!");resultText.setText("零没有倒数!");opearteValidFlag=false;}else{resultNum=resultNum+1.0/getNumFromText();}}else if(operate.equals("√x")){if(getNumFromText()<0){//System.out.println("负数不能开方!");resultText.setText("负数不能开方!");opearteValidFlag=false;}else{resultNum=resultNum+Math.sqrt(getNumFromText());}}else if(operate.equals("X²")){resultNum=resultNum+getNumFromText()*getNumFromText();}else if(key.equals("+/-")){resultNum=-getNumFromText();firstDigit=true;opearteValidFlag=true;}}//两个数进行运算 ÷ X - + =private void doOperator2(String key){if(operate.equals("÷")){if(getNumFromText()==0){//System.out.println("零不能做除数!");resultText.setText("零不能做除数!");opearteValidFlag=false;}else{resultNum/=getNumFromText();}}else if(operate.equals("X")){resultNum*=getNumFromText();}else if(operate.equals("+")){resultNum+=getNumFromText();}else if(operate.equals("-")){resultNum-=getNumFromText();}else if(operate.equals("=")){resultNum=getNumFromText();}if(opearteValidFlag){long t1=(long)resultNum;double t2=resultNum-t1;if(t2==0){resultText.setText(String.valueOf(t1));}else{resultText.setText(String.valueOf(new DecimalFormat("0.0000").format(resultNum)));}}operate=key;firstDigit=true;opearteValidFlag=true;}private void doNumberKey(String key){//如果是第一个输入的数字或者符号后第一个数字if(firstDigit){if(key.equals(".")) /*resultText.setText(resultText.getText()+".");*/{//上来直接按.  if(resultNum==0&&operate=="=") resultText.setText(resultText.getText()+".");//上来先按了个别的运算符 在按.else{resultText.setText("0.");// resultText.setText("出错!");//opearteValidFlag=false;}}else resultText.setText(key);}else if(key.equals(".")&&resultText.getText().indexOf(".")<0){resultText.setText(resultText.getText()+".");}else if(!key.equals(".")){resultText.setText(resultText.getText()+key);}firstDigit=false;}private double getNumFromText(){double result = 0;try {result = Double.valueOf(resultText.getText()).doubleValue();} catch (NumberFormatException e) {}return result;}MyActionListener myActionListener=new MyActionListener();public static void main(String[] args) {new MyCalculator().init();}
}

二、讲解

1、创建我们所需的变量

计算器上的按键不少,我们都定义在一个keys数组当中,并且初始化一个buttons按钮数组。

除了我们的按钮之外,还有我们的输出显示窗口resultText,输出的结果我们都用resultNum来记录,之后在放到我们的输出窗口上。

其他的都写成注解了。

private JFrame frame=new JFrame("CSDN--哈__");private String[] keys = {"%","C","CE","Back","1⁄x","X²","√x","÷","7","8","9","X","4","5","6","-","1","2","3","+","+/-","0",".","="};//计算器的功能键保存private JButton [] buttons=new JButton[keys.length];//创建按钮private JTextField resultText=new JTextField("0");//结果保存用于在计算器上显示private double resultNum =0.0000;//用于保存运算的结果private boolean firstDigit=true;//判断是否是第一个输入的数字,或者是运算符后第一个数字private String operate ="=";//记录当前的运算符private boolean opearteValidFlag =true;//判断当前输入是否合法

2.面板初始化

面板初始化就是init方法,注释我都写了,这里不在讲了,也没啥重要的,就是美化一下面板。

3.添加按钮事件监听机制

当我们点击计算机上的按钮的时候,计算器要给出反馈,这时就需要我们添加一个事件监听机制了。注释写好了,当我们点击不同的按钮的时候要处理不同的功能。

 public class MyActionListener implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {String key = e.getActionCommand();//对于具有清除删除功能按键的处理(CE C BACK)if(key.equals(keys[1])||key.equals(keys[2])||key.equals(keys[3])){doDeleteKey(key);}//对只需要一个数值的按键处理(% 1/x x² √x  +/-  )else if(key.equals(keys[0])||key.equals(keys[4])||key.equals(keys[5])||key.equals(keys[6])||key.equals(keys[20])){doOperator1(key);}//对需要两个数值的按键的处理(÷ X - += )else if(key.equals(keys[7])||key.equals(keys[11])||key.equals(keys[15])||key.equals(keys[19])||key.equals(keys[23])){doOperator2(key);}//对数字按键进行处理(1 2 3 4 5 6 7 8 9 .)else{doNumberKey(key);}}}

4.处理对于具有清除删除功能按键的处理(CE C BACK)

计算器上有个清空按键C大家都用过吧,点了这个C之后我们所有的输入都会被初始化。倘若点了退格键那我们就把面板上的文字域删掉一个符号。比如我们输入的是111,点了退格之后就是11,当然你会想这只是文字域的变化,那我们保存的要计算的值为什么不变?别着急,真正开始计算是在我们点击了加减乘除这一类的符号的时候才会从面板读取值的。

 private void doDeleteKey(String key){if(key.equals("CE")){resultText.setText("0");}else if(key.equals("C")){resultText.setText("0");resultNum=0.0000;firstDigit=true;opearteValidFlag=true;operate="=";}else{String text=resultText.getText();if(text.length()>1){resultText.setText(text.substring(0,text.length()-1)); //如果内容长度大于1,那么直接删掉最后一个字符}else{//内容长度等于1resultText.setText("0");firstDigit=true;}}}

5.两个数进行运算加减乘除

上来先判断你当前的的符号是什么,并且也进行了一些错误情况的判断,如除数不能为0什么的。

下边你就能看到我们的resultNum被使用了。最后来个操作是否合法判断,如果合法并且输出结果最后是0那我们直接就把0输出到面板上,但是倘若我们的输出结果有精度差,那我们就得自己将0放到面板上了。

注:我使用的浮点数计算并不是BigDecimal,所以存在精度差。

private void doOperator2(String key){if(operate.equals("÷")){if(getNumFromText()==0){//System.out.println("零不能做除数!");resultText.setText("零不能做除数!");opearteValidFlag=false;}else{resultNum/=getNumFromText();}}else if(operate.equals("X")){resultNum*=getNumFromText();}else if(operate.equals("+")){resultNum+=getNumFromText();}else if(operate.equals("-")){resultNum-=getNumFromText();}else if(operate.equals("=")){resultNum=getNumFromText();}if(opearteValidFlag){long t1=(long)resultNum;double t2=resultNum-t1;if(t2==0){resultText.setText(String.valueOf(t1));}else{resultText.setText(String.valueOf(new DecimalFormat("0.0000").format(resultNum)));}}operate=key;firstDigit=true;opearteValidFlag=true;}

 剩下的大家自己研究吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/807155.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣404,左叶子之和

404. 左叶子之和 已解答 简单 相关标签 相关企业 给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 示例 1&#xff1a; 输入: root [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中&#xff0c;有两个左叶子&#xff0c;分别是 9 和 15&#xff0c;…

C:数据结构之链栈(不带头)

目录 前序 准备工作 函数声明 函数接口 1.初始化 2.创造节点 3. 判断栈空 4.入栈 5.出栈 6.取栈顶元素 7.销毁栈 8. 获取栈的元素个数 总结 前序 链栈是基于单链表实现的,其实栈更加适合使用顺序表来实现的,这篇文章我们来探讨一下链栈的实现。 准备工作 老规…

透视 Insilico 英矽智能:AI 制药明星企业的飞跃、困境与破局

衰老&#xff0c;从古至今困扰了无数仁人志士。无论是千古一帝秦始皇&#xff0c;还是雄才大略汉武帝&#xff0c;亦或者挥斥方遒唐太宗&#xff0c;这些伟大的帝王无一例外的都留下了许多追求长生的故事。当时光的指针落在了 21 世纪的第二个十年&#xff0c;随着全球老龄化问…

【c++】string类常见接口函数

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好啊&#xff0c;本节我们来到STL内容的第一部分&#xff1a;string类接口函数的介绍 目录 1.string类的认识2.常见接口讲解2.1 string类对象的常见构造2.2 对string对象的遍历和…

Jackson解析Json数据

1.概述 Jackson 和 FastJson 一样&#xff0c;是一个 Java 语言编写的&#xff0c;可以进行 JSON 处理的开源工具库&#xff0c;Jackson 的使用非常广泛&#xff0c;Spring 框架默认使用 Jackson 进行 JSON 处理。 Jackson 有三个核包&#xff0c;分别是 Streaming、Databid、…

【实战JVM】类的生命周期

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

百度OCR身份证识别C++离线SDKV3.0 C#对接

百度OCR身份证识别C离线SDKV3.0 C#对接 目录 说明 效果 问题 项目 代码 下载 说明 自己根据SDK封装了动态库&#xff0c;然后C#调用。 SDK 简介 本 SDK 适应于于 Windows 平台下的⾝份证识别系统,⽀持 C接⼜开发的 SDK,开发者可在VS2015 下⾯进⾏开发&#xff08;推荐…

推荐学习什么编程语言?

选择编程语言学习时&#xff0c;除了就业因素外&#xff0c;还可以考虑以下几个方面来决定学习哪些编程语言&#xff1a; 个人兴趣与目标&#xff1a;如果你对某个特定领域感兴趣&#xff0c;比如游戏开发、数据分析、人工智能等&#xff0c;可以选择与该领域紧密相关的编程语言…

Altair® Access™ 面向研究人员和工程师的 HPC 作业提交门户

Altair Access™ 面向研究人员和工程师的 HPC 作业提交门户 Access 具有一个简单、强大且统一的界面&#xff0c;可以从中提交和监控远程集群、云或其他资源的相关作业&#xff0c;使工程师和研究人员能够专注于主要活动&#xff0c;减少在应用程序运行及数据移动上投入的时间。…

搭建第一个Web服务器(在eclipse或idea上部署Tomcat服务器)

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

2024年ERP软件上中下游结构分析及细分行业研究

环洋咨询Global Info Research的ERP软件市场调研报告提供ERP软件市场的基本概况&#xff0c;包括定义&#xff0c;分类&#xff0c;应用和产业链结构&#xff0c;同时还讨论发展政策和计划以及制造流程和成本结构&#xff0c;分析ERP软件市场的发展现状与未来市场趋势&#xff…

nandgame中的条件判断EQ(== 相等)、GT、LT、NOT、GOTO、IF_GOTO

相等从堆栈中弹出两个顶部值并进行比较。 如果它们相等&#xff0c;则推送值-1&#xff08;十六进制中的FFFF&#xff09;。 否则推送0。在条件语句中&#xff0c;FFFF代表真&#xff0c;0代表假。示例 之前 之后 堆栈 堆栈 7 0 8 结果如下&#xff1a; 代码 POP_D POP_A…

AI大模型探索之路-应用篇8:Langchain框架LangServe模块-专注于AI模型的部署

目录 前言 一、概述 二、功能特性 三、REST API 开发 四、Postman调用测试 五、Client调用测试 总结 前言 随着AI大语言模型&#xff08;LLM&#xff09;的技术的不断演进&#xff0c;AI应用的开发和部署变得越来越复杂。在这样的背景下&#xff0c;LangServe应运而生—…

设计模式——2_7 状态(State)

欲买桂花同载酒&#xff0c;终不似&#xff0c;少年游 ——刘过《唐多令芦叶满汀州》 文章目录 定义图纸一个例子&#xff1a;如何模拟一个转笔刀自动转笔刀PencilPencilSharpener 投诉和改善钝刀BladePencilSharpener 没有铅笔PencilSharpener if if ifStatePencilSharpener 碎…

48-基于腾讯云EKS的容器化部署实战

准备工作 在部署IAM应用之前&#xff0c;我们需要做以下准备工作&#xff1a; 开通腾讯云容器服务镜像仓库。安装并配置Docker。准备一个Kubernetes集群。 开通腾讯云容器服务镜像仓库 在Kubernetes集群中部署IAM应用&#xff0c;需要从镜像仓库下载指定的IAM镜像&#xff…

亚马逊、速卖通、lazada测评自养号与机刷有何区别?

在亚马逊平台&#xff0c;买家评价的重要性无需多言。许多消费者在决定购买产品前&#xff0c;都会习惯性地查看相关评论&#xff0c;对比同类产品的买家反馈&#xff0c;从而做出更明智的选择。正因如此&#xff0c;测评成为各大电商平台不可或缺的一种推广策略&#xff0c;亚…

C++ 模拟实现 STL 中的 set、map 与 multiset、multimap

目录 一&#xff0c;RB_tree 的实现 1&#xff0c;RB_tree 的节点与数据结构 2&#xff0c;RB_tree 的迭代器 3&#xff0c;RB_tree 的构造 4&#xff0c;RB_tree 的元素操作 5&#xff0c;完整代码 二&#xff0c;set 与 multiset 的实现 1&#xff0c;set 2&#x…

从零开始:Elasticsearch简介与详解

大家好,我是小米,今天我来和大家聊一聊阿里巴巴面试题中常见的一个话题:Elasticsearch。作为一名喜欢分享技术的小伙伴,我深知在技术的道路上,多一份了解就多一份优势。那么,让我们一起来探索一下Elasticsearch的特点、功能、场景以及与竞品的对比分析吧! 特点 特点是…

js爬虫puppeteer库 解决网页动态渲染无法爬取

我们爬取这个网址上面的股票实时部分宇通客车(600066)_股票价格_行情_走势图—东方财富网 我们用正常的方法爬取会发现爬取不下来&#xff0c;是因为这个网页这里是实时渲染的&#xff0c;我们直接通过网址接口访问这里还没有渲染出来 于是我们可以通过下面的代码来进行爬取: …

1. VirtualBox安装CentOS

安装 VirtualBox 地址:https://www.virtualbox.org/wiki/Downloads 版本: 6.1和7.0+版本都可以 安装: windows上安装需要admin权限,右键菜单选中 “Run as administrator” 安装 CentOS 6.10 地址:https://vault.centos.org/6.10/isos/x86_64/ 版本: 如果不需要GUI,选择…