一、简介

  本次项目要求:

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. AndroidJetpack数据处理之数据库Room和懒加载Paging

    数据库工具:Room Room结构 导入依赖 app的build.gradle中开启kapt: apply plugin: 'kotlin-kapt' 并导入以下依赖: def room_versio ...

  2. Nginx从安装到虚拟主机、https加密、重定向的设置

    编译前的设置: 在源代码文件中把版本号注释掉,这是为了防止针对特定版本的恶意攻击 关闭编译时的调试模式 解决编译前的依赖性 进行配置参数: 对参数进行解读: 编译和安装: 做软链接方便调用: 创建ng ...

  3. 关于antd Select 限制选择个数的解决方案

    应用场景描述: Select 被form 所包裹,且被getFieldDecorator修饰.所以值的改变应该通过form的setFieldsValue方法. Select模式肯定会是multiple ...

  4. Django——实现最基础的评论功能(只有一级评论)

    我对评论功能的理解: --------(1)数据库建一个评论的表 --------(2)前端建一个提交评论的form表单 --------(3)表单提交评论内容后写入到数据库评论表中 -------- ...

  5. [考试总结]noip模拟45

    真开心,挂没了.. 考完:"你们怎么第二题打了这么点分,明明一个爆搜就有65pts!!!怎么跟别人打?!" 然后我看了看我的爆搜,30pts. 然后认为自己打爆了... 我又想为什 ...

  6. 转:C#根据条件设置datagridview行的颜色

    1 private void LoadData() 2 { 3 DataTable tblDatas = new DataTable(); 4 tblDatas.Columns.Add("I ...

  7. 在excel中,应用公式到多行

    当一个单元格中输入公式后, 选中单元格 然后将鼠标放到右下角的控制手柄处,当鼠标变成"黑十字"标志 双击鼠标左键 即可

  8. 痞子衡嵌入式:嵌入式Cortex-M中断向量表对齐原则的深入研究

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是Cortex-M中断向量表对齐原则. 今天这篇文章的内容主要来自于五年前做 Kinetis K32W 系列双核启动时的发现,最近正好有同 ...

  9. PTA——c++面向对象基础

    1.结构不是面向对象的主要特征 2.每个 C++程序中都必须包含有这样一个函数,该函数的函数名为main 3.C++对C语言作了很多改进,下列描述中()使得C语言发生了质变,从面向过程变成了面向对象. ...

  10. PHP中的对象比较

    在之前的文章中,我们讲过PHP中比较数组的时候发生了什么?.这次,我们来讲讲在对象比较的时候PHP是怎样进行比较的. 首先,我们先根据PHP文档来定义对象比较的方式: 同一个类的实例,比较属性大小,根 ...