Java程序设计——编写计算器

news2024/11/15 2:05:00

 设计主类

Calculator

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.0
    private 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的值以字符串的形式传给m
                this.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,控制变量j
        for (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类型的变量result
        return 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;// 静态指针Top
        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]);// 顺序出栈两个数字字符串,并转换为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();
    }
}

然后运行 

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

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

相关文章

如何快速制作一个房地产电子传单?

在如今高度数字化的时代&#xff0c;电子传单成为了宣传推广的一种重要方式。下面将介绍如何利用乔拓云平台快速制作一个房地产电子传单。 第一步&#xff0c;找一个可靠的第三方制作平台/工具&#xff0c;比如乔拓云平台。乔拓云平台是一个功能强大、简单易用的电子传单制作工…

SpringBoot+微信小程序奶茶在线点单小程序系统 附带详细运行指导视频

文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码 一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBoot微信小程序框架开发的奶茶在线点单小程序系统。首先&#xff0c;这是一个前后端分离的项目&#xff…

2023年,IT人都在追寻什么样的科技和技术?

摘要&#xff1a; 随着科技的不断发展&#xff0c;IT领域也在以惊人的速度发展。每年都会有新的技术和趋势出现&#xff0c;成为IT人士关注和追逐的对象。那么&#xff0c;在2023年&#xff0c;IT人都在追寻什么样的科技和技术呢&#xff1f;本文将探索2023年IT 人士最热衷的科…

SpringBoot---内置Tomcat 配置和切换

&#x1f600;前言 本篇博文是关于内置Tomcat 配置和切换&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&#x…

4 STM32标准库函数 之 FLASH存储器(FLASH)所有函数的介绍及使用

3 STM32标准库函数 之 FLASH存储器所有函数的介绍及使用 1. 图片有格式2 文字无格式二、FLASH 库函数固件库函数预览2.1 函数FLASH_SetLatency2.2 函数FLASH_HalfCycleAccessCmd2.3 函数FLASH_PrefetchBufferCmd2.4 函数FLASH_Unlock2.5 函数FLASH_Lock2.6 函数FLASH_ErasePage…

LeetCode 2236. 判断根结点是否等于子结点之和

【LetMeFly】2236.判断根结点是否等于子结点之和 力扣题目链接&#xff1a;https://leetcode.cn/problems/root-equals-sum-of-children/ 给你一个 二叉树 的根结点 root&#xff0c;该二叉树由恰好 3 个结点组成&#xff1a;根结点、左子结点和右子结点。 如果根结点值等于…

【数据分析入门】Matplotlib

目录 零、图形解析与工作流0.1 图形解析0.2 工作流 一、准备数据1.1 一维数据1.2 二维数据或图片 二、绘制图形2.1 画布2.2 坐标轴 三、绘图例程3.1 一维数据3.2 向量场3.3 数据分布3.4 二维数据或图片 四、自定义图形4.1 颜色、色条与色彩表4.2 标记4.3 线型4.4 文本与标注4.5…

Zoho CRM有哪些特点?

企业想要选择一款CRM系统&#xff0c;只看CRM公司排名或CRM厂商排名可以吗&#xff1f;其实&#xff0c;选型时的误区就是盲目选择大品牌&#xff0c;反而忽略了CRM和业务的适配度&#xff0c;毕竟适合的才是最好的。。 Zoho CRM是一款国际知名的SaaS云端CRM系统&#xff0c;面…

阿里云访问端口被限制解决方法记录

阿里云服务器&#xff0c;80端口可以访问&#xff0c;但是加入了安全组端口8080 通过公网访问改端口策略&#xff0c;发现不能被访问 问题出在防火墙&#xff0c;需要重置一下 解决方法&#xff1a; 在运行的服务器上执行如下命令&#xff1a; # iptables -A INPUT -j ACCEP…

23年9月到24年3月苹果产品发布

2023年到2024年的苹果产品发布 9月 基本就是手机&#xff0c;4款&#xff1a;15、15plus、15pro、15pro max 手表和ipodmini 10月就是新的M3芯片&#xff0c;至于M pro芯片会放在24年的3月份。 其他的就没什么新意了

课程项目设计--项目设计--宿舍管理系统--vue+springboot完成项目--项目从零开始

写在前面&#xff1a; 本文是从项目设计到完成开始写的&#xff0c;本来这个项目基础功能是做完了的&#xff0c;但是之前时间紧张想从头做起了。之前一周写前端后端累死了. 设计是关键&#xff0c;这一篇主讲设计。可能后面会有修改&#xff0c;本人实力有限&#xff0c;如有…

【微信小程序】下拉刷新功能实现

微信小程序开发系列 文章目录 前言一、onPullDownRefresh函数二、实现1.开启下拉刷新2.监听下拉事件 前言 在开发微信小程序中经常会需要下拉页面进行更新要页面数据的功能&#xff0c;微信小程序提供了onPullDownRefresh函数。该函数作用是监听用户下拉动作。 一、onPullDown…

【多线程】 —— 线程池

文章目录 1、什么是线程池&#xff0c;线程池有哪些&#xff08;创建&#xff09;(1) newCachedThreadPool(2) newFixedThreadPool(3) newSingleThreadExecutor(4) newScheduleThreadPool 2、为什么要使用线程池&#xff1f;3、线程池底层工作原理4、ThreadPoolExecutor 对象有…

【剖析STL】vector

vector的介绍及使用 1.1 vector的介绍 cplusplus.com/reference/vector/vector/ vector是表示可变大小数组的序列容器。就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问&#xff0c;和数组一样高效。但是…

激活函数总结(十四):激活函数补充(Gaussian 、GCU、ASU)

激活函数总结&#xff08;十四&#xff09;&#xff1a;激活函数补充 1 引言2 激活函数2.1 Gaussian 激活函数2.2 Growing Cosine Unit (GCU)激活函数2.3 Amplifying Sine Unit (ASU)激活函数 3. 总结 1 引言 在前面的文章中已经介绍了介绍了一系列激活函数 (Sigmoid、Tanh、R…

AI绘画之三_StableDiffusion_界面操作

1 介绍 首先&#xff0c;介绍界面中的重要元素&#xff0c;如图所示&#xff1a; 基础模型&#xff1a;基础模型是最重要的设置项文生图&#xff1a;选项卡列出了各大功能&#xff0c;文生图指通过文字生成图片图生图&#xff1a;图生图指通过图片和文字生成图片修复照片&am…

LLM大模型生产部署的12个最佳实践

大型语言模型 (LLM) 彻底改变了自然语言处理和理解领域&#xff0c;实现了跨各个领域的广泛人工智能应用。 然而&#xff0c;在生产中部署 LLM 应用程序也面临着一系列挑战。 从解决自然语言的歧义到管理成本和延迟&#xff0c;有几个因素需要仔细考虑。 推荐&#xff1a;用 NS…

腾讯云轻量应用服务器配置(详细版)

腾讯云轻量应用服务器CPU内存带宽配置高&#xff0c;成本很低&#xff0c;腾讯云百科来详细说下腾讯云服务器从购买、配置到网站上线全流程&#xff0c;包括轻量服务器配置选择、应用镜像选择、重置密码、防火墙开放端口教程等详细教程&#xff1a; 目录 一&#xff1a;注册腾…

jsp 网络社区便利店系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 网络社区便利店系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.…