当前位置: 首页 > news >正文

Java——一个简单的计算器程序

 

该代码是一个简单的计算器程序,使用了Java的图形化界面库Swing。具体分析如下:

  1. 导入必要的类和包:

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Objects;
    import javax.swing.*;
    

    代码中导入了用于创建图形界面的类和接口,以及其他必要的类。

  2. 定义Calculator类:

    public class Calculator extends JFrame implements ActionListener {// 类的成员变量和组件的定义
    }
    

    代码中定义了一个名为Calculator的类,继承了JFrame类,并实现了ActionListener接口。Calculator类是程序的主类,并包含了图形界面相关的成员变量和组件的定义。

  3. 初始化界面和组件:

    public Calculator() {// 界面和组件的初始化代码
    }
    

    在Calculator类的构造方法中,定义了计算器的界面布局,并创建了相关的各种组件,如按钮、文本域等,并设置它们的大小、位置和属性。

  4. 处理按钮事件:

    public void actionPerformed(ActionEvent e) {// 按钮事件的处理代码
    }
    

    Calculator类实现了ActionListener接口,重写了接口中的actionPerformed方法,用于处理按钮的点击事件。根据不同按钮的标签,在该方法中执行相应的操作,如进行计算、清空、显示历史记录等。

以上就是该代码的分析。它实现了一个简单的图形化计算器界面,并提供了一些基本的计算功能和历史记录功能。用户可以通过界面上的按钮进行输入和操作,并在文本域中显示结果和历史记录。

package ch5;import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Objects;import javax.swing.*;//Calculator类,继承JFrame框架,实现事件监听器接口
public class Calculator extends JFrame implements ActionListener {private final String[] KEYS = { "7", "8", "9", "AC", "4", "5", "6", "-", "1", "2", "3", "+", "0", "e", "pi", "/", "sqrt","%", "x*x", "*", "(", ")", ".", "=" };private JButton keys[] = new JButton[KEYS.length];private JTextArea resultText = new JTextArea("0.0");// 文本域组件TextArea可容纳多行文本;文本框内容初始值设为0.0private JTextArea History = new JTextArea();// 历史记录文本框初始值设为空private JPanel jp2=new JPanel();private JScrollPane gdt1=new JScrollPane(resultText);//给输入显示屏文本域新建一个垂直滚动滑条private JScrollPane gdt2=new JScrollPane(History);//给历史记录文本域新建一个垂直滚动滑条// private JScrollPane gdt3=new JScrollPane(History);//给历史记录文本域新建一个水平滚动滑条private JLabel label = new JLabel("历史记录");private String b = "";// 构造方法public Calculator() {super("Caculator");//“超”关键字,表示调用父类的构造函数,resultText.setBounds(20, 18, 255, 115);// 设置文本框大小resultText.setAlignmentX(RIGHT_ALIGNMENT);// 文本框内容右对齐resultText.setEditable(false);// 文本框不允许修改结果History.setBounds(290, 40, 250,370);// 设置文本框大小History.setAlignmentX(LEFT_ALIGNMENT);// 文本框内容右对齐History.setEditable(false);// 文本框不允许修改结果label.setBounds(300, 15, 100, 20);//设置标签位置及大小jp2.setBounds(290,40,250,370);//设置面板窗口位置及大小jp2.setLayout(new GridLayout());JPanel jp1 = new JPanel();jp1.setBounds(20,18,255,115);//设置面板窗口位置及大小jp1.setLayout(new GridLayout());resultText.setLineWrap(true);// 激活自动换行功能resultText.setWrapStyleWord(true);// 激活断行不断字功能resultText.setSelectedTextColor(Color.RED);History.setLineWrap(true);//自动换行History.setWrapStyleWord(true);History.setSelectedTextColor(Color.blue);gdt1.setViewportView(resultText);//使滚动条显示出来gdt2.setViewportView(History);gdt1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//设置让垂直滚动条一直显示gdt2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//设置让垂直滚动条一直显示gdt2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);//设置让水平滚动条一直显示jp1.add(gdt1);//将滚动条添加入面板窗口中jp2.add(gdt2);this.add(jp1);//将面板添加到总窗体中this.add(jp2);//将面板添加到总窗体中this.setLayout(null);this.add(label);// 新建“历史记录”标签//this.add(resultText);// 新建文本框,该语句会添加进去一个新的JTextArea导致带有滚动条的文本无法显示或者发生覆盖//this.add(History);// 新建历史记录文本框,该语句会添加进去一个新的JTextArea导致带有滚动条的文本无法显示// 放置按钮int x = 20, y = 150;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, 567, 480);this.setDefaultCloseOperation(EXIT_ON_CLOSE);this.setVisible(true);}// 事件处理public void actionPerformed(ActionEvent e){//History.setText(b);//使输入的表达式显示在历史记录文本框中String label=e.getActionCommand();//获得事件源的标签if(Objects.equals(label, "="))//{resultText.setText(this.b);History.setText(History.getText()+resultText.getText());if(label.equals("="))//调用计算方法,得出最终结果{String[] s =houzhui(this.b);String result=Result(s);this.b=result+"";//更新文本框,当前结果在字符串b中,并未删除,下一次输入接着此结果以实现连续运算resultText.setText(this.b);History.setText(History.getText()+"="+resultText.getText()+"\n");}}else if(Objects.equals(label, "AC"))//清空按钮,消除显示屏文本框前面所有的输入和结果{this.b="";resultText.setText("0");//更新文本域的显示,显示初始值;}else if(Objects.equals(label, "sqrt")){String n=kfys(this.b);resultText.setText("sqrt"+"("+this.b+")"+"="+n);//使运算表达式显示在输入界面History.setText(History.getText()+"sqrt"+"("+this.b+")"+"=");//获取输入界面的运算表达式并使其显示在历史记录文本框this.b=n;}else if(Objects.equals(label, "x*x")){String m=pfys(this.b);resultText.setText(this.b+"^2"+"="+m);//使运算表达式显示在输入界面History.setText(History.getText()+this.b+"^2"+"=");//获取输入界面的运算表达式并使其显示在历史记录文本框this.b=m;}else if(Objects.equals(label, "e") || Objects.equals(label, "pi")){if(label.equals("e")){String m=String.valueOf(2.71828);//将e的值以字符串的形式传给mthis.b=this.b+m;//保留显示m之前输入的运算符或数字字符继续下一步运算resultText.setText(this.b);// History.setText(History.getText()+this.b);}if(label.equals("pi")){String m=String.valueOf(3.14159265);this.b=this.b+m;resultText.setText(this.b);// History.setText(History.getText()+this.b);}}else{this.b=this.b+label;resultText.setText(this.b);// History.setText(History.getText()+this.b);}//History.setText(History.getText()+this.b);//使输入的表达式显示在历史记录文本框中}//将中缀表达式转换为后缀表达式private String[] houzhui(String str) {String s = "";// 用于承接多位数的字符串char[] opStack = new char[100];// 静态栈,对用户输入的操作符进行处理,用于存储运算符String[] postQueue = new String[100];// 后缀表达式字符串数组,为了将多位数存储为独立的字符串int top = -1, j = 0;// 静态指针top,控制变量jfor (int i = 0; i < str.length(); i++)// 遍历中缀表达式// indexof函数,返回字串首次出现的位置;charAt函数返回index位置处的字符;{if ("0123456789.".indexOf(str.charAt(i)) >= 0) // 遇到数字字符的情况直接入队{s = "";// 作为承接字符,每次开始时都要清空for (; i < str.length() && "0123456789.".indexOf(str.charAt(i)) >= 0; i++) {s = s + str.charAt(i);//比如,中缀表达式:234+4*2,我们扫描这个字符串的时候,s的作用相当于用来存储长度为3个字符的操作数:234}i--;postQueue[j] = s;// 数字字符直接加入后缀表达式j++;}else if ("(".indexOf(str.charAt(i)) >= 0) {// 遇到左括号top++;opStack[top] = str.charAt(i);// 左括号入栈}else if (")".indexOf(str.charAt(i)) >= 0) {// 遇到右括号for (;;)// 栈顶元素循环出栈,直到遇到左括号为止{if (opStack[top] != '(') {// 栈顶元素不是左括号postQueue[j] = opStack[top] + "";// 栈顶元素出栈j++;top--;} else { // 找到栈顶元素是左括号top--;// 删除栈顶左括号break;// 循环结束}}}else if ("*%/+-".indexOf(str.charAt(i)) >= 0)// 遇到运算符{if (top == -1){// 若栈为空则直接入栈top++;opStack[top] = str.charAt(i);}else if ("*%/".indexOf(opStack[top]) >= 0){// 当栈顶元素为高优先级运算符时,让栈顶元素出栈进入后缀表达式后,当前运算符再入栈postQueue[j] = opStack[top] + "";j++;opStack[top] = str.charAt(i);}else {top++;opStack[top] = str.charAt(i);// 当前元素入栈}}}while (top != -1) {// 遍历结束后将栈中剩余元素依次出栈进入后缀表达式postQueue[j] = opStack[top] + "";j++;top--;}return postQueue;}//开方运算方法public String kfys(String str) {String result = "";double a = Double.parseDouble(str), b = 0;b = Math.sqrt(a);result = String.valueOf(b);//将运算结果转换为string类型并赋给string类型的变量resultreturn result;}//平方运算方法public String pfys(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;// 静态指针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]);Top--;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);// 将运算结果重新入栈}}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);// 将运算结果重新入栈}}}return Result[Top];// 返回最终结果}// 主函数public static void main(String[] args) {Calculator a = new Calculator();}
}

 

相关文章:

Java——一个简单的计算器程序

该代码是一个简单的计算器程序&#xff0c;使用了Java的图形化界面库Swing。具体分析如下&#xff1a; 导入必要的类和包&#xff1a; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Objects; import javax.…...

自定义滑动到底部触发指令,elementUI实现分页下拉框

在 main.js 中添加 // 自定义滑动到底部指令 Vue.directive(selectLoadMore, {bind(el, binding) {// 获取element-ui定义好的scroll盒子const SELECTWRAP_DOM el.querySelector(.el-select-dropdown .el-select-dropdown__wrap)SELECTWRAP_DOM.addEventListener(scroll, fun…...

【Windows 常用工具系列 10 -- linux ssh登录脚本输入密码】

文章目录 脚本输入SSH登录密码scp 脚本免密传输 脚本输入SSH登录密码 sshpass 是一个用于运行时非交互式ssh密码提供的工具&#xff0c;它允许你直接在命令行中为ssh命令提供密码。这就意味着你可以在脚本中使用ssh命令&#xff0c;而不需要用户交互地输入密码。 一般来说&am…...

C#的索引器

索引器 在 C# 中&#xff0c;索引器&#xff08;Indexer&#xff09;是一种特殊的属性&#xff0c;允许通过类的实例像访问数组一样访问对象的元素。索引器允许将类的实例作为集合来使用&#xff0c;可以按照自定义的方式访问类中的元素。 索引器的定义类似于属性&#xff0c…...

软件配置安装(破解)--- maven下载配置

检查环境是否已有 首先检查一下电脑里有无maven环境&#xff0c;有的话就不用安装了 查看path环境中没有maven&#xff0c;开始准备接下来的重头戏 下载maven 下载bin.zip版 解压mavenxxxbin.zip &#xff08;建议把解压的文件放在一个文件夹内&#xff0c;命名英文的env…...

python解析小说

前言 在信息爆炸的时代&#xff0c;网络上充斥着大量的小说资源&#xff0c;让人们能够随时随地尽享阅读的乐趣。然而&#xff0c;有些小说网站要求用户付费才能获取完整的内容&#xff0c;这给许多人带来了困扰&#xff0c;尤其是像我这类对金钱概念模糊的人。不过&#xff0…...

SQL Server 执行报错: “minus“ 附近有语法错误。

sql server 执行带 minus 的语句一直报错&#xff0c;如下图&#xff1a; 找了好久才知道minus是Oracle里面的语法&#xff0c;SQL server 应用 EXCEPT。...

kali linux查看局域网下所有IP,并对指定IP攻击

kali linux查看局域网下所有IP&#xff0c;并对指定IP实施局域网内攻击 首先我们打开我们熟悉的kali linux操作系统&#xff0c;利用指令&#xff1a; ifconfig来确认本机的ip地址 确认了本机的ip地址之后&#xff0c;利用一下的指令查看局域网下所有ip: fping -g 本机IP地址…...

基于QCC_BES 平台的LMS自适应滤波算法实现

+我V hezkz17进数字音频系统研究开发交流答疑群(课题组) LMS算法是最小均方(Least Mean Square)算法的缩写。它是一种自适应滤波算法,常用于信号处理、系统辨识和自适应滤波等领域。 LMS算法的目标是通过对输入信号和期望输出信号之间的误差进行最小化,来调整滤波器的权重…...

大疆飞卡30运载无人机技术分享

大疆飞卡30是大疆公司面向运输领域推出的一款专业运载无人机。它采用了优秀的设计,装备了多种先进传感器,以解决运输中的难题。以下我们来了解一下其主要特点: 【应用领域】 飞卡30适用于山地救灾、农业化肥施用、工程材料运送等交通不便的山区应用,也适用于海岛联通等运输链…...

单片机的串口通信

今天&#xff0c;完整地总结一下普中科技的单片机的串口通信的硬件与编程&#xff0c;记录一下以后如果需要也比较方便捡起来。 单片机的串口部分的电路图。开发板上集成了 1 个串口通信电路&#xff0c;是 USB 转串口模块&#xff0c;它既可下载程序也可实现串口通信功能。 对…...

【C/C++】STL学习所得

文章目录 STL 框架核心组成部分STL 序列容器分类STL 容器适配器分类STL 迭代器分类STL 中一些易混淆知识点一些重要的简述 STL 框架核心组成部分 算法容器迭代器适配器空间配置器访函数 STL 序列容器分类 vectorqueuelistarrayforward_list STL 容器适配器分类 stack 栈qu…...

leetcode几个数组题

数组理论基础 数组是存放在连续内存空间上的相同类型数据的集合 因为数组的在内存空间的地址是连续的&#xff0c;所以我们在删除或者增添元素的时候&#xff0c;就难免要移动其他元素的地址 二分查找 移除元素 有序数组的平方 209.长度最小的子数组...

【LeetCode】模拟实现FILE以及认识缓冲区

模拟实现FILE以及认识缓冲区 刷新缓冲逻辑图自定义实现如何强制刷新内核缓冲区例子 刷新缓冲逻辑图 自定义实现 mystdio.h #pragma once #include <stdio.h>#define NUM 1024 #define BUFF_NOME 0x1 #define BUFF_LINE 0x2 #define BUFF_ALL 0x4typedef struct _MY_FIL…...

【Terraform学习】使用 Terraform 将 EC2 实例作为 Web 服务器启动(Terraform-AWS最佳实战学习)

使用 Terraform 将 EC2 实例作为 Web 服务器启动 实验步骤 前提条件 安装 Terraform&#xff1a; 地址 下载仓库代码模版 本实验代码位于 task_ec2 文件夹中。 变量文件 variables.tf 在上面的代码中&#xff0c;您将声明&#xff0c;aws_access_key&#xff0c;aws_secr…...

WebGL 变量uniform、gl.getUniformLocation、gl.uniform4f及其同族函数相关

目录 uniform变量命名规范 获取 uniform 变量的存储地址 gl.getUniformLocation 向uniform变量赋值 gl.uniform4f ​编辑 gl.uniform4f()的同族函数 demo&#xff1a;点击webgl坐标系的四个象限绘制各自不同颜色的点 uniform变量命名规范 var FSHADER_SOURCE uniform vec4…...

【Visual Studio】生成.i文件

环境 VS版本&#xff1a;VS2013 问题 如何生成.i预编译文件&#xff1f; 步骤 1、打开VS项目属性&#xff0c;打开C/C\预处理器页面&#xff0c;【预处理到文件】选择是&#xff0c;开启。 2、生成文件如下。 3、正常编译需要关闭此选项。...

本地生活服务平台加盟哪家公司好?

本地生活的竞争从年初的火热到现在&#xff0c;已经进入了下半场&#xff0c;随着优胜劣汰的筛选&#xff0c;那么直到现在&#xff0c;想做本地生活服务平台加盟&#xff0c;哪家公司比较好呢&#xff0c;应该如何选择呢&#xff1f; 首先我们得弄懂&#xff0c;我们加盟本地…...

css-grid使用

文章目录 grid概念容器和项目网格轨道&#xff1a;网格单元网格线 使用分配item空间大小对于子元素的意义 行列指定隐式和显示网格默认排列 grid容器属性grid-template-rows: 100px 100px 200px;grid-template-columns: 100px 100px 100px;grid-auto-rows: 200pxgrid-column-ga…...

springBoot提取一个List<?>中的某个字段集合

import cn.hutool.core.collection.CollUtil;PageResult prrecommendUserApi.queryRecommendUserList(dto.getPage(),dto.getPagesize(),userId);List<RecommendUser> items (List<RecommendUser>) pr.getItems(); //提取所有推荐的用户id List<Long> ids …...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

前端高频面试题2:浏览器/计算机网络

本专栏相关链接 前端高频面试题1&#xff1a;HTML/CSS 前端高频面试题2&#xff1a;浏览器/计算机网络 前端高频面试题3&#xff1a;JavaScript 1.什么是强缓存、协商缓存&#xff1f; 强缓存&#xff1a; 当浏览器请求资源时&#xff0c;首先检查本地缓存是否命中。如果命…...