当前位置 博文首页 > 程序员漫话编程的博客:Java 实现QQ界面聊天小项目,可在线聊天

    程序员漫话编程的博客:Java 实现QQ界面聊天小项目,可在线聊天

    作者:[db:作者] 时间:2021-09-18 18:50

    有情怀,有干货,微信搜索【程序员漫话编程】关注这个技术控程序员。
    本文?GitHub?https://github.com/ProceduralZC/JavaDevGuide?已收录,有一线大厂面试完整考点、资料以及我的系列文章。

    .功能实现

    1.修改功能(密码、昵称、个性签名)
    2.添加好友、删除好友
    3.单聊功能
    4.判断好友是否在线

    2.模块划分

    图片

    3.使用的知识

    • netty

    • swing

    • 集合等同步阻塞队列synchronousQueue

    • 数据库MySQL中的CRUD

    • C3p0连接池

    • JSON字符串

    4.部分代码实现

    1.nettyController.java

    • 接收到来自客户端的消息,与dao层进行交互

    • dao层与之数据库进行交互

    修改密码

    图片

    添加好友

    图片

    从添加好友逻辑实现上我走了很多的弯路频繁的访问数据库,这是一件很不好的事情

    package?chat.Project.controller;
    
    import?chat.Project.bean.information;
    import?chat.Project.constant.EnMsgType;
    import?chat.Project.dao.*;
    import?chat.utils.CacheUtil;
    import?chat.utils.JsonUtils;
    import?com.fasterxml.jackson.databind.node.ObjectNode;
    import?io.netty.channel.Channel;
    
    import?java.util.ArrayList;
    import?java.util.Iterator;
    
    public?class?NettyController?{
    
    ????private?static?UserDao?userDao?=?new?UserDaoImpl();
    ????private?static?informationDao?informationDao?=?new?informationDaoImpl();
    ????private?static?friendDao?friendDao?=?new?friendDaoImpl();
    
    ????public?static?String?processing(String?message,?Channel?channel){
    
    ????????//解析客户端发送的消息
    ????????ObjectNode?jsonNodes?=?JsonUtils.getObjectNode(message);
    ????????String?msgtype?=?jsonNodes.get("msgtype").asText();
    ????????if?(EnMsgType.EN_MSG_LOGIN.toString().equals(msgtype)){
    ????????????//登录操作
    ????????????return?loginOperation(jsonNodes,channel);
    ????????}else?if?(EnMsgType.EN_MSG_MODIFY_SIGNATURE.toString().equals(msgtype)){
    ????????????//修改签名
    ????????????return?modifySignature(jsonNodes);
    ????????}else?if?(EnMsgType.EN_MSG_MODIFY_NICKNAME.toString().equals(msgtype)){
    ????????????//修改昵称
    ????????????return?modifyNickname(jsonNodes);
    ????????}else?if?(EnMsgType.EN_MSG_GETINFORMATION.toString().equals(msgtype)){
    ????????????//获取登录信息
    ????????????return?getInformation(jsonNodes);
    ????????}else?if?(EnMsgType.EN_MSG_VERIFY_PASSWORD.toString().equals(msgtype)){
    ????????????//进行修改密码
    ????????????return?verifyPasswd(jsonNodes);
    ????????}else?if?(EnMsgType.EN_MSG_CHAT.toString().equals(msgtype)){
    ????????????//单聊模式
    ????????????return?SingleChat(jsonNodes);
    ????????}else?if?(EnMsgType.EN_MSG_GET_ID.toString().equals(msgtype)){
    ????????????//获取id
    ????????????return?getId(jsonNodes);
    ????????}else?if?(EnMsgType.EN_MSG_GET_FRIEND.toString().equals(msgtype)){
    ????????????//获取好友列表
    ????????????return?getFriend(jsonNodes);
    ????????}else?if?(EnMsgType.EN_MSG_ADD_FRIEND.toString().equals(msgtype)){
    ????????????//添加好友
    ????????????return?addFriends(jsonNodes);
    ????????}else?if?(EnMsgType.EN_MSG_DEL_FRIEND.toString().equals(msgtype)){
    ????????????//删除好友
    ????????????return?delFriend(jsonNodes);
    ????????}else?if?(EnMsgType.EN_MSG_ACTIVE_STATE.toString().equals(msgtype)){
    ????????????//判断好友的在线状态
    ????????????return?friendIsActive(jsonNodes);
    ????????}
    ????????return?"";
    ????}
    
    ????//判断好友在线状态
    ????private?static?String?friendIsActive(ObjectNode?jsonNodes)?{
    ????????int?friendId?=?jsonNodes.get("friendId").asInt();
    
    ????????ObjectNode?objectNode?=?JsonUtils.getObjectNode();
    ????????objectNode.put("msgtype",EnMsgType.EN_MSG_ACK.toString());
    ????????objectNode.put("srctype",EnMsgType.EN_MSG_ACTIVE_STATE.toString());
    
    ????????//客户端保证用户独立存在且是好友
    ????????Channel?channel?=?CacheUtil.get(friendId);
    ????????//判断用户是否在线
    ????????if?(channel?==?null){
    ????????????//用户不在线
    ????????????objectNode.put("code",200);
    ????????}else?{
    ????????????//用户在线
    ????????????objectNode.put("code",300);
    ????????}
    ????????return?objectNode.toString();
    ????}
    
    ????//添加好友
    ????private?static?String?delFriend(ObjectNode?jsonNodes)?{
    ????????Integer?friendId?=?jsonNodes.get("friendId").asInt();
    ????????int?userId?=?jsonNodes.get("id").asInt();
    ????????String?localName?=?jsonNodes.get("localName").asText();
    
    ????????//封装发回客户端的JSON
    ????????ObjectNode?objectNode?=?JsonUtils.getObjectNode();
    ????????objectNode.put("msgtype",EnMsgType.EN_MSG_ACK.toString());
    ????????objectNode.put("srctype",EnMsgType.EN_MSG_DEL_FRIEND.toString());
    ????????objectNode.put("code",200);
    
    ????????//验证是否存在当前好友
    ????????information?information?=?informationDao.getInformation(friendId);
    ????????String?friendName?=?information.getNickname();
    ????????//查询自己是否有该好友
    ????????boolean?exist?=?friendDao.isExist(friendName,userId);
    ????????if?(exist){
    ????????????//存在当前好友进行删除操作
    ????????????friendDao.delFriend(userId,friendName);
    ????????????friendDao.delFriend(friendId,localName);
    ????????????objectNode.put("code",300);
    ????????}
    ????????return?objectNode.toString();
    ????}
    
    ????//添加好友
    ????private?static?String?addFriends(ObjectNode?jsonNodes)?{
    ????????Integer?friendId?=?jsonNodes.get("friendId").asInt();
    ????????int?userId?=?jsonNodes.get("id").asInt();
    ????????String?localName?=?jsonNodes.get("localName").asText();
    
    ????????//验证是否有ID
    ????????boolean?exists?=?userDao.verifyExistFriend(friendId);
    ????????ObjectNode?objectNode?=?JsonUtils.getObjectNode();
    ????????objectNode.put("msgtype",EnMsgType.EN_MSG_ACK.toString());
    ????????objectNode.put("srctype",EnMsgType.EN_MSG_ADD_FRIEND.toString());
    ????????objectNode.put("code",200);
    
    ????????if(exists){
    ????????????//表示存在此id
    ????????????objectNode.put("code",300);
    ????????????//获取好友昵称
    ????????????information?information?=?informationDao.getInformation(friendId);
    ????????????String?friendNickname?=?information.getNickname();
    ????????????//进行添加好友的操作???两个对应的信息都应该添加
    ????????????friendDao.addFriends(userId,localName,friendNickname);
    ????????????friendDao.addFriends(friendId,friendNickname,localName);
    ????????}
    ????????return?objectNode.toString();
    ????}
    
    ????//获取好友列表
    ????private?static?String?getFriend(ObjectNode?jsonNodes)?{
    
    ????????int?uid?=?jsonNodes.get("uid").asInt();
    
    ????????//返回ArrayLis集合
    ????????ArrayList<String>?friends?=?friendDao.getFriends(uid);
    ????????//封装JSON
    ????????ObjectNode?objectNode?=?JsonUtils.getObjectNode();
    ????????objectNode.put("msgtype",EnMsgType.EN_MSG_ACK.toString());
    ????????objectNode.put("srctype",EnMsgType.EN_MSG_GET_FRIEND.toString());
    
    ????????//写回friend集合
    ????????Iterator<String>?iterator?=?friends.iterator();
    ????????int?i?=?0;
    ????????while?(iterator.hasNext()){
    ????????????objectNode.put("res"+i,iterator.next());
    ????????????i++;
    ????????}
    ????????//记录好友个数
    ????????objectNode.put("count",i);
    
    ????????return?objectNode.toString();
    ????}
    
    ????//获取id
    ????private?static?String?getId(ObjectNode?jsonNodes)?{
    ????????String?nickname?=?jsonNodes.get("nickname").asText();
    ????????information?information?=?informationDao.nicknameGetId(nickname);
    ????????//联系人的id
    ????????int?uid?=?information.getUid();
    ????????//封装JSON
    ????????ObjectNode?objectNode?=?JsonUtils.getObjectNode();
    ????????objectNode.put("msgtype",EnMsgType.EN_MSG_ACK.toString());
    ????????objectNode.put("srctype",EnMsgType.EN_MSG_GET_ID.toString());
    ????????objectNode.put("uid",uid);
    ????????return?objectNode.toString();
    ????}
    
    ????//单聊模式
    ????private?static?String?SingleChat(ObjectNode?jsonNodes)?{
    
    ????????int?id?=?jsonNodes.get("id").asInt();
    
    ????????//根据id在friend表获取登录用户名
    
    ????????//封装JSON数据服务端转发数据
    ????????ObjectNode?objectNode?=?JsonUtils.getObjectNode();
    ????????objectNode.put("msgtype",EnMsgType.EN_MSG_ACK.toString());
    ????????objectNode.put("srctype",EnMsgType.EN_MSG_CHAT.toString());
    
    ????????//客户端保证用户独立存在且是好友
    ????????Channel?channel?=?CacheUtil.get(id);
    ????????//判断用户是否在线
    ????????if?(channel?==?null){
    ????????????//用户不在线
    ????????????objectNode.put("code",200);
    ????????}else{
    ????????????//用户在线
    ????????????objectNode.put("code",300);
    ????????????//消息转发
    ????????????channel.writeAndFlush(jsonNodes.toString());
    ????????}
    ????????return?objectNode.toString();
    ????}
    
    ????//修改密码
    ????private?static?String?verifyPasswd(ObjectNode?jsonNodes)?{
    ????????int?id?=?jsonNodes.get("id").asInt();
    ????????String?oldPasswd?=?jsonNodes.get("oldPasswd").asText();
    ????????String?newPasswd?=?jsonNodes.get("newPasswd").asText();
    
    ????????boolean?exits?=?userDao.verifyPassword(oldPasswd,?id);
    
    ????????ObjectNode?objectNode?=?JsonUtils.getObjectNode();
    ????????objectNode.put("msgtype",EnMsgType.EN_MSG_VERIFY_PASSWORD.toString());
    ????????objectNode.put("code",200);
    ????????if?(exits){
    ????????????//验证成功
    ????????????userDao.modifyPasswd(newPasswd,id);
    ????????????objectNode.put("code",300);
    ????????}
    ????????return?objectNode.toString();
    ????}
    
    ????//获取信息
    ????private?static?String?getInformation(ObjectNode?jsonNodes)?{
    ????????int?id?=?jsonNodes.get("id").asInt();
    
    ????????information?information?=?informationDao.getInformation(id);
    
    ????????//封装JSON发回客户端
    ????????ObjectNode?objectNode?=?JsonUtils.getObjectNode();
    ????????objectNode.put("msgtype",EnMsgType.EN_MSG_ACK.toString());
    ????????objectNode.put("srctype",EnMsgType.EN_MSG_GETINFORMATION.toString());
    ????????objectNode.put("Nickname",information.getNickname());
    ????????objectNode.put("Signature",information.getSignature());
    
    ????????return?objectNode.toString();
    ????}
    
    ????//修改昵称
    ????private?static?String?modifyNickname(ObjectNode?jsonNodes)?{
    ????????int?id?=?jsonNodes.get("id").asInt();
    ????????String?nickname?=?jsonNodes.get("nickname").asText();
    ????????//进行存储
    ????????informationDao.storeNickname(nickname,id);
    ????????return?"";
    ????}
    
    ????//修改签名
    ????private?static?String?modifySignature(ObjectNode?jsonNodes)?{
    ????????int?id?=?jsonNodes.get("id").asInt();
    ????????String?signature?=?jsonNodes.get("signature").asText();
    ????????//进行存储
    ????????informationDao.storeSignature(signature,id);
    ????????return?"";
    ????}
    
    ????//登录操作
    ????private?static?String?loginOperation(ObjectNode?objectNode,Channel?channel)?{
    
    ????????int?id?=?objectNode.get("id").asInt();
    ????????String?passwd?=?objectNode.get("passwd").asText();
    ????????//进行数据库查询
    ????????boolean?exits?=?userDao.getInformation(id,?passwd);
    
    ????????ObjectNode?jsonNodes?=?JsonUtils.getObjectNode();
    ????????jsonNodes.put("msgtype",EnMsgType.EN_MSG_ACK.toString());
    ????????jsonNodes.put("srctype",EnMsgType.EN_MSG_LOGIN.toString());
    ????????jsonNodes.put("code",300);
    ????????//返回状态码
    ????????if?(exits){
    ????????????jsonNodes.put("code",200);
    
    ????????????//添加用户的在线信息
    ????????????CacheUtil.put(id,channel);
    ????????}
    ????????return?jsonNodes.toString();
    ????}
    }
    

    2.ClientHandler.java

    • 客户端接受来自服务端返回的消息

    • 根据返回的状态码来判断是否操作成功

    package?chat.Project.netty;
    
    import?chat.Frame.chat.ChatFrame;
    import?chat.Frame.chat.linkmen;
    import?chat.Frame.chat.login;
    import?chat.Project.constant.EnMsgType;
    import?chat.util.JsonUtils;
    import?com.fasterxml.jackson.databind.node.ObjectNode;
    import?io.netty.channel.ChannelHandlerContext;
    import?io.netty.channel.SimpleChannelInboundHandler;
    
    import?java.util.concurrent.SynchronousQueue;
    
    
    public?class?ClientHandler?extends?SimpleChannelInboundHandler<String>?{
    
    ????//定义一个同步阻塞队列状态码
    ????public?static?SynchronousQueue<Object>?queue?=?new?SynchronousQueue<>();
    
    ????public?static?String?Nickname;
    ????public?String?Signature;
    
    ????@Override
    ????protected?void?channelRead0(ChannelHandlerContext?channelHandlerContext,?String?s)?throws?Exception?{
    
    ????}
    
    ????//客户端接收数据
    ????@Override
    ????public?void?channelRead(ChannelHandlerContext?ctx,?Object?msg)?throws?Exception?{
    ????????System.out.println(msg);
    ????????//解析服务端发送的消息
    ????????ObjectNode?jsonNodes?=?JsonUtils.getObjectNode((String)?msg);
    ????????String?msgtype?=?jsonNodes.get("msgtype").asText();
    ????????if?(EnMsgType.EN_MSG_ACK.toString().equals(msgtype))?{
    ????????????String?srctype?=?jsonNodes.get("srctype").asText();
    ????????????if?(EnMsgType.EN_MSG_LOGIN.toString().equals(srctype))?{
    ????????????????//登录操作
    ????????????????queue.offer(jsonNodes.get("code").asInt());
    ????????????}else?if(EnMsgType.EN_MSG_GETINFORMATION.toString().equals(srctype)){
    ????????????????//存取信息
    ?????????????????Nickname?=?jsonNodes.get("Nickname").asText();
    ?????????????????Signature?=?jsonNodes.get("Signature").asText();
    ????????????????linkmen.label_1.setText(Nickname);
    ????????????????linkmen.field.setText(Signature);
    ????????????}else?if?(EnMsgType.EN_MSG_CHAT.toString().equals(srctype)){
    ????????????????//发送端返回消息
    ????????????????queue.offer(jsonNodes.get("code").asInt());
    ????????????}else?if?(EnMsgType.EN_MSG_GET_ID.toString().equals(srctype)){
    ????????????????int?uid?=?jsonNodes.get("uid").asInt();
    ????????????????queue.offer(uid);
    ????????????}else?if?(EnMsgType.EN_MSG_GET_FRIEND.toString().equals(srctype)){
    ????????????????//获取登录用户的好友
    ????????????????int?count?=?jsonNodes.get("count").asInt();
    ????????????????login.friend?=?new?String[count];
    ????????????????for?(?int?i?=?0;i<count;i++){
    ????????????????????login.friend[i]?=?jsonNodes.get("res"+i).asText();
    ????????????????????System.out.println(jsonNodes.get("res"+i));
    ????????????????}
    ????????????}else?if?(EnMsgType.EN_MSG_ADD_FRIEND.toString().equals(srctype)){
    ????????????????//添加好友
    ????????????????queue.offer(jsonNodes.get("code").asInt());
    ????????????}else?if?(EnMsgType.EN_MSG_DEL_FRIEND.toString().equals(srctype)){
    ????????????????//删除好友
    ????????????????queue.offer(jsonNodes.get("code").asInt());
    ????????????}else?if?(EnMsgType.EN_MSG_ACTIVE_STATE.toString().equals(srctype)){
    ????????????????//好友在线状态
    ????????????????queue.offer(jsonNodes.get("code").asInt());
    ????????????}
    ????????}else?if?(EnMsgType.EN_MSG_VERIFY_PASSWORD.toString().equals(msgtype)){
    ????????????//修改密码
    ????????????int?code?=?0;
    ????????????code?=?jsonNodes.get("code").asInt();
    ????????????queue.offer(code);
    ????????}else?if?(EnMsgType.EN_MSG_CHAT.toString().equals(msgtype)){
    ????????????//接收端接受消息??封装朋友昵称
    ????????????String?message?=?"?"+?jsonNodes.get("message").asText();
    ????????????//聊天显示框读取消息
    ????????????ChatFrame.sb.append(message+"\n");
    ????????????ChatFrame.displayTextPanel.setText(ChatFrame.sb.toString());
    ????????}
    ????}
    
    }
    

    3.linkmen.java

    这是登录成功的界面

    package?chat.Frame.chat;
    
    import?chat.Frame.operation.alterColumn.changeNickname;
    import?chat.Frame.operation.alterColumn.changePassword;
    import?chat.Frame.operation.alterColumn.changeSignature;
    import?chat.Frame.operation.friendHandle.addFriend;
    import?chat.Frame.operation.friendHandle.delFriend;
    import?chat.Frame.tipFrame;
    import?chat.Project.services.sendServers;
    import?io.netty.channel.Channel;
    
    import?javax.swing.*;
    import?javax.swing.event.ListSelectionEvent;
    import?javax.swing.event.ListSelectionListener;
    import?java.awt.*;
    import?java.awt.event.ItemEvent;
    import?java.awt.event.ItemListener;
    
    
    /**
    ?*?联系人界面
    ?*/
    public?class?linkmen?extends?JFrame?{
    ????//容器
    ????private?JFrame?frame;
    ????//标签
    ????private?JLabel??label_2,?label_3,?label_4,?label;
    ????//昵称
    ????public?static?JLabel?label_1;
    ????//状态框
    ????private?JComboBox?box,?box_1,?box_2;
    ????//图片
    ????private?ImageIcon?icon_1,?icon;
    ????//文本
    ????private?JTextField??field_1;
    ????//个性签名
    ????public?static?JTextField?field;
    ????//面板
    ????private?JPanel?panel_1,?panel_3,?panel;
    ????//滚动面板
    ????public?JScrollPane?panel_2;
    ????//列表
    ????public?static?JList?list;
    ????//与服务端通信的通道
    ????private?Channel?channel;
    ????//用户的id
    ????private?Integer?id;
    ????//暂存oldPasswd
    ????public?static?JLabel?label_5,label_6;
    ????//好友列表数组
    ????private?String[]?fd;
    ????//列表
    ????public?static?DefaultListModel<String>?model;
    
    ????public?linkmen(Integer?id,?Channel?channel,String[]?fd)?{
    ????????this.id?=?id;
    ????????this.channel?=?channel;
    ????????this.fd?=?fd;
    ????}
    
    ????public?void?init()?{
    ????????//初始化面板1并设置信息
    ????????panel_1?=?new?JPanel();
    ????????panel_1.setLayout(null);
    ????????panel_1.setLocation(0,?0);
    ????????panel_1.setBorder(BorderFactory.createTitledBorder("资料卡"));
    ????????panel_1.setSize(new?Dimension(295,?148));
    ????????panel_1.setOpaque(false);
    
    
    ????????//初始化面板3并设置信息
    ????????panel_3?=?new?JPanel();
    ????????panel_3.setLayout(null);
    ????????panel_3.setBorder(BorderFactory.createTitledBorder("系统设置"));
    ????????panel_3.setLocation(0,?617);
    ????????panel_3.setSize(new?Dimension(295,?55));
    ????????panel_3.setOpaque(false);
    
    ????????//设置头像标签
    ????????label_2?=?new?JLabel(new?ImageIcon("E:\\聊天软件\\untitled\\src\\imageSource\\4.png"));
    ????????label_2.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    ????????label_2.setBounds(15,?15,?100,?100);
    ????????panel_1.add(label_2);
    
    ????????//初始暂存标签
    ????????label_5?=?new?JLabel();
    ????????label_6?=?new?JLabel();
    
    ????????//设置昵称标签
    ????????label_1?=?new?JLabel("");
    ????????label_1.setBounds(130,?10,?100,?30);
    ????????label_1.setFont(new?Font("宋体",?Font.PLAIN,?18));
    ????????panel_1.add(label_1);
    
    ????????list?=?new?JList<String>(model);
    ????????//设置每个列表的高
    ????????list.setFixedCellHeight(20);
    ????????list.setSelectionBackground(new?Color(0xD8FF2F));
    ????????list.addListSelectionListener(new?ListSelectionListener()?{
    ????????????@Override
    ????????????public?void?valueChanged(ListSelectionEvent?e)?{
    ????????????????//打开一个聊天窗口
    ????????????????if?(e.getValueIsAdjusting())?{
    ????????????????????for?(int?i?=?0;?i?<?model.size();?i++)?{
    ????????????????????????if?(model.get(i).equals(list.getSelectedValue())){
    ????????????????????????????//获取id有错误
    ????????????????????????????int?ids?=?new?sendServers(channel).getId((String)?list.getSelectedValue());
    ????????????????????????????if?(ids!=0)?{
    ????????????????????????????????new?sendServers(channel).friendIsActive(ids);
    ????????????????????????????????new?ChatFrame(ids,?channel).setVisible(true);
    ????????????????????????????}else{
    ????????????????????????????????System.out.println("好友不存在");
    ????????????????????????????}
    ????????????????????????}
    ????????????????????}
    ????????????????}
    ????????????}
    ????????});
    
    ????????//初始化面板二
    ????????panel_2?=?new?JScrollPane(list);
    ????????panel_2.setBorder(BorderFactory.createTitledBorder("联系人"));
    ????????panel_2.setLocation(0,?147);
    ????????panel_2.setSize(new?Dimension(295,?470));
    ????????panel_2.getViewport().setOpaque(false);
    ????????list.setOpaque(false);
    ????????panel_2.setOpaque(false);
    
    ????????//设置在线状态bBox();
    ????????box?=?new?JComboBox();
    ????????box.addItem("?在线");
    ????????box.addItem("\uD83D\uDCBF隐身");
    ????????box.addItem("\uD83D\uDCBB忙碌");
    ????????box.addItem("?离线");
    ????????box.setBounds(200,?10,?70,?30);
    ????????panel_1.add(box);
    
    ????????//设置个性签名的标签
    ????????label_4?=?new?JLabel("个性签名:");
    ????????label_4.setFont(new?Font("宋体",?Font.PLAIN,?16));
    ????????label_4.setForeground(Color.BLUE);
    ????????label_4.setBounds(120,?50,?100,?20);
    ????????panel_1.add(label_4);
    
    ????????//设置文本
    ????????field?=?new?JTextField("");
    ????????field.setBounds(120,?80,?160,?30);
    ????????panel_1.add(field);
    
    ????????label_3?=?new?JLabel("\uD83D\uDD0D");
    ????????label_3.setForeground(Color.RED);
    ????????label_3.setBounds(10,?122,?20,?20);
    ????????panel_1.add(label_3);
    
    ????????//设置搜索栏
    ????????field_1?=?new?JTextField();
    ????????field_1.setBounds(30,?120,?250,?25);
    ????????panel_1.add(field_1);
    
    ????????//对面板三进行初始化
    ????????box_1?=?new?JComboBox();
    ????????box_1.addItem("\uD83D\uDD12\uD83D\uDD28\uD83D\uDD13");
    ????????box_1.addItem("修改密码");
    ????????box_1.addItem("修改昵称");
    ????????box_1.addItem("修改签名");
    ????????box_1.setBounds(8,?20,?100,?25);
    ????????panel_3.add(box_1);
    ????????box_1.addItemListener(new?ItemListener()?{
    ????????????@Override
    ????????????public?void?itemStateChanged(ItemEvent?e)?{
    ????????????????if?("修改签名".equals(box_1.getSelectedItem()))?{
    ????????????????????//执行一次
    ????????????????????if?(e.getStateChange()?==?ItemEvent.SELECTED)?{
    ????????????????????????changeSignature?changeSignature?=?new?changeSignature(linkmen.this);
    ????????????????????????changeSignature.setVisible(true);
    ????????????????????????field.setText(changeSignature.jTextField.getText());
    ????????????????????????String?signature?=?field.getText();
    ????????????????????????//存储签名的方法
    ????????????????????????new?sendServers(channel).modifySignature(signature,?id);
    ????????????????????}
    ????????????????}
    ????????????????if?("修改密码".equals(box_1.getSelectedItem()))?{
    ????????????????????if?(e.getStateChange()?==?ItemEvent.SELECTED)?{
    ????????????????????????changePassword?changePassword?=?new?changePassword(linkmen.this);
    ????????????????????????changePassword.setVisible(true);
    ????????????????????????label_5.setText(changePassword.oldPassword.getText());
    ????????????????????????String?oldPasswd?=?label_5.getText();
    ????????????????????????label_6.setText(new?String(changePassword.newPassword.getPassword()));
    ????????????????????????String?newPasswd?=?label_6.getText();
    ????????????????????????//进行验证
    ????????????????????????new?sendServers(channel).verifyPasswd(oldPasswd,?id,newPasswd);
    
    ????????????????????}
    ????????????????}
    ????????????????if?("修改昵称".equals(box_1.getSelectedItem()))?{
    ????????????????????if?(e.getStateChange()?==?ItemEvent.SELECTED)?{
    ????????????????????????changeNickname?changeNickname?=?new?changeNickname(linkmen.this);
    ????????????????????????changeNickname.setVisible(true);
    ????????????????????????label_1.setText(changeNickname.jTextField.getText());
    ????????????????????????String?nickname?=?label_1.getText();
    ????????????????????????//存储昵称
    ????????????????????????new?sendServers(channel).modifyNickname(nickname,?id);
    ????????????????????}
    ????????????????}
    ????????????}
    ????????});
    ????????//添加好友、删除好友
    ????????box_2?=?new?JComboBox();
    ????????box_2.addItem("\uD83D\uDC65");
    ????????box_2.addItem("添加好友");
    ????????box_2.addItem("删除好友");
    ????????box_2.setBounds(170,?20,?100,?25);
    ????????box_2.addItemListener(new?ItemListener()?{
    ????????????@Override
    ????????????public?void?itemStateChanged(ItemEvent?e)?{
    ????????????????if?("添加好友".equals(box_2.getSelectedItem()))?{
    ????????????????????if?(e.getStateChange()?==?ItemEvent.SELECTED)?{
    ????????????????????????addFriend?addFriend?=?new?addFriend(linkmen.this);
    ????????????????????????addFriend.setVisible(true);
    ????????????????????????//读取要搜索的ID
    ????????????????????????String?friendIds?=?addFriend.jTextField.getText();
    ????????????????????????//判断是否是字符串
    ????????????????????????if?(judgeDigit(friendIds)){
    ????????????????????????????int?friendId?=?Integer.parseInt(friendIds);
    ????????????????????????????//搜索数据库
    ????????????????????????????new?sendServers(channel).addFriendOperate(friendId,id,label_1.getText());
    ????????????????????????}else?{
    ????????????????????????????new?tipFrame().init("输入参数错误");
    ????????????????????????}
    ????????????????????}
    ????????????????}
    ????????????????if?("删除好友".equals(box_2.getSelectedItem()))?{
    ????????????????????if?(e.getStateChange()?==?ItemEvent.SELECTED)?{
    ????????????????????????delFriend?delFriend?=?new?delFriend(linkmen.this);
    ????????????????????????delFriend.setVisible(true);
    ????????????????????????//对其数据库进行删除操作
    ????????????????????????String?friendIds?=?delFriend.TextField.getText();
    ????????????????????????//判断是否是字符串
    ????????????????????????if(judgeDigit(friendIds)){
    ????????????????????????????int?friendId?=?Integer.parseInt(friendIds);
    ????????????????????????????//操作数据库
    ????????????????????????????new?sendServers(channel).delFriendOperate(friendId,id,label_1.getText());
    ????????????????????????}else{
    ????????????????????????????new?tipFrame().init("输入参数错误");
    ????????????????????????}
    ????????????????????}
    ????????????????}
    ????????????}
    ????????});
    ????????panel_3.add(box_2);
    ????????//设置frame信息
    ????????frame?=?new?JFrame();
    ????????//设置窗体信息
    ????????frame.setTitle("腾讯QQ");
    ????????//给窗体设置图片
    ????????icon_1?=?new?ImageIcon("E:\\聊天软件\\untitled\\src\\imageSource\\3.png");
    ????????frame.setIconImage(icon_1.getImage());
    ????????icon?=?new?ImageIcon("E:\\聊天软件\\untitled\\src\\imageSource\\5.png");
    ????????label?=?new?JLabel(icon);
    ????????//获取窗口的第二层,将label放入
    ????????frame.getLayeredPane().add(label,?new?Integer(Integer.MIN_VALUE));
    ????????//获取frame的顶层容器,并设置为透明
    ????????panel?=?(JPanel)?frame.getContentPane();
    ????????panel.setOpaque(false);
    ????????frame.setLayout(null);
    ????????frame.setLocation(750,?150);
    ????????frame.setSize(287,?700);
    ????????frame.setVisible(true);
    ????????frame.setResizable(false);
    ????????label.setBounds(0,?0,?287,?700);
    ????????frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    ????????frame.add(panel_1);
    ????????frame.add(panel_2);
    ????????frame.add(panel_3);
    ????}
    
    ????public?void?mian()?{
    ????????//初始化面板2并设置信息
    ????????model?=?new?DefaultListModel<>();
    ????????for?(int?i?=?0;?i?<?fd.length;?i++)?{
    ????????????model.addElement(fd[i]);
    ????????}
    ????????init();
    ????????//更新昵称和签名
    ????????new?sendServers(channel).update(id);
    ????????//获取用户的昵称,和好友列表
    
    ????????//设置签名和昵称字体初始样式和大小
    ????????label_1.setFont(new?Font("宋体",?Font.PLAIN,?18));
    ????????field.setFont(new?Font("宋体",?Font.PLAIN,?18));
    ????}
    
    ????//判断是否是数字
    ????private?static?boolean?judgeDigit(String?string){
    ????????for?(int?i?=?0;?i?<?string.length();?i++)?{
    ????????????if?(!Character.isDigit(string.charAt(i))){
    ????????????????return?false;
    ????????????}
    ????????}
    ????????return?true;
    ????}
    }
    

    4.tipFrame

    提示操作状态窗口

    package?chat.Frame;
    
    import?chat.Frame.chat.linkmen;
    import?chat.Frame.operation.alterColumn.changeNickname;
    
    import?javax.swing.*;
    import?java.awt.*;
    import?java.awt.event.ActionEvent;
    import?java.awt.event.ActionListener;
    
    public?class?tipFrame?extends?JDialog?{
    
    ????private?Container?container;
    ????//显示错误信息
    ????public?JLabel?label;
    ????//确认按钮
    ????private?JButton?button;
    
    ????public?tipFrame(){
    
    ????}
    
    ????public?void?init(String?msg){
    ????????container?=?getContentPane();
    ????????label?=?new?JLabel(msg);
    ????????label.setBounds(70,0,200,70);
    ????????label.setFont(new?Font("微软雅黑",Font.PLAIN,20));
    ????????container.add(label);
    ????????button?=?new?JButton("确认");
    ????????button.setBounds(35,50,140,40);
    ????????container.add(button);
    ????????setBounds(780,170,220,140);
    ????????setLayout(null);
    ????????setVisible(true);
    ????????container.setBackground(new?Color(0xD8FFD5));
    ????????//提示窗口前置
    ????????setAlwaysOnTop(true);
    ????????button.addActionListener(new?ActionListener()?{
    ????????????@Override
    ????????????public?void?actionPerformed(ActionEvent?e)?{
    ????????????????tipFrame.this.dispose();
    ????????????}
    ????????});
    ????}
    }
    

    5.运行例图

    1.登录界面

    注册账号和忘记密码没有添加事件现在就是个摆设

    2.联系人界面

    图片

    这里面的所有功能都可以使用

    3.聊天界面

    图片

    这个里面表情按钮没弄好

    4.通信的过程

    图片

    5.修改操作

    图片

    6.好友的操作

    图片

    文章持续更新,可以微信搜一搜「 程序员漫话编程?」第一时间阅读,回复【学习资料】或者【实战项目】有我准备的一线大厂面试资料和实战项目学习资源。
    本文?GitHub?https://github.com/ProceduralZC/JavaDevGuide?已经收录,有大厂面试完整考点,欢迎Star。

    cs