1.实验要求.

  • 用Java图形用户界面编写聊天室服务器端和客户端, 支持多个客户端连接到一个服务器。每个客户端能够输入账号。
  • 可以实现群聊(聊天记录显示在所有客户端界面)。
  • 完成好友列表在各个客户端上显示。
  • 可以实现私人聊天,用户可以选择某个其他用户,单独发送信息。
  • 服务器能够群发系统消息,能够强行让某些用户下线。
  • 客户端的上线下线要求能够在其他客户端上面实时刷新。

2.实验平台及语言.

实验选择语言为Java,开发平台为Eclipse IDE for Enterprise Java Developers.
Version: 2019-06 (4.12.0)

3.项目完整代码.

JavaSocket编程开发聊天室ThreeStrikes.

4.设计思路.

  • 整个项目采用Client-Server设计模式,粗略地可以分为两个部分,即客户端Client与服务器端Server。客户端与服务器端进行交互的方式是:客户端封装自己需要进行的操作,例如发送文本消息、发送窗口抖动、登录、退出等,成为一类抽象的请求-plea,每一种不同的plea实例化之后通过不同的标识属性值来进行区分,而后将请求送达服务器端。服务器端采用多线程策略,为每一个到达的客户端请求建立一个线程,专门为该客户端服务,接收到客户端传来的plea后,服务器端内部进行一系列的处理(判断该请求是否合法、是否正确,比如你不能向自己发送消息、你不能用错误的账号和密码进行登录),之后服务器端封装自己的处理结果,例如允许登录、允许客户端发送消息等,成为一类抽象的回答-reply,每一种不同的reply实例化之后也通过不同的标识属性值来进行区分,而后将回答返还给客户端。
  • 在具体的实现过程中,我们不可能将所有的功能都实现在同一个类中。比方说,按照我们上面的分析,我们只设计4个类:Client、Server、Plea、Reply就从逻辑上完成了整个项目。但这显然是不合理的,每一个类中会有太多的功能,例如Client类中,既要进行登录、注册、聊天界面的设计,又要完成发送消息、接收消息等业务代码的实现,这样的代码即使不出差错地写出来了,也是不忍回首的。我的想法是,从界面设计入手。用户最先进入的界面是登录界面,而后产生分支——或是选择注册,或是选择直接进入聊天室,在界面设计的过程中,不断进行功能之间的解耦合(例如登录界面中就不会考虑到发送消息的功能),不断细化整个客户端的分类,同时也不断实现每一个界面上需要实现的功能。
  • 下面我们从客户端Client部分入手,讲述整个项目的实现及其细节。

5.Client客户端.

ClientLauncher.

ClientLauncher是用户看到的客户端的入口,由于服务器端Server是需要先于客户端Client启动的,所以我们讲述时,会假定已经有一个"Server"已经在等待着为我们服务了。整个ClientLauncher的代码并不是很长,我们在下面直接给出其main函数:

public static void main(String[] args) {//Connect with a Server.Make_Connection();//Client appearance.JFrame.setDefaultLookAndFeelDecorated(true);JDialog.setDefaultLookAndFeelDecorated(true);try{String LookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();UIManager.setLookAndFeel(LookAndFeel);}catch(Exception e){e.printStackTrace();}new ClientLogin();}

可以看出ClientLauncher中实际上只做了两件事:1、进行客户端与服务端连接的初始化建立;2、给出整个UI的风格确定(即代码中的getCrossPlatformLookAndFeelClassName())。
Make_Connection()中,我们所做的事情就是从预先配置好的属性文件中,按名读取"IP"与"Port"用于建立从客户端到服务器端的Socket,并且通过该Socket我们能够对连接的输入流和输出流进行操作。关于属性文件的操作,可以参看《Eclipse项目中创建.properties属性文件及其中属性》。
注意到ClientLauncher的最后,我们通过new创建了一个ClientLogin对象,顾名思义,这就是用户登录的界面。关于Java的各种显示风格,只需要更改setLookAndFeel()中的参数即可,这里使用的CrossPlatform是一种不依赖于操作系统的界面风格,在每一种OS上都能够展示出来。

ClientLogin.

ClientLauncher以调出ClientLogin的界面结束,我们下面直接给出ClientLogin的构造器代码:

public ClientLogin()
{Initialize();setVisible(true);
}

由于需要GUI,所以我们让ClientLogin继承了JFrame类,这也是需要setVisible(true)让整个GUI显示出来的原因。Initialize()方法中进行的是整个登陆界面的控件摆放,包括输入账号、密码的输入框、登录按钮、注册按钮以及一个出于美观考虑的Logo,除此之外,Initialize()方法中还完成了各种控件和事件监听器的绑定。最后的GUI如下图所示:

界面设计的细节描述如下:

  • 设置界面上的字体,示例代码以JLabel为例,实际上很多控件都可以通过setFonts()方法来进行字体更改。
Font myFont = new Font("Arial Rounded MT Bold",Font.BOLD,18);
JLabel ID_Label=new JLabel("Identity:");
ID_Label.setFont(myFont);

至于自己的电脑上已经安装了哪些字体,以Win10为例,可以在C:\Windows\Fonts文件夹中查看。

  • 设置边框,例如上图中包含Login Info的边框。
JPanel MainLoginPanel=new JPanel();
Border border=BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
MainLoginPanel.setBorder(BorderFactory.createTitledBorder(border,"Login Info.",TitledBorder.CENTER,TitledBorder.TOP));

代码段中createEtchedBorder()的意思是创建蚀刻风格的边框,而下面依据中的createTitleBorder则是在已经创建好的蚀刻边框上加入文字信息,我们对比其中的参数以及上图中的最终UI效果,不难看出其中参数的作用。更多关于边框的归纳知识,可以参看这篇文章。

  • 设置背景色,无法通过直接调用setBackground(Color)来实现,虽然调用这一方法确实设置了背景色,但你却无法看到它,因为呈现出来的是contentPane的背景色。问题的关键在于,JComponent控件中的Opaque属性默认是false的,Opaque意为不透明,该属性为false也就意味着这一控件透明,所以最终的GUI会透过该控件而显示出底层的颜色。
MainLoginPanel.setOpaque(true);
MainLoginPanel.setBackground(new Color(179, 220, 241));

关于Color,我们可以使用Java预定义的值,例如Color.BLUE、Color.BLACK,也可以向上述代码中,通过RGB值来创建一个Color实例。至于如何查看某处颜色的RGB值,可以参看图片任意点的RGB值。

  • JButton的事件监听器绑定,这是GUI程序中很常见的一种操作。
RegisterButton.addActionListener(new ActionListener()
{@Overridepublic void actionPerformed(ActionEvent e) {new ClientRegister();}
});

通过addActionListener()方法,我们可以将一个"动作"绑定到一个按钮上,当这个按钮被点击时,就执行绑定到上面的动作。其中关于匿名内部类的语法,就不再赘述。

  • 验证账号的正确性。上面给出的GUI界面中,有【Sign Up】和【Sign in】两个JButton,它们分别对应于进入注册界面注册一个新账号和使用已有的账号登录进入聊天室。我们先叙述ClientRegister类中的内容,而后再讲述,如何验证账号的正确性。

ClientRegister.

在ClientLogin的GUI上点击【Sign Up】会进入ClientRegister的界面,客户端注册类的构造器和客户端登录类完全一样,区别就在于它们各自的Initialize()方法中所进行的界面设计以及绑定到控件的动作。ClientRegister中涉及昵称、密码、再次确认密码、性别、头像这些输入型控件以及完成注册、重填信息以及取消注册这些辅助功能按钮的设置,最后的GUI界面如下所示:

界面设计上的细节描述如下:

  • 空布局null,这种布局策略相较于我们常见的边界布局BorderLayout、流式布局FlowLayout来说,程序员需要做的事情变多了,但好处是控件的摆放更为灵活。对于一个控件,我们可以通过方法setBounds(int x,int y,int width,int height)来精确控制它在最终GUI中的位置。需要注意的是,setBounds()方法中的参数不是相较于整个屏幕而言,而是相较于采用null布局的这个界面而言。
getContentPane().setLayout(null);
JLabel nickname = new JLabel("Nickname:");
nickname.setBounds(24,36,65,17);
getContentPane().add(nickname);
  • 单选按钮JRadioButton,单选按钮并没有很复杂的用法,我们上述的GUI中用它来给用户提供性别选择。
Male = new JRadioButton("Male",true);
Female = new JRadioButton("Female");
Male.setBounds(248,31,60,25);
Female.setBounds(310, 31, 75, 25);
getContentPane().add(Male);
getContentPane().add(Female);

其中Male按钮的构造器中的第二个参数,是设置该按钮是否默认选中,并且该参数默认为false。

  • 下拉框JComboBox,下拉框是一种很便捷的展示形式,我们这里用它来进行头像的展示,头像图片的.png文件都是存放在项目下的文件夹中的。下拉框的具体效果如下图所示:
Profile = new JComboBox();
Profile.setBounds(278,70,65,45);
Profile.setMaximumRowCount(3);
for(int i=0;i<11;++i)
{Profile.addItem(new ImageIcon("D:\\NewDesktop\\images\\" + i + ".png"));
}
Profile.setSelectedIndex(0);

上述代码段有关GUI中下拉框的部分,.png文件的位置是可以自由设置的。这里的两个方法setMaximunRowCount(int x)是指下列的视图中最多显示几个完整的item,我们从上面的下拉框效果图中也可以看出这一点,而setSelectedIndex(int x)则是设置默认选中的item的序列号(从0开始).

  • 记录完成注册流程的用户,当用户完成了信息的正确输入之后点击了OK按钮,我们就需要将这一用户的信息保存到本地的.db文件(是服务器端Server完成这一工作的,客户端不应该拥有修改记录所有用户信息的.db文件,.db文件同样是在前面提到的属性文件中完成配置的),用于登录时的账号验证。显然,记录下完成注册的用户信息并不是客户端自己能够完成的事情,所以这里需要和服务器端Server进行交互。首先客户端向Server发送标记为【注册】的请求以及表示该用户的【抽象用户数据】,而后等待Server的回复。这里我们先不展开叙述Server所作的工作,理想地认为Server能够给出正确的回复(例如对于已有用户的识别)。客户端得到Server的回复之后,它检查这个回复,如果Server回复中标记为了【成功】,客户端的注册界面就给出注册成功的信息,否则引导用户进行重填或者退出注册。当一个用户进行登录时,客户端也会向Server发送一个标记为【登录】的请求以及表示这一用户的【抽象用户数据】,理想的Server就对这一请求进行处理,判断是否密码正确、是否存在这一用户以及该用户是否已经登录,从而给出回复信息,客户端再根据回复中的标记,给出错误信息或者成功进入聊天界面。
private void RealRegis(ADT_of_User newUser) throws IOException,ClassNotFoundException
{Plea plea = new Plea();plea.setAction("Register");plea.setData("User", newUser);Reply reply  = ClientToServer.sendMessage(plea);ReplyPhase phase = reply.getPhase();switch(phase){case SUCCESS:ADT_of_User tempUser = (ADT_of_User)reply.getData("User");JOptionPane.showMessageDialog(ClientRegister.this, "Wow!You have got yourself's account : "+tempUser.getID(),"Success Regiter.",JOptionPane.INFORMATION_MESSAGE);this.setVisible(false);break;default:JOptionPane.showMessageDialog(ClientRegister.this, "What a pity!Something wrong has happened.","ERROR",JOptionPane.ERROR_MESSAGE);}
}

ClientChat简述.

在ClientLogin的GUI上点击【Sign in】会进入ClientChat的界面,也就是聊天室的主要界面,大同小异的构造器就不再赘述。ClientChat的最终GUI如下所示,我们给出了两个客户端的界面:


ClientChat的界面相较于前面的登录界面、注册界面都复杂了很多,主要分为五个板块:左上角的群聊消息区、左下角的编辑消息区、右上角的在线用户列表、右下角的【自己】信息区以及一些给出辅助功能的区域(例如有着发送和退出的按钮区、私聊和常见聊天室功能的按钮区以及系统状态的提示区)。并且在上面展示的GUI中,已经进行了消息发送的演示,两张图对比起来看,可以很清楚看出发送消息的时间、逻辑关系。

JavaSocket编程开发聊天室-客户端核心部分中会详细叙述ClientChat的内容.

【Java】JavaSocket编程开发聊天室-总览与部分客户端界面相关推荐

  1. 视频教程-基于Java的WebSocket的聊天室-Java

    基于Java的WebSocket的聊天室 多年 Java 企业级应用开发工作经验,曾参与中国人寿.华夏人寿.泰康人寿.信达财险等保险行业内部业务管理系统以及线上在线产品的开发:参与中国人民银行.清华大 ...

  2. 基于Java socket的网络聊天室的设计与实现

    目 录 摘要 I Abstract II 目 录 III 1 引言 1 2 网络聊天室的简介 2 2.1网络聊天室现状和发展 2 3 完成网络聊天室的技术以及环境 4 3.1 Java的介绍 4 3. ...

  3. 局域网服务器发送消息,Java实现简单局域网聊天室

    本文实例为大家分享了Java实现简单局域网聊天室的具体代码,供大家参考,具体内容如下 Java 的Socket编程: 1.TCP协议是面向连接的.可靠的.有序的.以字节流的方式发送数据,通过三次握手方 ...

  4. Java中文编程开发,让Java编写更加容易

    Java中文编程开发,让Java编写更加容易 目录 创建Java项目 创建类 编写方法 调用方法 Tips:文件必须以UTF-8格式保存才能够运行 1.创建Java项目 项目创建完成后,创建一个资源包 ...

  5. Python用tornado的websocket开发聊天室

    Python用tornado的websocket开发聊天室 用tornado开发基于异步websocket聊天室-demo 目录结构 Python包 main.py app/views.py temp ...

  6. java实现多人聊天室+私聊+Derby数据库

    java实现多人聊天室+私聊+Derby数据库(没有实现注册功能) 这个聊天室困扰了我好久好久,一步一步的修改,终于不负我的努力啊,可算完成了,对于一个初学java的来说,完成第一个比较完整的项目,也 ...

  7. 基于JavaSwing开发聊天室(QQ聊天 群聊)系统+论文+PPT 大作业 毕业设计项目源码

    基于JavaSwing开发聊天室(QQ聊天 群聊)系统+论文+PPT(毕业设计/大作业) 开发环境: Windows操作系统 开发工具: Eclipse/Myeclipse+Jdk 演示视频: jav ...

  8. Java+Springboot+Websocket在线聊天室

    1.什么是websocket? websocket是由HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯.它是一种在单个TCP连接上进行全双工通信的协议.W ...

  9. java swing多人聊天室_使用java swing和socket编程实现简单的多人聊天室-Go语言中文社区...

    完成效果如下 客户端: 服务器端: 客户端功能: 输入服务器对应的端口,IP号,用户名(昵称),可以互相发送消息 服务器端功能: 输入端口号,启动,可以向所有客户端发送消息,IP地址自动获取. 下面是 ...

  10. JAVA基于局域网的聊天室系统(源代码+论文)

    毕业论文 局域网聊天室系统的设计与实现 论文作者姓名: 申请学位专业: 申请学位类别: 指导教师姓名(职称): 论文提交日期: 基于局域网的视频聊天室系统的设计与实现 摘 要 视频聊天系统作为一种新型 ...

最新文章

  1. 【探讨】javascript事件机制底层实现原理
  2. php和python和java-python与java区别
  3. 在.Net中进行跨线程的控件操作(上篇:Control.Invoke)
  4. 2019.04.09 电商25 结算功能1
  5. QML工作笔记-为PushButton戴上皮肤
  6. python-函数的返回值
  7. R语言 相关分析和典型相关分析
  8. [转]Stream 和 byte[] 之间的转换
  9. c语言宏定义数组_利用数组处理批量数据 C语言程序编写定义与利用数组技巧全归纳...
  10. ERROR Utils: Uncaught exception in thread stdout writer for python
  11. linux制作win7启动u盘
  12. 常用音频接口简介(PDM/PCM/IIS/SLIMBUS)
  13. w10 桌面计算机垃圾桶,解答win10我的电脑怎么放在桌面
  14. 抖音上热门的六大规律
  15. 读书笔记 摘自:《你坏》
  16. 【浙大版《Python 程序设计》题目集(解)】第3章-14 字符串字母大小写转换(15分)
  17. 【ALM】POLARION ALM之需求管理解决方案介绍02
  18. Nodejs纯esm模块的迁移方法、社区冲击、评价浅论
  19. Spring的注解@Bean
  20. 用Echarts实现中国地图

热门文章

  1. Python学习笔记大总结(我把我所有python笔记做了总结和学习顺序,点击即可进入相关博客。希望可以便于你们阅读)
  2. Ubuntu安装adobe字体
  3. PilotEdit 破解版下载|PilotEdit(文本编辑器) 中文破解版 v11.8下载(含注册机)
  4. lowagie.text 表格带复杂表头 导出word
  5. Egg.js框架的简单使用
  6. sd卡卡槽_SD卡无法读取最完整解决办法汇总
  7. NekoHTML 学习笔记
  8. java 将ofd转为pdf(代码简单)
  9. 华为交换机学习指南基于MAC地址划分VLAN
  10. 淘宝双11的服务器架构分析(1)