【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;}
剩下的大家自己研究吧。
相关文章:
【Java】Java使用Swing实现一个模拟计算器(有源码)
📝个人主页:哈__ 期待您的关注 今天翻了翻之前写的代码,发现自己之前还写了一个计算器,今天把我之前写的代码分享出来。 我记得那会儿刚学不会写,写的乱七八糟,但拿来当期末作业还是不错的哈哈。 直接上…...
MC9S12DJ64微控制器
这份文件是关于Freescale的MC9S12DJ64微控制器的用户指南,包含了关于该设备的详细信息和使用说明。以下是核心内容的整理: 产品信息: 产品信息详细描述如下: 1. **产品名称**:- MC9S12DJ64微控制器单元(MCU)2. **核心…...
小程序打开空白的问题处理
小程序打开是空白的,如下: 这个问题都是请求域名的问题: 一、检查服务器域名配置了 https没有,如果没有,解决办法是申请个ssl证书,具体看这里 https://doc.crmeb.com/mer/mer2/4257 二、完成第一步后&#…...
langchain + azure chatgpt组合配置并运行
首先默认你已经有了azure的账号。 最重要的是选择gpt-35-turbo-instruct模型、api_version:2023-05-15,就这两个参数谷歌我尝试了很久才成功。 我们打开https://portal.azure.com/#home,点击更多服务: 我们点击Azure OpenAI&#…...
【JVM性能调优】- GC调优实操思路
1、GC调优实操思路 前面几点所提及的都是GC调优的一些方法论以及衡量指标,但在真正需要处理GC调优时,上面几点只能给你提供辅导,并不能建立完善的调优思路,因此,接下来再一同论述GC调优的具体实操思想。 GC调优时&…...
四川教育装备行业协会考察团走访云轴科技ZStack共话技术创新应用
近日,四川省教育装备行业协会高等教育技术专业委员会组织了一次深入的考察活动,旨在加强与其他省市高校及企业之间的交流与合作,学习借鉴先进的教育装备与管理经验,以提升本省的高等教育技术水平。考察团一行先后走访了武汉理工大…...
KIVY 学习1
环境 python 3.6 3.7 对应Kivy 1.11.1版本各依赖 python -m pip install docutils pygments pypiwin32 kivy_deps.sdl20.1.22 kivy_deps.glew0.1.12 这是一个用于安装Python包的命令,它会安装一些特定的包。具体来说,这个命令会安装以下包: …...
在Go语言中使用select和channel来期待确定性行为
Go开发人员在使用channel时常犯的一个错误是,对select在多个channel中的行为方式做出错误的假设。错误的假设可能会导致难以识别和重现的细微错误。假设我们要实现一个需要从两个channel接收消息的goroutine: 我们可能会决定像下面这样处理优先级: for {select {case v := &…...
【MATLAB源码-第19期】matlab基于导频的OFDM系统瑞利信道rayleigh的信道估计仿真,输出估计与未估计误码率对比图。
1、算法描述 正交频分复用(英语:Orthogonal frequency-division multiplexing, OFDM)有时又称为分离复频调制技术(英语:discrete multitone modulation, DMT),可以视为多载波传输的一个特例&am…...
坚持十天做完Python入门编程100题第三天加班
坚持十天做完Python入门编程100题第三天加班 第24题 扫描文件列表第25题 如何将字典转换成JSON并写入json文件?第26题 JSON转换成字典 第24题 扫描文件列表 如何扫描当前目录下的文件列表?解析:可以使用python内置的glob模块,用法…...
MSOLSpray:一款针对微软在线账号(AzureO365)的密码喷射与安全测试工具
关于MSOLSpray MSOLSpray是一款针对微软在线账号(Azure/O365)的密码喷射与安全测试工具,在该工具的帮助下,广大研究人员可以直接对目标账户执行安全检测。支持检测的内容包括目标账号凭证是否有效、账号是否启用了MFA、租户账号是…...
uos安装lxml避坑记录
环境:紫光电脑uos系统 python:系统自带3.7.3 条件:已打开开发者模式,可以自行安装应用商店之外的软件 一、pip3 install lxml4.8.0可以正正常下载,但出现如下错误 另:为什么是4.8.0?因为这个…...
518. 零钱兑换 II(力扣LeetCode)
文章目录 518. 零钱兑换 II题目描述动态规划一维数组为什么不能交换两个for循环的顺序? 二维数组 518. 零钱兑换 II 题目描述 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数…...
01串的熵(蓝桥杯)
文章目录 01串的熵问题描述答案:11027421题意解释暴力枚举 01串的熵 问题描述 对于一个长度为n的01串 S x 1 x 2 x 3 x_{1}x_{2}x_{3} x1x2x3… x n x_{n} xn,香农信息熵的定义为 H(S) − ∑ 1 n p ( x i ) l o g 2 ( p ( x i ) ) -\sum _{1…...
Rust 基础语法和数据类型
数据类型 Rust提供了一系列的基本数据类型,包括整型(如i32、u32)、浮点型(如f32、f64)、布尔类型(bool)和字符类型(char)。此外,Rust还提供了原生数组、元组…...
【Java SE】10 String类
目录 1. String类的重要性 2.常用方法 2.1字符串构造 2.2 String对象的比较 2.3字符串查找 2.4转化 2.5字符串替换 2.6字符串拆分 2.7字符串截取 2.8其他操作方法 2.9字符串的不可变性 2.10字符串修改 3. StringBuffer和StringBuilder 3.1StringBuilder的介绍 4.…...
web蓝桥杯真题:新鲜的蔬菜
代码: .box {display: flex; } #box1 {align-items: center;justify-content: center; }#box2 {justify-content: space-between; } #box2 .item:nth-child(2) {align-self: end; }#box3 {justify-content: space-between; } #box3 .item:nth-child(2) {align-self…...
超声波清洗机能洗哪些东西?洗眼镜超声波清洗机推荐
在现代生活中,人们对清洁卫生的要求越来越高,尤其是对一些细小物件的清洁。眼镜作为我们日常生活中不可或缺的物品,清洁保养更是至关重要。传统的清洗方式可能无法完全清洁眼镜表面的细菌和污垢,于是超声波清洗机成为了很多人的选…...
[C++][算法基础]走迷宫(BFS)
给定一个 nm 的二维整数数组,用来表示一个迷宫,数组中只包含 0 或 1,其中 0 表示可以走的路,1 表示不可通过的墙壁。 最初,有一个人位于左上角 (1,1)(1,1) 处,已知该人每次可以向上、下、左、右任意一个方…...
C语言字符串左旋
一、前言 这个题目的完整题目是这样子的。 二、我们实现这个编程的思路 2.1暴力破解思想 假如有一个数组里面的字符串为”abcdef“,我们这时候就这样先将字符”a“移到最后再将其余的字符前移。 2.2三步移动法 同样我们还是假设一个数组里面存的是字符串”abcd…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
