当前位置: 首页 > 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 …...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

rm视觉学习1-自瞄部分

首先先感谢中南大学的开源&#xff0c;提供了很全面的思路&#xff0c;减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接&#xff1a;https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架&#xff1a; 代码框架结构&#xff1a;readme有…...

负载均衡器》》LVS、Nginx、HAproxy 区别

虚拟主机 先4&#xff0c;后7...