当前位置:   article > 正文

Java实现简易聊天软件(含课程论文、实施计划书、演示视频、答辩PPT、源代码及运行环境)_java 简易聊天应用

java 简易聊天应用

西北农林科技大学信息工程学院

《面向对象程序设计实践》实习报告

题 目: 简易聊天软件

学 号
姓 名
专业班级
指导教师
实践日期年6月26日-7月7日

目 录

一、综合训练目的与要求11

二、综合训练任务11

三、总体设计11

四、详细设计说明77

五、调试与测试1616

六、实习日志1717

七、实习总结2020

八、附录:核心代码清单2020

一、综合训练目的与要求

  1. 目的
    学生通过利用面向对象程序设计思想进行项目开发,加深学生对面向对象程序设计核心思想的理解,提高的编程能力,掌握撰写规范程序设计文档的能力,为今后从事软件开发打下必要的基础。
  2. 要求

通过本实践性教学环节,巩固学生理解和掌握面向对象程序设计的类、对象、继承、接口等主要内容。将理论与实践结合,提高学生利用面向对象程序设计思想开发程序的能力。

二、综合训练任务

简易聊天软件要求:仿QQ软件,开发简洁美观的界面,实现注册、登录、查找好

友,文件传输和双人或多人聊天等基本功能。

三、总体设计

根据题目要求和需求分析,我对简易聊天软件的总体设计如下:

图1 用例图
图2 类图
图3 活动图_注册
图4 活动图_登录
图5 活动图_查找好友
图6 活动图_群聊
图7 活动图_截图

四、详细设计说明

图8-1 类图_Clientframe图8-2 运行结果_Clientframe登录界面界面构成头像,Logo,背景均为JLabel。UI风格为Nimbus风格(以下均同)。清除窗口装饰,并通过JLabel设计图标及其对应监听器(以下均同)。功能构成无界面拖动功能:没有窗口修饰下实现拖动(以下均同)。注册账号:新建注册界面。找回密码:新建找回密码界面。登录:客户端先判断基本的账号、密码是否输入,之后调用客户端写信息线程对服务器发送请求。
图9-1 类图_Clientframe_register图9-2 运行结果_Clientframe_register注册账号界面界面构成提示信息、头像为JLabel,密码框与输入密码框为JPasswordField,头像选择框为JComboBox,其余输入框均为JTextField。功能构成注册:发送注册请求到服务器建立数据库数据。返回:返回登录界面。
图10-1 类图_Clientframe_control图10-2 运行结果_ Clientframe_control控制界面界面构成头像为JLabel,用户信息为自定义的JList,它的模型为继承AbstractListModel的ArrayList<>,它的列表项继承了JLabel和实现了ListCellRenderer,详细如图10-1类图_Clientframe_control功能构成查看好友信息:点击好友头像查看信息。刷新好友列表:直接刷新好友列表。发起群聊:发起多人聊天。添加好友:根据昵称、账号、地址等信息进行精确和模糊查找。吸附功能:类似QQ,贴近上边缘自动吸附。
图11-1 类图_Clientframe_add图11-2 运行结果_Clientframe_add添加好友界面界面构成提示信息为JLabel,输入框为JTextField和一个添加按钮Button功能构成精确添加好友:查找好友唯一时直接添加好友。模糊添加好友:查找好友不唯一时弹出选择框由用户选择添加好友。
图12-1 类图_Clientframe_chat图12-2 运行结果_Clientframe_chat聊天界面界面构成输入和输出窗口为JtextArea,发送按钮为Button,背景、截图功能为JLabel。功能构成群发信息:发送群发请求给服务器接着转发给所有客户端。截图功能:截图,并能显示截图点RGB值和截图大小,最终以当前时间命名保存桌面。
图13 类图_Server服务器类界面构成无界面,运行后打印。功能构成获得服务器:可以获得服务器唯一实例,一个服务器对应多客户端,保证线程安全。获得在线客户端集合:每登录一个客户端便存储在集合中,调用群发信息时使用。
图14 类图_ServerJDBC服务器连接数据库类界面构成无界面,供调用数据库时使用。功能构成查询功能:执行查询语句,返回ResultSet。更新功能:执行更新语句,返回影响行数。插入账号功能:根据用户输入信息插入信息到用户表,并返回生成的账号。登录验证功能:判断用户账号密码是否一致。用户头像、用户昵称、好友列表信息:返回对应查询到串值。添加朋友:插入用户间关系到好友表中。
图15 类图_ServerReaderThread服务器读信息进程类界面构成无界面,供客户端发送功能请求时使用。功能构成注册、登录、获取昵称、获取头像、获取好友列表、找回密码、查找好友、添加好友、群聊、退出功能:处理客户端注册等对应请求。
图16 类图_ServerWriterThread服务器写信息进程类界面构成无界面,供服务器读信息进程类返回处理客户端请求结果时使用。功能构成输出信息:建立线程输出信息给客户端。

五、调试与测试

  1. 对象流无法读写
    最初的预想是结合对象流和网络编程以传对象的方法对信息进行读写,但是在这个困难上困扰了两天的时间,最后不得已放弃这个方法,改为用更有效率的前缀法,通过构建服务器和客户端双方协议,读取某一类信息并进行处理。
  2. 去除窗口装饰(最小化、最大化、关闭)后无法拖动
    去除窗口修饰后,整个画面风格变得非常优美简洁,但是带来一个很大的缺点是无法拖动、最小化、关闭等基础功能,鉴于此,我添加了两个JLabel来模拟最小化和关闭的功能。并在查资料后获得窗口拖动的方法,建立两个点和鼠标监听器,通过boolean变量来切换可否拖拽,并实时setLocation来改变窗口坐标。
  3. 方法内变量覆盖类的变量

有时为了方便申请变量的名字比较求简,这时候容易造成方法内变量覆盖类变量的情况。方法内变量覆盖类变量后一些方法的输出便变得很奇怪,这个时候并不会出现编译错误、异常等明显的错误,此时只需要使用回溯的思想,根据输出的结果一点点追究源头来发现覆盖的变量名,发现后改名即可。

六、实习日志

  1. 6.26第一天
  2. 一天工作
    今天我的主要工作为前期分析,进行准备工作。完成了项目功能分类,类的设计概况,UML图绘制,与学习相关绘制知识。具体成果有1张用例图,1张类图,4张活动图。
  3. 遇到的问题
    最大的问题是不知从何下手,其次是不清楚UML图的具体功能及其绘制方法。
  4. 解决方案

为解决不知从何下手,我首先明确我的项目“简易聊天软件”的基本功能有哪些并记录纸上,同时利用知网搜索相关资料查阅类似项目概况。接着,我翻阅早已准备好的《疯狂Java讲义》,认真阅读理解此书第二章——理解面向对象,并且仔细阅读UML的相关介绍内容,大致了解了UML图的功能。

为了解UML图绘制方法,我结合此书和搜索引擎及电子书《大象Thinking in UML》,在了解和模仿的基础上不断对书上内容补充、更正,之后利用亿图图示专家进行绘制。

  1. 6.27第二天
  2. 一天工作
    早上我的工作仍然以前期准备工作为主。完成了类图大致的具体设计,与学习相关网络编程知识。具体成果有1张类图,2张活动图。
    下午我进行了JDBC编程,对程序进行数据库连接,同时编程实现了通用SQL函数,以此完成了注册的部分功能,成功将数据插入到数据库表中。
  3. 遇到的问题
    最大的问题是不清楚网络编程的具体过程,导致绘制类图的时候没有准确的属性和方法,只能大概绘制。第二大问题是不熟悉JDBC编程的前期准备过程,最重要的是连接MySQL数据库。
  4. 解决方案

我先将网络编程摆在一边,将每个功能模块可能涉及的数据项写出,并初步完成表的划分。接着进行数据库连接,通过询问老师和查阅《疯狂Java讲义》,安装MySQL后,初步建表,添加JAR到程序后照着老师PPT和书上实例成功连接数据库。

  1. 6.28第三天
  2. 一天工作
    今天我的工作以知识储备为主。
    早上我深入学习了网络编程的ServerSocket和Socket建立连接方法,并成功实现服务器和客户端的连接。
    下午我学习了流的各种概念,掌握了各种流的基本使用方法,重点学习了重头戏——对象流,并明确了对象流的两个关键点:一,父类最好序列化。二、引用类也应序列化。同时了解了序列化算法的流程,及自定义序列化将让账号传输加密,使其具有更高安全性。
  3. 遇到的问题
    心理上感觉一天没怎么敲代码,感觉心慌不踏实。
  4. 解决方案

冷静下来喝杯水,下位走一走,觉得今天的知识复习和储备是值得的,因为后面的大量编程将多次使用到今天所重点学习的知识。

  1. 6.29第四天
  2. 一天工作
    早上我根据昨天学习的网络编程ServerSocket和Socket建立方法和对象流,想通过网络传输对象,但是却一直报错。整个早上都在调试bug,试图修正错误,然而徒劳无功。和老师讨论后发现,我的服务器同时应该建立起多线程,并且通过这个讨论的过程,我了解了使用Debug的一些小技巧。
    下午我浏览了多线程的内容,根据网上的例子一步步将我的客户端建立起来,并使用List将客户端的Socket存储起来以便管理。
  3. 遇到的问题
    不懂得将Java的三个难点——“对象流”,“网络编程”与“多线程”的知识完美结合在一起,写出一个能正常运行的C/S结构。
  4. 解决方案

将书上内容结合在一起,并深入理解流和网络编程的知识。接着通过搜索引擎搜索相关小论文对比代码。

询问老师,演示程序,讨论得出解决大方向。

将所遇到的问题利用搜索引擎寻找多线程的例子,模仿例子完善自我代码。

  1. 6.30第五天
  2. 一天工作
    认识到网络编程最好结合界面来做后,我果断抛弃一直坚持的问题,转而进行界面的设计,完成了客户端登录界面和用户界面,并进行了十分满意的美化。同时设计了用户界面像QQ一样能吸附到上方的功能。
  3. 遇到的问题
    不懂得如何进行模仿QQ界面的窗口部件如最小化、关闭等的美化,不懂得如何实现吸附功能。
  4. 解决方案

结合书上内容,设计出大概布局,然后根据想实现的功能进行搜索,看懂别人实现方法后根据我的需求进行更改。

  1. 7.3第六天
  2. 一天工作
    由于下午和晚上要考试,今天的工作较少。
    今天我完成了界面的相对位置和相对大小的实现。因为每台PC屏幕都可能不一样,我根据操作环境的比例,设计了两个函数使界面打开后能处于一个合适的大小和位置,提高用户体验。
  3. 遇到的问题
    不懂得如何在一开始调整界面相对大小及各个部件的位置。
  4. 解决方案

根据需求使用搜索引擎获得的方法进行改进并解决现实问题。

  1. 7.4第七天
  2. 一天工作
    设计注册账号、找回密码、登录验证的功能,并根据现实需求完善用户体验,同时对应通过数据库类对数据库进行增、查操作。
  3. 遇到的问题
    不懂得如何传输信息给服务器。
  4. 解决方案

根据需求使用搜索引擎得知,传输信息给服务器可以加个前缀,但最好不要使用硬编码。并在服务器接收到信息的时候判断这个信息对应的前缀要求实现怎样的功能,同时根据需求调用数据库类。

  1. 7.5第八天
  2. 一天工作
    完成查找好友功能,能根据号码、昵称、邮箱、手机号、地址进行精确查找或模糊查找。
  3. 遇到的问题
    不懂数据库的某些操作可能引发的异常,在数据库查找没有结果的时候不能够使用next()函数进行取值,否则会引发异常。
    如果查找到多个好友如何选择对应的那个并再传信息给客户端进行添加好友操作。
  4. 解决方案

使用Array类存储匹配到多个可能好友的串,并传给输入选择框展示给用户,接着再进行一次信息发送和返回。

  1. 7.6第九天
  2. 一天工作
    实现用户列表功能和群聊功能,在自定义JList的基础上实现群聊。
  3. 遇到的问题
    不懂如何实现自定义的JList。
    不懂如何实现群聊,在客户端处统一实现Socket。
  4. 解决方案

通过搜索引擎查找JList继承AbstractListModel类和实现ListCellRenderer 接口的范例,并通过自己的具体情况进行深化,最后实现用户列表含有用户头像、昵称和账号,并且点击后可以显示对应的信息。

查看相关功能的视频,并类似地学会思想,在服务器接收Socket的同时,以客户端name为Key,对应的Socket为value,来生成一个对应的Map集合类。

  1. 7.7第十天
  2. 一天工作
    今天主要完成了PPT的设计,直至凌晨4点才睡。
    接着我负责收集全班的Java工程在自己的电脑上导入并配置好环境,让下午1点的答辩能顺利进行。
    到了下午进行答辩,在细节和沟通上没有处理好,导致和老师产生矛盾,这是值得反思的。
  3. 遇到的问题
    视频录制和剪辑的时间过长。
  4. 解决方案

日后多找机会锻炼视频录制和剪辑的能力。

七、实习总结

通过这次实习,我深深认识到自己的编程仅仅局限在敲代码层面上,而没有上升到更为高级更为高效的面向对象系统设计当中。因此,日后课下应多多主动去了解相关系统设计的知识中,才能在日后的大程序设计中设计出高效、系统的程序。

八、附录:核心代码清单

  1. 登录请求(客户端发送请求信息)
    void login(){
    Socket socket = ChatUtil.getInstance().getSocket();//获得唯一实例Socket
    PrintWriter pw = new PrintWriter(socket.getOutputStream());//输出流
    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//输入流
    pw.println(ChatUtil.LOGIN+num+ChatUtil.SPLIT+pas); //双方协议好的前缀,此时不应用硬编码
    pw.flush(); //刷新缓冲区
    String message = ""; //用来接收服务器返回的信息
    while(message==null || message.length()<=0){
    message = br.readLine();//等待服务器回传信息 }
    }
  2. 登录请求(服务器处理请求信息)
    void login(String str){
    String[] arr = str.split(ChatUtil.SPLIT); //将客户端发送的信息分隔开
    String number = arr[1]; //提取账号
    String password = arr[2]; //提取密码
    ServerJDBC serverjdbc = new ServerJDBC(); //实例化服务器连接数据库类
    if(serverjdbc.checkPassword(number, password)==true) { //调用数据库类方法验证密码
    new ServerWriterThread(socket,Client.ChatUtil.LOGIN+"succ").start(); //回传登陆成功信息
    Map<String,Socket> userOnlineMap = server.getUserOnlineMap();//存储客户端的Socket
    userOnlineMap.put(number, socket);//一个账号对应一个Socket
    Collection<Socket> sockets = userOnlineMap.values();//存储客户端的Socket
    }
    else {
    new ServerWriterThread(socket,Client.ChatUtil.LOGIN+"fail").start();//回传登陆失败信息
    }
    }
  3. 自定义单元渲染器(JList项目)

/*继承JLabel并实现ListCellRenderer*/

class FriendsListCellRenderer extends JLabel implements ListCellRenderer {

public Component getListCellRendererComponent(JList list, Object value,int index,boolean isSelected,boolean cellHasFocus){//实现接口

Friend friend = (Friend)value;//取出对象实例

String text = "<html><font size='4' face='微软雅黑'>"+friend.getName()+"<br/>"+friend.getNumber()+"</font><html/>";//设置JLable的文字

setText(text); //设置JLable的文字

Image img = friend.getPhoto().getScaledInstance(85, 85, Image.SCALE_DEFAULT);//创建图像的缩放版本,image.getImage()方法设置头像,同时设置图片

setIcon(new ImageIcon(img));//设置JLable的图片

setIconTextGap(15);//设置JLable的图片与文字之间的距离

return this;//返回自定义项目

}

}

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/804412
推荐阅读
相关标签
  

闽ICP备14008679号