简易计算器-课后程序(JAVA基础案例教程-黑马程序员编著-第十一章-课后作业)

news2025/1/13 9:31:29

【案例11-2】 简易计算器

【案例介绍】

1.案例描述

本案例要求利用Java Swing 图形组件开发一个可以进行简单的四则运算的图形化计算器。

2.运行结果

运行结果

 

【案例分析】

要制作一个计算器,首先要知道它由哪些部分组成,如下图所示:

一个简单的图形化界面计算器,需要由界面组件、组件的时间监听器和具体的事件处理逻辑组成。

实现一个简易图形化界面计算器可分以下几个步骤:

1.UI组件创建和初始化:包括窗体的创建,显示计算结果文本框、清除按钮、数字按钮、运算符等按钮的初始化。

2.在窗体中添加UI组件:包括放置数字键及运算符面板、放置清除框面板。

3.布局结束之后,就是计算器的难点:编写事件处理程序。

4.按键的响应实现。

5.计算逻辑的实现。

6.注册监听器

【案例实现】

Calculator.java

  1. package chapter1102;
  2. import java.awt.*;
  3. import java.awt.event.*;
  4. import javax.swing.*;
  5. import java.util.Vector;
  6. import java.math.BigDecimal;
  7. public class Calculator {
  8.           // 操作数1,为了程序的安全,初值一定设置,这里我们设置为0
  9.           String str1 = "0";
  10.          // 操作数2
  11.      String str2 = "0";
  12.      // 运算符
  13.     String signal = "+";  
  14.      // 运算结果
  15.     String result = "";
  16.      // 以下k1k5为状态开关
  17.      // 开关1用于选择输入方向,将要写入str1str2
  18.      // 1 时写入 str1,为 2 时写入 str2
  19.     int k1 = 1;
  20.     // 开关 2 用于记录符号键的次数
  21.      // 如果 k2>1 说明进行的是 2+3-9+8 这样的多符号运算
  22.     int k2 = 1;
  23.      // 开关3用于标识 str1 是否可以被清 0
  24.      // 等于 1 时可以,不等于1时不能被清0
  25.     int k3 = 1;
  26.      // 开关4用于标识 str2 是否可以被清 0
  27.      // 等于 1 时可以,不等于1时不能被清0
  28.     int k4 = 1;
  29.      // 开关5用于控制小数点可否被录入
  30.      // 等于1时可以,不为1时,输入的小数点被丢掉
  31.     int k5 = 1;
  32.      // store的作用类似于寄存器,用于记录是否连续按下符号键
  33.     JButton store;
  34.      //vt 存储之前输入的运算符。
  35.     @SuppressWarnings("rawtypes")
  36.     Vector vt = new Vector(20, 10);
  37.      // 创建一个 JFrame 对象并初始化。JFrame 可以理解为程序的主窗体。  
  38.      JFrame frame = new JFrame("Calculator");
  39.  //创建一个JTextField对象并初始化。JTextField用于显示操作和计算结果的文本框。
  40.      // 参数 20 表明可以显示 20 列的文本内容
  41.     JTextField result_TextField = new JTextField(result, 20);
  42.      // 清除按钮
  43.     JButton clear_Button = new JButton("Clear");
  44.      // 数字键09
  45.     JButton button0 = new JButton("0");
  46.     JButton button1 = new JButton("1");
  47.     JButton button2 = new JButton("2");
  48.     JButton button3 = new JButton("3");
  49.     JButton button4 = new JButton("4");
  50.     JButton button5 = new JButton("5");
  51.     JButton button6 = new JButton("6");
  52.     JButton button7 = new JButton("7");
  53.     JButton button8 = new JButton("8");
  54.     JButton button9 = new JButton("9");
  55.      // 计算命令按钮,加减乘除以及小数点等
  56.     JButton button_Dian = new JButton(".");
  57.     JButton button_jia = new JButton("+");
  58.     JButton button_jian = new JButton("-");
  59.     JButton button_cheng = new JButton("*");
  60.     JButton button_chu = new JButton("/");
  61.     JButton button_dy = new JButton("=");
  62.     public Calculator() {
  63.         button0.setMnemonic(KeyEvent.VK_0);
  64.     result_TextField.setHorizontalAlignment(JTextField.RIGHT);
  65.         // 创建一个 Jpanel 对象并初始化
  66.          JPanel pan = new JPanel();
  67.          // 设置该容器的布局为四行四列,边距为5像素
  68.         pan.setLayout(new GridLayout(4, 4, 5, 5));
  69.          // 将用于计算的按钮添加到容器内
  70.         pan.add(button7);
  71.         pan.add(button8);
  72.         pan.add(button9);
  73.         pan.add(button_chu);
  74.         pan.add(button4);
  75.         pan.add(button5);
  76.         pan.add(button6);
  77.         pan.add(button_cheng);
  78.         pan.add(button1);
  79.         pan.add(button2);
  80.         pan.add(button3);
  81.         pan.add(button_jian);
  82.         pan.add(button0);
  83.         pan.add(button_Dian);
  84.         pan.add(button_dy);
  85.         pan.add(button_jia);
  86.          // 设置 pan 对象的边距
  87.         pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
  88.          // 按照同样的方式设置第二个JPanel
  89.         JPanel pan2 = new JPanel();
  90.         pan2.setLayout(new BorderLayout());
  91.         pan2.add(result_TextField, BorderLayout.WEST);
  92.         pan2.add(clear_Button, BorderLayout.EAST);
  93.           // 设置主窗口出现在屏幕上的位置
  94.         frame.setLocation(300, 200);
  95.          // 设置窗体可以调大小
  96.         frame.setResizable(true);
  97.          //窗体中可以放置 JPanel,这里我们将面板pan和面板pan2让如窗体
  98.         frame.getContentPane().setLayout(new BorderLayout());
  99.         frame.getContentPane().add(pan2, BorderLayout.NORTH);
  100.         frame.getContentPane().add(pan, BorderLayout.CENTER);
  101.         frame.pack();
  102.         frame.setVisible(true);
  103.          //Listener类中编写的是数字键的响应逻辑。
  104.         class Listener implements ActionListener {
  105.            @SuppressWarnings("unchecked")
  106.            public void actionPerformed(ActionEvent e) {
  107.                String ss = ((JButton) e.getSource()).getText();
  108.                store = (JButton) e.getSource();
  109.                vt.add(store);
  110.                if (k1 == 1) {
  111.                    if (k3 == 1) {
  112.                        str1 = "";
  113.                        k5 = 1;
  114.                    }
  115.                    str1 = str1 + ss;
  116.                    k3 = k3 + 1;
  117.                    result_TextField.setText(str1);
  118.                } else if (k1 == 2) {
  119.                    if (k4 == 1) {
  120.                        str2 = "";
  121.                        k5 = 1;
  122.                }
  123.                    str2 = str2 + ss;
  124.                    k4 = k4 + 1;
  125.                    result_TextField.setText(str2);
  126.                }                              
  127.            }
  128.         }
  129.           //Listener_signal类中编写了运算符号键的响应逻辑
  130.         class Listener_signal implements ActionListener {
  131.            @SuppressWarnings("unchecked")
  132.            public void actionPerformed(ActionEvent e) {
  133.                String ss2 = ((JButton) e.getSource()).getText();
  134.                store = (JButton) e.getSource();
  135.                vt.add(store);
  136.                if (k2 == 1) {
  137.                    k1 = 2;
  138.                    k5 = 1;
  139.                    signal = ss2;
  140.                    k2 = k2 + 1;
  141.                } else {
  142.                    int a = vt.size();
  143.                    JButton c = (JButton) vt.get(a - 2);
  144.                    if (!(c.getText().equals("+"))
  145.                            && !(c.getText().equals("-"))
  146.                            && !(c.getText().equals("*"))
  147.                            && !(c.getText().equals("/")))
  148.                    {
  149.                        cal();
  150.                        str1 = result;
  151.                        k1 = 2;
  152.                        k5 = 1;
  153.                        k4 = 1;
  154.                        signal = ss2;
  155.                    }
  156.                    k2 = k2 + 1;
  157.                }
  158.            }
  159.         }
  160.      //Listener_clear类中编写了清除键的响应逻辑
  161.     class Listener_clear implements ActionListener {
  162.            @SuppressWarnings("unchecked")
  163.            public void actionPerformed(ActionEvent e) {
  164.                store = (JButton) e.getSource();
  165.                vt.add(store);
  166.                k5 = 1;
  167.                k2 = 1;
  168.                k1 = 1;
  169.                k3 = 1;
  170.                k4 = 1;
  171.                str1 = "0";
  172.                str2 = "0";
  173.                signal = "";
  174.                result = "";
  175.                result_TextField.setText(result);
  176.                vt.clear();
  177.            }
  178.         }
  179.      //Listener_dy类中编写的是等于号键的响应逻辑
  180.     class Listener_dy implements ActionListener {
  181.            @SuppressWarnings("unchecked")
  182.            public void actionPerformed(ActionEvent e) {
  183.                store = (JButton) e.getSource();
  184.                vt.add(store);
  185.                cal();
  186.                k1 = 1;
  187.                k2 = 1;
  188.                k3 = 1;
  189.                k4 = 1;
  190.                str1 = result;
  191.            }
  192.         }
  193. //Listener_xiaos类中编写的是小数点键的相应逻辑
  194. class Listener_xiaos implements ActionListener {
  195.            @SuppressWarnings("unchecked")
  196.            public void actionPerformed(ActionEvent e) {
  197.                store = (JButton) e.getSource();
  198.                vt.add(store);
  199.                if (k5 == 1) {
  200.                    String ss2 = ((JButton) e.getSource()).getText();
  201.                    if (k1 == 1) {
  202.                        if (k3 == 1) {
  203.                            str1 = "";
  204.                            k5 = 1;
  205.                        }
  206.                        str1 = str1 + ss2;
  207.                        k3 = k3 + 1;
  208.                        result_TextField.setText(str1);
  209.                    } else if (k1 == 2) {
  210.                        if (k4 == 1) {
  211.                            str2 = "";
  212.                            k5 = 1;
  213.                        }
  214.                        str2 = str2 + ss2;
  215.                        k4 = k4 + 1;
  216.                        result_TextField.setText(str2);
  217.                    }
  218.                }
  219.                k5 = k5 + 1;
  220.            }
  221.         }
  222.           // 监听等于键
  223.         Listener_dy jt_dy = new Listener_dy();
  224.          // 监听数字键
  225.         Listener jt = new Listener();
  226.          // 监听符号键
  227.         Listener_signal jt_signal = new Listener_signal();
  228.          // 监听清除键
  229.         Listener_clear jt_c = new Listener_clear();
  230.          // 监听小数点键
  231.         Listener_xiaos jt_xs = new Listener_xiaos();
  232.         button7.addActionListener(jt);
  233.         button8.addActionListener(jt);
  234.         button9.addActionListener(jt);
  235.         button_chu.addActionListener(jt_signal);
  236.         button4.addActionListener(jt);
  237.         button5.addActionListener(jt);
  238.         button6.addActionListener(jt);
  239.         button_cheng.addActionListener(jt_signal);
  240.         button1.addActionListener(jt);
  241.         button2.addActionListener(jt);
  242.         button3.addActionListener(jt);
  243.         button_jian.addActionListener(jt_signal);
  244.         button0.addActionListener(jt);
  245.         button_Dian.addActionListener(jt_xs);
  246.         button_dy.addActionListener(jt_dy);
  247.         button_jia.addActionListener(jt_signal);
  248.         clear_Button.addActionListener(jt_c);
  249.           // 窗体关闭事件的响应程序
  250.         frame.addWindowListener(new WindowAdapter() {
  251.            public void windowClosing(WindowEvent e) {
  252.                System.exit(0);
  253.            }
  254.         });
  255.     }
  256.      // calc()方法中编写了计算逻辑的实现。
  257.     public void cal() {
  258.         double a2;
  259.         double b2;
  260.         String c = signal;
  261.         double result2 = 0;
  262.         if (c.equals("")) {
  263.            result_TextField.setText("Please input operator");
  264.         } else {
  265.            if (str1.equals("."))
  266.                str1 = "0.0";
  267.            if (str2.equals("."))
  268.                str2 = "0.0";
  269.            a2 = Double.valueOf(str1).doubleValue();
  270.            b2 = Double.valueOf(str2).doubleValue();
  271.            if (c.equals("+")) {
  272.                result2 = a2 + b2;
  273.            }
  274.            if (c.equals("-")) {
  275.                result2 = a2 - b2;
  276.            }
  277.            if (c.equals("*")) {
  278.                BigDecimal m1 = new BigDecimal(Double.toString(a2));
  279.                    BigDecimal m2 = new
  280.                                     BigDecimal(Double.toString(b2));
  281.                    result2 = m1.multiply(m2).doubleValue();
  282.            }
  283.            if (c.equals("/")) {
  284.                if (b2 == 0) {
  285.                    result2 = 0;
  286.                } else {
  287.                    result2 = a2 / b2;
  288.                }
  289.            }
  290.            result = ((new Double(result2)).toString());
  291.            result_TextField.setText(result);
  292.         }
  293.     }
  294.     @SuppressWarnings("unused")
  295.     public static void main(String[] args) {
  296.     try {  
  297.  //通过 UIManager 来设置窗体的 UI 风格
  298.  UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
  299.         } catch (Exception e) {
  300.            e.printStackTrace();
  301.         }
  302.         Calculator cal = new Calculator();
  303.     }
  304. }

上述代码中,第7-32行代码,定义了一些成员变量,方便响应的逻辑实现。第34-35行代码,创建了一个Vector对象,存储之前输入的运算符。第37行代码,创建了一个 JFrame 对象并初始化。JFrame 可以理解为程序的主窗体。第40行代码,创建了一个JTextField对象并初始化。JTextField用于显示操作和计算结果的文本框。参数 20 表明可以显示 20 列的文本内容。第42行代码,创建了一个清除按钮对象。第44-53行,创建数字键0-9按钮对象。第55-60行,创建计算命令按钮,加减乘除以及小数点等按钮对象。第65-101行代码,是对计算器进行布局。Listener类中编写的是数字键的响应逻辑。Listener_xiaos类中编写的是小数点键的相应逻辑。Listener_signal类中编写了运算符号键的响应逻辑。Listener_dy类中编写的是等于号键的响应逻辑。Listener_clear类中编写了清除键的响应逻辑。calc()方法中编写了计算逻辑的实现。第222-247行代码,创建监听对象,斌对各个按键进行监听。第249-253行代码,为窗体关闭事件的响应程序。第297行代码,通过 UIManager 来设置窗体的 UI 风格。

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

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

相关文章

见山,见路,见天地:OpenHarmony的开源共建攀登

自诞生之日起,OpenHarmony就引起着各方的关注,可谓是盛况空前。但一款开源操作系统的成功,困难不在第一步,而是第一步后面的一万步。那么,踏出开源第一步之后的OpenHarmony,后面的故事如何发展了呢&#xf…

(五十三)大白话基于主键的索引是如何设计的,以及如何根据主键索引查询?

上回我们说了数据页分裂的过程,在你不停的往表里灌入数据的时候,会搞出来一个一个的数据页,如果你的主键不是自增的,他可能会有一个数据行的挪动过程,保证你下一个数据页的主键值都大于上一个数据页的主键值。 在这个…

开启MySQL慢查询以及慢查询日志使用

目录 要开启慢查询,需要关注这几个参数 打开慢查询日志 把日志文件存储在文件中 模拟慢查询 如何寻找并查看慢查询日志 把日志文件存储在表中: 其他关注参数 log_slow_admin_statements Slow_queries 在生产环境中:mysqldumpslow工具分…

问题与解决办法整理一

文章目录1. Linux报错:terminate called after throwing an instance of ‘std::regex_error‘ what(): regex_error;[regex报错,需要将G,GCC都要升级才可以](https://blog.csdn.net/qq_56101220/article/details/127371121)2. ctemplate时遇到连接库失败的问题,将l…

redis(12)持久化操作-RDB

前言 Redis 提供了 2 个不同形式的持久化方式: RDB(Redis DataBase) AOF(Append Of File) RDB 在指定的时间间隔内将内存中的数据集快照写入磁盘, 也就是行话讲的 Snapshot 快照,它恢复时是将快照文件直接读到内存里。 备份是如何执行的 Re…

自动化测试框架/工具选择

单元测试(白盒测试) XUnit等(一般开发自己做) 接口自动化测试(灰盒测试) soapUI,优点:上手快 缺点:商业工具 postMan:chrome插件 优点:免费 缺点:用例管理…

深入了解Apache InLong和重点理解Sort的应用

深入了解Apache InLong和重点理解Sort的应用一、产品优势二、产品架构三、模块四、已支持数据节点五、基本概念六、Agent 插件七、Sort插件八、Manager 插件九、DataProxy插件十、重点理解Sort的应用1.支持多种数据节点2.安装部署3.启动 InLong Sort 任务4.MySQL to PostgreSQL…

数据库——3.数据库的设计规范(实用版)

前面也出过一篇文章,那篇文章里面详细介绍了数据库的设计规范,包括方方面面的内容。说实话,其实里面好多东西都是一种习惯的问题,用不用都影响不大,只要知道那个概念,遇见时能理解,需要时会使用…

云原生可观察性工具泛滥的思考

前言 对于采用容器环境和kubernetes的公司来说,可观察性正变得越来越重要。CNCF最近的一份报告发现,72%的受访者使用了多达9种不同的工具来监控他们的云原生环境和应用程序。当然,如果不使用足够的监控工具,可能会导致隐藏的安全…

【链表OJ题(一)】移除链表元素

​ ​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:数据结构 🎯长路漫漫浩浩,万事皆有期待 文章目录链表OJ题(一)1. 移除…

FreeRTOS入门(06):任务通知

文章目录目的基础说明使用演示作为二进制信号量作为计数信号量作为事件组作为队列或邮箱相关函数总结目的 任务通知(TaskNotify)是RTOS中相对常用的用于任务间交互的功能,这篇文章将对相关内容做个介绍。 本文代码测试环境见前面的文章&…

「JVM 高效并发」锁优化

为了线程间更高效的共享数据及解决竞争问题,提高程序执行效率,JDK 6 做了大量锁优化,如适应性自旋(Adaptive Spinning)、锁消除(Lock Elimination)、锁膨胀(Lock Coarsening&#xf…

2、监控界面设计

【任务描述】本任务要求使用相对布局或约束布局以及相应的控件完成智慧园区监控系统界面开发一、相对布局(RelativeLayout)概述相对布局(RelativeLayout)是一种根据父容器和兄弟控件作为参照来确定控件位置的布局方式。使用相对布…

《机器学习》- 习题解析 - 第一章

《机器学习》- 习题 - 第一章 文章目录《机器学习》- 习题 - 第一章一、示例-计算表1.1中的版本空间二、习题 1 - 计算题目中的版本空间三、单个合取式&析合范式的概念四、习题 2 - 计算题目中假设空间的规模大小一、示例-计算表1.1中的版本空间 首先从概念上理解版本空间…

一起玩转开源数据库!OceanBase DevCon 之开源生态全景解析

​ 2023 年 3 月 25 日,首次 OceanBase 开发者大会将在北京举办,OceanBase 首席科学家阳振坤与 OceanBase CTO 杨传辉领携众多技术专家,将与开发者共同探讨单机分布式、云原生、HTAP 等数据库前沿趋势,OceanBase 开源技术全景生…

数据库——1.数据库设计的三大范式

这篇文章我们主要来讲一下数据库设计的三大范式,这个还是很有用的。 目录 1.概述 2.第一范式 3.第二范式 4.第三范式 5.小结 1.概述 为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范…

Python每日一练(20230301)

目录 1. 只出现一次的数字 2. 以特殊格式处理连续增加的数字 3. 最短回文串 1. 只出现一次的数字 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 说明: 你的算法应该具有线性…

「TCG 规范解读」基础设施架构和协议 (2)

可信计算组织(Ttrusted Computing Group,TCG)是一个非盈利的工业标准组织,它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立,并采纳了由可信计算平台联盟(the Trusted Computing Platform Alli…

有什么好用的在线统计表单吗?

有什么好用的在线统计表单吗?最好是免费的?市面上这样的表单工具其实很多,先来看看题主的需求: 收集信息,数据统计数据分析,报表展示 以简道云在线表单为例,能完美实现题主这两个需求—— http…

携程面经1

面经 HDFS读写流程 1.读流程 客户端向NameNode发起读请求(如果存在)NameNode返回一批block地址客户端与第一个block的拓扑距离最近的节点建立连接以packet(64kb)的单位读取数据块。一个block读取完成后客户端会断开与该DataNod…