一、简介

  本次项目要求:

1、所有功能通过图形化界面操作,可以是桌面应用,可以是网站(编程语言和技术不限);

2、用户注册功能。用户提供手机号码,点击注册将收到一个注册码,用户可使用该注册码完成注册;

3、用户完成注册后,界面提示设置密码,用户输入两次密码匹配后设置密码成功。密码6-10位,必须含大小写字母和数字。用户在登录状态下可修改密码,输入正确的原密码,再输入两次相同的新密码后修改密码成功;

4、密码设置成功后,跳转到选择界面,界面显示小学、初中和高中三个选项,用户点击其中之一后,提示用户输入需要生成的题目数量;

5、用户输入题目数量后,生成一张试卷(同一张卷子不能有相同题目,题目全部为选择题),界面显示第一题的题干和四个选项,用户选择四个选项中的一个后提交,界面显示第二题,...,直至最后一题;

6、最后一题提交后,界面显示分数,分数根据答对的百分比计算;

7、用户在分数界面可选择退出或继续做题;

8、小初高数学题目要求见个人项目。

二、代码复用情况

  我用的是java语言,对于图形化设计比C++方便,所以我们本次的结对编程项目大体采用JAVA。我在处理小初高数学题目的代码部分逻辑有些混乱,而队友的结构思路清晰,所以我们在本次项目的题目生成部分采用他在C++的思路,并且注册登录方延续个人项目的文件流读写操作,开始是准备使用数据库,奈何个人技术不支持~——~。

三、分工合作

  我本人比较擅长写图形化界面UI的部分,所以所有显示界面都是由我来完成;队友和我一块负责后端代码实现,他实现题目的生成以及得分的判定,我负责手机验证码的发送与接受,注册登录方面

四、项目的构建流程、

       (如图所示)

五、代码分析

  

  上图是我们本次项目所用到的类的定义

  1. 首先是登录界面LoginUI,通过JFrame构建页面并向内添加登录和注册的按钮,并将其对应的监听器绑定按钮

        public void loginUI(){
    jframe = new JFrame();
    jlabel1 = new JLabel("手机号:");
    jlabel2 = new JLabel("密码:");
    //实例化FlowLayout流式布局类的对象,指定对齐方式为居中对齐,组件之间的间隔为5个像素
    flowLayout = new FlowLayout(FlowLayout.CENTER, 10,10);
    jTextField = new JTextField();
    jPasswordField = new JPasswordField();
    jbutton1 = new JButton();
    jbutton2 = new JButton();
    init();
    }
    //类中定义初始化界面的方法
    public void init() {
    //设置窗体对象的属性值,标题,大小,显示位置,关闭操作,布局,禁止调整大小
    jframe.setTitle("小初高数学学习软件"); //设置标题
    jframe.setSize(400, 500); //设置窗体大小
    jframe.setDefaultCloseOperation(3); //设置窗体关闭操作;3表示关闭窗体退出程序
    jframe.setLocationRelativeTo(null); //设置窗体相对与另一个组件的居中位置,,参数null表示相对于屏幕正中央
    jframe.setResizable(false); //设置禁止调整窗体大小
    jframe.setLayout(flowLayout); //实例化流式布局对象
    jframe.setVisible(true);//设置窗体可见 JLabel jlabelIcon = new JLabel("**********************中小学数学学习系统**********************");
    //设置标签大小——setSize(, )方法只对窗体有效,如果想设置组件大小只能用Dimension
    //将jlabelICon标签添加到窗体上
    jframe.add(jlabelIcon); //实例化JLabel标签对象,显示“账号:”
    //将jlabelName标签添加到窗体上
    jframe.add(jlabel1); //实例化JTextField标签对象
    Dimension dimension1 = new Dimension(300, 30);
    //jtextName.serSize()方法支队顶级容器有效,其他组件使用无效
    jTextField.setPreferredSize(dimension1); //设置除了顶级容器组件 其他组件的大小
    jframe.add(jTextField); //实例化JLabel标签对象,显示“密码:”
    //将jlabelPass标签添加到窗体上
    jframe.add(jlabel2); //实例化JPasswordField
    //设置大小
    jPasswordField.setPreferredSize(dimension1);
    //添加jPasswordField到窗体上
    jframe.add(jPasswordField); //设置按钮显示内容
    Dimension dimension2 = new Dimension(100, 30);
    jbutton1.setText("登录");
    //设置按钮大小
    jbutton1.setSize(dimension2);
    jframe.add(jbutton1); Dimension dimension3 = new Dimension(100, 30);
    jbutton2.setText("注册");
    //设置按钮大小
    jbutton2.setSize(dimension3);
    jframe.add(jbutton2); //登录
    SignListener signListener = new SignListener();
    signListener.setSignListener(jTextField, jPasswordField);
    jbutton1.addActionListener(signListener); //注册
    EnrollListener enrollListener = new EnrollListener();
    jbutton2.addActionListener(enrollListener); jframe.setVisible(true);//设置窗体可见 }
  2. 登录功能,FunctionUI里实现了出题,修改密码,重新登陆的功能,并用相应地监听器绑定
    public void functionUI(){
    jframe = new JFrame();
    flowLayout = new FlowLayout(FlowLayout.CENTER, 10,10);
    jlabel1 = new JLabel("请选择如下功能:");
    jlabel2 = new JLabel("————————————————————————");
    jbutton1 = new JButton();
    jbutton2 = new JButton();
    jbutton3 = new JButton(); jframe.setTitle("功能界面"); //设置标题
    jframe.setSize(300, 300); //设置窗体大小
    jframe.setDefaultCloseOperation(3); //设置窗体关闭操作;3表示关闭窗体退出程序
    jframe.setLocationRelativeTo(null); //设置窗体相对与另一个组件的居中位置,,参数null表示相对于屏幕正中央
    jframe.setResizable(false); //设置禁止调整窗体大小
    jframe.setLayout(flowLayout); //实例化流式布局对象
    jframe.add(jlabel1);
    jframe.add(jlabel2);
    jframe.setVisible(true);//设置窗体可见 //设置按钮显示内容
    Dimension dimension1 = new Dimension(200, 50); jbutton1.setText("出题");
    //设置按钮大小
    jbutton1.setSize(dimension1);
    jframe.add(jbutton1); jbutton2.setText("重新登录");
    //设置按钮大小
    jbutton2.setSize(dimension1);
    jframe.add(jbutton2); jbutton3.setText("修改密码");
    //设置按钮大小
    jbutton3.setSize(dimension1);
    jframe.add(jbutton3); SetProblemListener setProblemListener = new SetProblemListener();
    jbutton1.addActionListener(setProblemListener); ResignListener resignListener = new ResignListener();
    jbutton2.addActionListener(resignListener); ResetPassword resetPassword = new ResetPassword();
    resetPassword.setResetPW(jTextField);
    jbutton3.addActionListener(resetPassword); }
  3. 注册功能实现,使用腾讯云平台,注册账号后在pom.xml里添加腾讯云的依赖,然后通过其函数以及自己的id可以发送验证码(只需修改XXX部分就好)
    public void ReceiveMassages(String number, String templateParam){
    try {
    /* 必要步骤:
    * 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。
    * 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。
    * 你也可以直接在代码中写死密钥对,但是小心不要将代码复制、上传或者分享给他人,
    * 以免泄露密钥对危及你的财产安全。
    * CAM密匙查询: https://console.cloud.tencent.com/cam/capi*/
    Credential cred = new Credential("XXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXX"); // 实例化一个http选项,可选,没有特殊需求可以跳过
    HttpProfile httpProfile = new HttpProfile();
    // 设置代理
    // httpProfile.setProxyHost("真实代理ip");
    // httpProfile.setProxyPort(真实代理端口);
    /* SDK默认使用POST方法。
    * 如果你一定要使用GET方法,可以在这里设置。GET方法无法处理一些较大的请求 */
    httpProfile.setReqMethod("POST");
    /* SDK有默认的超时时间,非必要请不要进行调整
    * 如有需要请在代码中查阅以获取最新的默认值 */
    httpProfile.setConnTimeout(60);
    /* SDK会自动指定域名。通常是不需要特地指定域名的,但是如果你访问的是金融区的服务
    * 则必须手动指定域名,例如sms的上海金融区域名: sms.ap-shanghai-fsi.tencentcloudapi.com */
    httpProfile.setEndpoint("sms.tencentcloudapi.com"); /* 非必要步骤:
    * 实例化一个客户端配置对象,可以指定超时时间等配置 */
    ClientProfile clientProfile = new ClientProfile();
    /* SDK默认用TC3-HMAC-SHA256进行签名
    * 非必要请不要修改这个字段 */
    clientProfile.setSignMethod("HmacSHA256");
    clientProfile.setHttpProfile(httpProfile);
    /* 实例化要请求产品(以sms为例)的client对象
    * 第二个参数是地域信息,可以直接填写字符串ap-guangzhou,或者引用预设的常量 */
    SmsClient client = new SmsClient(cred, "ap-guangzhou",clientProfile);
    /* 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数
    * 你可以直接查询SDK源码确定接口有哪些属性可以设置
    * 属性可能是基本类型,也可能引用了另一个数据结构
    * 推荐使用IDE进行开发,可以方便的跳转查阅各个接口和数据结构的文档说明 */
    SendSmsRequest req = new SendSmsRequest(); /* 填充请求参数,这里request对象的成员变量即对应接口的入参
    * 你可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义
    * 基本类型的设置:
    * 帮助链接:
    * 短信控制台: https://console.cloud.tencent.com/smsv2
    * sms helper: https://cloud.tencent.com/document/product/382/3773 */ /* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId,示例如1400006666 */
    String sdkAppId = "XXXXXXXXXX";
    req.setSmsSdkAppId(sdkAppId); /* 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名,签名信息可登录 [短信控制台] 查看 */
    String signName = "XXXXXXXX";
    req.setSignName(signName); /* 国际/港澳台短信 SenderId: 国内短信填空,默认未开通,如需开通请联系 [sms helper] */
    String senderid = "";
    req.setSenderId(senderid); /* 用户的 session 内容: 可以携带用户侧 ID 等上下文信息,server 会原样返回 */
    String sessionContext = "xxx";
    req.setSessionContext(sessionContext); /* 短信号码扩展号: 默认未开通,如需开通请联系 [sms helper] */
    String extendCode = "";
    req.setExtendCode(extendCode); /* 模板 ID: 必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看 */
    String templateId = "1146916";
    req.setTemplateId(templateId); /* 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]
    * 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号 */
    String[] phoneNumberSet = {number};
    req.setPhoneNumberSet(phoneNumberSet); /* 模板参数: 若无模板参数,则设置为空 */
    String[] templateParamSet = {templateParam, "2"};
    req.setTemplateParamSet(templateParamSet); /* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
    * 返回的 res 是一个 SendSmsResponse 类的实例,与请求对象对应 */
    SendSmsResponse res = client.SendSms(req); // 输出json格式的字符串回包
    System.out.println(SendSmsResponse.toJsonString(res)); // 也可以取出单个值,你可以通过官网接口文档或跳转到response对象的定义处查看返回字段的定义
    System.out.println(res.getRequestId()); } catch (TencentCloudSDKException e) {
    e.printStackTrace();
    }
    }

六、问题与解决

  1.手机验证码模块:这个阶段我们在使用腾讯云的函数时老是报错,而且我们都是按照流程走的,当时一脸懵,后来看了好多教程才发现,在pom.xml里的依赖版本不一样,基本上每个教程的版本都有所变化,所以我们在腾讯云上查询了最新的版本后解决此问题

  2.修改密码模块:我们注册后都是通过文件流保存在了txt文档里,每次登录要从文档里读取数据并进行判断,而修改密码也是需要判断当前号码对应的原密码是否为文档里存储的密码,并且要将新修改的密码存到文档里并将号码之前的记录删除,本来我们想着是直接将文档里对应位置的密码直接删除,但是删除完后向文档里添加新的密码时会重复出现两次,查阅资料后发现我们写入文档函数中文件流没有close(),而在下一次写在本文档内时会重复写两次,所以我们对写入函数进行修改后解决问题。

  3.得分模块:我们当时把重心放在计算式子的得分函数上,而忽略了判断题目的数量这部分,导致出现式子已经全部算完并记录得分后,还会出现0得分的现象,这导致后续在显示得分数时与做对题目数量不匹配,所以我们在其中加了限制了条件,当题目数超过给定的题目数量后会自动停止

七、总结

  本次结对项目对于我和我队友这俩菜鸡来说还是挺有挑战性的,在平时的代码书写也强制自己规范一点,这次项目过程中,体会到了小团队合作的益处,如果我自己一个人的话绝对完不成,俩人分工合作效率翻倍,并且还提高了沟通协调能力,虽然最后功能还是没有实现完全,但是这种经过自己努力思考和交流得出的成品还是值得骄傲的!

  

结对编程——带UI的小初高数学学习软件的更多相关文章

  1. 带UI的小初高数学学习软件—艰难地用C++(QT库)实现的过程

    从互相了解对方的代码思路然后确定用C++编写,到用win32写界面时变得摇摆不定的考虑着要不要改变语言,再到用QT写完界面后发现短信接口一般都不提供C++,最后到QT打包出来的可执行文件在别的设备上无 ...

  2. 带UI的小初高数学学习软件

    结对编程项目总结   一.项目需求分析与功能总结 (1)用户注册功能 用户提供手机号码,点击注册将收到一个注册码,用户可使用该注册码完成注册. (2)设置密码功能 密码6-10位,必须含大小写字母和数 ...

  3. 结对编程项目复盘:带UI的小初高数学学习软件

    实现个人项目时,由于我当时的Java GUI编程基础还比较薄弱,所以我选择通过命令行实现,并将编程开发的重点放到了算法效率上去.没能设计出用户体验更佳的UI成为了我在个人项目阶段最大的遗憾. 在这次结 ...

  4. 带UI 的小初高数学学习系统 —结对编程项目总结

    一. 项目综述 本系统是基于QT Creator 4.3.0开发环境,开发语言C++,能够实现用户注册,发送短信验证码,用户登陆,用户选择题目类型和数量,显示用户本次答题基本功能.支持对用户账号查重, ...

  5. HNU_小初高数学学习软件_功能说明

    结对编程项目主要功能: 1.用户注册功能.用户提供手机号码,点击注册将收到一个注册码,用户可使用该注册码完成注册: 2.用户完成注册后,界面提示设置密码,用户输入两次密码匹配后设置密码成功.密码6-1 ...

  6. 结对编程收获——UI真的没有那么简单

    结对编程收获——UI真的没有那么简单                                                      詹元成 初看作业要求,心里还有一点欣喜,不就是做一个UI ...

  7. HNU_小中初数学学习软件(可视化编程)_结对项目总结与体会

    前言 经过将近一周的共同努力,HnuLyx和我终于完成了项目,期间心酸苦辣,受益良多,请允许我一一道来. 问题(需求要求的

  8. 记java的那些编辑器的故事之凌嘉文+李晓彤-结对编程

    [写在前面]这次是复用个人项目进行结对编程,其实主要复用的就是凌老板的出题部分和我的文件读写部分,其余部分都是新学的.在这次编程中也涨了很多知识,其中最最最让人哭笑不得的就是:两个人用了不一样的编辑器 ...

  9. 结对编程—黄金点游戏WinForm单机版

    本小游戏场景来自邹欣老师的<移山之道>一书: "阿超的课都是下午两点钟,这时班上不少的同学都昏昏欲睡,为了让大家兴奋起来,阿超让同学玩一个叫"黄金点"的游戏: ...

随机推荐

  1. multipass指定virualbox搭建k8s集群(选择docker作为默认容器)

    目录 前言 步骤 初始化三台虚拟机 统一安装docker 修改docker镜像源 查看masterIP 安装master节点(重点设置) 查看master的token 安装worker节点 测试 部署 ...

  2. hyperf从零开始构建微服务(一)——构建服务提供者

    阅读目录 什么是服务 构建服务提供者 1.创建数据表 2.构建服务提供者 3.安装json rpc依赖 4.安装rpc server组件 5.修改server配置 6.配置数据库 7.编写基础代码 7 ...

  3. 第二课:启动 GDB 调试

    使用 GDB 调试程序一般有三种方式: gdb filename gdb attach pid gdb filename corename 这也对应着本节课的核心内容: 直接调试目标程序 附加进程 调 ...

  4. Vue Abp vNext获取当前登录用户

    系统默认提供了获取当前用户的api方法 https://localhost:44364/api/identity/my-profile 手工实现方法:abp后台获取当前用户需要在AppService应 ...

  5. Apache网页优化

    目录: 一.Apache网页优化概述 二.网页压缩 三.网页缓存 四.隐藏版本信息 五.Apache防盗链 一.Apache网页优化概述 在企业中,部署Apache后只采用默认的配置参数,会引发网站很 ...

  6. DHCP的原理和配置

    前言 在大型企业网络中,会有大量的主机或设备需要获取IP地址等网络参数.如果采用手工配置,工作量大且不好管理,如果有用户擅自修改网络参数,还有可能会造成 IP地址冲突等问题.使用动态主机配置协议DHC ...

  7. Docker部署启动错误,需要手动进入Docker的容器里,启动程序,排查错误

    #docker-compose build --no-cache //重新创建容器,不管有没有 #docker-compose up #docker-compose up -d //后台启动并运行容器 ...

  8. FastAPI(7)- get 请求 - 详解 Path

    前言 上一篇讲了可以为查询参数添加额外的校验和元数据,Query 库:https://www.cnblogs.com/poloyy/p/15306809.html 这篇讲可以为路径查询添加额外的校验和 ...

  9. html jquey的选择器checkbox,select

    1 判断checkbox是否选中 用到 jquery的 is方法 jquery: <div id="divId" class="divTable"> ...

  10. Shell系列(31)- 双分支if语句简介

    双分支if条件语句 if [ 条件判断式 ] then 条件成立,执行的程序 else 条件不成立,执行的程序 fi 需求 根据用户输入的目录名,判断是否存在 脚本: #!/bin/bash #使用r ...