前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >仿QQ聊天室项目_仿QQ程序设计与开发

仿QQ聊天室项目_仿QQ程序设计与开发

作者头像
全栈程序员站长
发布2022-10-03 16:56:02
发布2022-10-03 16:56:02
1.5K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

仿QQ聊天室项目 完整代码见 https://github.com/skyerhxx/QQ-Project 完整项目结构 QQ_Client

QQ_Server

二者之间的连接简图

一些界面的程序的对应关系 QqClientLogin

QqFriendList

QqChat

MyServerFrame

开发过程 登录界面

创建普通Java项目 并创建model、view、tools、common 四个包

在view下创建QqClientLogin.java

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 功能: qq客户端登录界面
 */

package com.qq.client.view;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class QqClientLogin extends JFrame {

    //定义界面上部需要的组件
    JLabel jbl1;

    //定义界面中部需要的组件

    //定义界面下部需要的组件
    JPanel jp1;
    JButton jp1_jb1,jp1_jb2,jp1_jb3;

    public static void main(String[] args){
        QqClientLogin qqClientLogin = new QqClientLogin();

    }
    public QqClientLogin(){
        //处理界面上部
        jbl1 = new JLabel(new ImageIcon("./src/resources/tou.gif"));
        this.add(jbl1,"North");
        this.setSize(350,240);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true); //设置让它可见

    }
}

 

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 功能: qq客户端登录界面
 */

package com.qq.client.view;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class QqClientLogin extends JFrame {

    //定义界面上部需要的组件
    JLabel jbl1;

    //定义界面中部需要的组件

    //定义界面下部需要的组件
    JPanel jp1;
    JButton jp1_jb1,jp1_jb2,jp1_jb3;

    public static void main(String[] args){
        QqClientLogin qqClientLogin = new QqClientLogin();

    }
    public QqClientLogin(){
        //处理界面上部
        jbl1 = new JLabel(new ImageIcon("./src/resources/tou.gif"));

        //处理界面下部
        jp1 = new JPanel();
        jp1_jb1 = new JButton(new ImageIcon("./src/resources/denglu.gif"));
        jp1_jb2 = new JButton(new ImageIcon("./src/resources/quxiao.gif"));
        jp1_jb3 = new JButton(new ImageIcon("./src/resources/xiangdao.gif"));
        //把3个按钮放入到jp1
        jp1.add(jp1_jb1);
        jp1.add(jp1_jb2);
        jp1.add(jp1_jb3);


        this.add(jbl1,"North");
        //把jp1放在页面下部
        this.add(jp1,"South");
        this.setSize(350,240);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true); //设置让它可见

    }
}

 

代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 功能: qq客户端登录界面
 */

package com.qq.client.view;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class QqClientLogin extends JFrame {

    //定义界面上部需要的组件
    JLabel jbl1;

    //定义界面中部需要的组件
        //中部有3个JPanel, 由一个选项卡窗口管理
    JTabbedPane jtp;
    JPanel jp2,jp3,jp4;
    JLabel jp2_jbl1,jp2_jbl2,jp2_jbl3,jp2_jbl4;
    JButton jp2_jb1;
    JTextField jp2_jtf;
    JPasswordField jp2_jpf;
    JCheckBox jp2_jcb1,jp2_jcb2;


    //定义界面下部需要的组件
    JPanel jp1;
    JButton jp1_jb1,jp1_jb2,jp1_jb3;

    public static void main(String[] args){
        QqClientLogin qqClientLogin = new QqClientLogin();

    }
    public QqClientLogin(){
        //处理界面上部
        jbl1 = new JLabel(new ImageIcon("./src/resources/tou.gif"));
        //处理界面中部
        jp2 = new JPanel(new GridLayout(3,3));

        jp2_jbl1 = new JLabel("QQ号码",JLabel.CENTER);
        jp2_jbl2 = new JLabel("QQ密码",JLabel.CENTER);
        jp2_jbl3 = new JLabel("忘记密码",JLabel.CENTER);
        jp2_jbl3.setForeground(Color.blue);
        jp2_jbl4 = new JLabel("申请密码保护",JLabel.CENTER);
        jp2_jb1 = new JButton(new ImageIcon("./src/resources/clear.gif"));
        jp2_jtf = new JTextField();
        jp2_jpf = new JPasswordField();
        jp2_jcb1 = new JCheckBox("隐身登录");
        jp2_jcb2 = new JCheckBox("记住密码");
        //把控件按照顺序加入到jp2
        jp2.add(jp2_jbl1);
        jp2.add(jp2_jtf);
        jp2.add(jp2_jb1);
        jp2.add(jp2_jbl2);
        jp2.add(jp2_jpf);
        jp2.add(jp2_jbl3);
        jp2.add(jp2_jcb1);
        jp2.add(jp2_jcb2);
        jp2.add(jp2_jbl4);
        //创建选项卡窗口
        jtp = new JTabbedPane();
        jtp.add("QQ号码",jp2);
        jp3 = new JPanel();
        jtp.add("手机号码",jp3);
        jp4 = new JPanel();
        jtp.add("电子邮件",jp4);


        //处理界面下部
        jp1 = new JPanel();
        jp1_jb1 = new JButton(new ImageIcon("./src/resources/denglu.gif"));
        jp1_jb2 = new JButton(new ImageIcon("./src/resources/quxiao.gif"));
        jp1_jb3 = new JButton(new ImageIcon("./src/resources/xiangdao.gif"));
        //把3个按钮放入到jp1
        jp1.add(jp1_jb1);
        jp1.add(jp1_jb2);
        jp1.add(jp1_jb3);


        this.add(jbl1,"North");
        this.add(jtp,"Center");
        //把jp1放在页面下部
        this.add(jp1,"South");
        this.setSize(350,240);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true); //设置让它可见

    }
}

 

好友列表界面 新建QqFriendList.java

代码语言:javascript
代码运行次数:0
运行
复制
/*
    我的好友列表,也包括陌生人和黑名单
 */
package com.qq.client.view;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class QqFriendList extends JFrame{

    //处理第一张卡片
    JPanel jphy1,jphy2,jphy3;
    JButton jphy_jb1,jphy_jb2,jphy_jb3;
    JScrollPane jsp1;

    public static void main(String[] args) {
        QqFriendList qqFriendList = new QqFriendList();
    }

    public QqFriendList(){
        //处理第一张卡片
        jphy_jb1 = new JButton("我的好友");
        jphy_jb2 = new JButton("陌生人");
        jphy_jb3 = new JButton("黑名单");
        jphy1 = new JPanel(new BorderLayout());
        //假定有50个好友
        jphy2 = new JPanel(new GridLayout(50,1,4,4));
        //给jphy2初始化50个好友
        JLabel []jbls = new JLabel[50];
        for (int i = 0; i < jbls.length; i++) {
            jbls[i] = new JLabel(i+1+"", new ImageIcon("./src/resources/mm.jpg"),JLabel.LEFT);
            jphy2.add(jbls[i]);
        }


        jphy3 = new JPanel(new GridLayout(2,1));
        //把两个按钮加入到jphy3
        jphy3.add(jphy_jb2);
        jphy3.add(jphy_jb3);



        jsp1 = new JScrollPane(jphy2);

        //对jphy1初始化
        jphy1.add(jphy_jb1,"North");
        jphy1.add(jsp1,"Center");
        jphy1.add(jphy3,"South");

        this.add(jphy1,"Center");
        this.setSize(140,400);
        this.setVisible(true);
    }
}

 

代码语言:javascript
代码运行次数:0
运行
复制
/*
我的好友列表,也包括陌生人和黑名单
*/
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class QqFriendList extends JFrame implements ActionListener,MouseListener{
//处理第一张卡片(好友)
//hy = 好友
JPanel jpmsr1,jpmsr2,jpmsr3;
JButton jpmsr_jb1,jpmsr_jb2,jpmsr_jb3;
JScrollPane jsp2;
//处理第二张卡片(陌生人)
//msr = 陌生人
JPanel jphy1,jphy2,jphy3;
JButton jphy_jb1,jphy_jb2,jphy_jb3;
JScrollPane jsp1;
//把整个JFrame设置成CardLayout布局
CardLayout cl;
public static void main(String[] args) {
QqFriendList qqFriendList = new QqFriendList();
}
public QqFriendList(){
//处理第一张卡片(显示好友列表)
jphy_jb1 = new JButton("我的好友");
jphy_jb2 = new JButton("陌生人");
jphy_jb2.addActionListener(this);
jphy_jb3 = new JButton("黑名单");
jphy1 = new JPanel(new BorderLayout());
//假定有50个好友
jphy2 = new JPanel(new GridLayout(50,1,4,4));
//给jphy2初始化50个好友
JLabel []jbls = new JLabel[50];
for (int i = 0; i < jbls.length; i++) {
jbls[i] = new JLabel(i+1+"", new ImageIcon("./src/resources/mm.jpg"),JLabel.LEFT);
jbls[i].addMouseListener(this);
jphy2.add(jbls[i]);
}
jphy3 = new JPanel(new GridLayout(2,1));
//把两个按钮加入到jphy3
jphy3.add(jphy_jb2);
jphy3.add(jphy_jb3);
jsp1 = new JScrollPane(jphy2);
//对jphy1初始化
jphy1.add(jphy_jb1,"North");
jphy1.add(jsp1,"Center");
jphy1.add(jphy3,"South");
//处理第二张卡片
jpmsr_jb1 = new JButton("我的好友");
jpmsr_jb1.addActionListener(this);
jpmsr_jb2 = new JButton("陌生人");
jpmsr_jb3 = new JButton("黑名单");
jpmsr1 = new JPanel(new BorderLayout());
//假定有20个陌生人
jpmsr2 = new JPanel(new GridLayout(20,1,4,4));
//给jphy2初始化50个陌生人
JLabel []jbls2 = new JLabel[20];
for (int i = 0; i < jbls2.length; i++) {
jbls2[i] = new JLabel(i+1+"", new ImageIcon("./src/resources/mm.jpg"),JLabel.LEFT);
jpmsr2.add(jbls2[i]);
}
jpmsr3 = new JPanel(new GridLayout(2,1));
//把两个按钮加入到jpmsr3
jpmsr3.add(jpmsr_jb1);
jpmsr3.add(jpmsr_jb2);
jsp2 = new JScrollPane(jpmsr2);
//对jpmsr1初始化
jpmsr1.add(jpmsr3,"North");
jpmsr1.add(jsp2,"Center");
jpmsr1.add(jpmsr_jb3,"South");
cl = new CardLayout();
this.setLayout(cl);
this.add(jphy1,"1");
this.add(jpmsr1,"2");
this.setSize(140,400);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent arg0) {
//如果用户点击了陌生人按钮,就显示第二张卡片
if(arg0.getSource() == jphy_jb2){
cl.show(this.getContentPane(),"2");
}
else if(arg0.getSource()==jpmsr_jb1){
cl.show(this.getContentPane(),"1");
}
}
@Override
public void mouseClicked(MouseEvent arg0) {
//响应用户双击的事件,并得到好友的编号
if(arg0.getClickCount() == 2){
//得到该好友的编号
String friendNo = ((JLabel)arg0.getSource()).getText();
System.out.println("你希望和 "+friendNo+" 聊天");
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent arg0) {
JLabel jl = (JLabel)arg0.getSource();
jl.setForeground(Color.red);
}
@Override
public void mouseExited(MouseEvent arg0) {
JLabel jl = (JLabel)arg0.getSource();
jl.setForeground(Color.black);
}
}

 

效果是鼠标放上变红,移开又变黑 双击会输出 你希望和谁聊天 聊天界面 对象流 Qqchat()

代码语言:javascript
代码运行次数:0
运行
复制
/*
这是与好友聊天的界面
*/
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class QqChat extends JFrame {
JTextArea jta;
JTextField jtf;
JButton jb;
JPanel jp;
public static void main(String[] args) {
QqChat qqChat = new QqChat("1");
}
public QqChat(String friend){
jta = new JTextArea();
jtf = new JTextField(15);
jb = new JButton("发送");
jp = new JPanel();
jp.add(jtf);
jp.add(jb);
this.add(jta,"Center");
this.add(jp,"South");
this.setTitle("你正在和 "+friend+" 聊天");
this.setIconImage(new ImageIcon("./src/resources/qq.gif").getImage());
this.setSize(300,200);
this.setVisible(true);
}
}
 

接下来是 由它

到它

先写服务器,先不涉及数据库

代码语言:javascript
代码运行次数:0
运行
复制
/*
这是服务器端的控制界面,可以完成启动服务器,关闭服务器
可以管理和监控用户
*/
package com.qq.server.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyServerFrame extends JFrame {
JPanel jp1;
JButton jb1,jb2;
public static void main(String[] args) {
MyServerFrame mysf = new MyServerFrame();
}
public MyServerFrame(){
jp1 = new JPanel();
jb1 = new JButton("启动服务器");
jb2 = new JButton("关闭服务器");
jp1.add(jb1);
jp1.add(jb2);
this.add(jp1);
this.setSize(500,400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}

 

用对象流获取用户发送的消息 如何在网络间传递对象:对象流 对象流还要将对象序列化,才能在网络上传输 登录验证

MyServerFrame是服务器 先启动QQ_Server中的MyServerFrame

启动QQ_Client中的QqClientLogin

输入正确的密码123456

一对一聊天

多对多的聊天 实现多人聊天 每一个用户登录都会开一个线程. 你有3个用户登录就有3个线程同时在处理这3个用户与服务器的交互

把接收到的消息,显示到该显示的聊天界面(这是第7集的内容)

好友在线提示 好友在线,头像就是彩色的,不在线就是灰色的

当用户一登录成功了之后,迅速发一个请求包,让服务器给返回有哪些人在线 所有在线的人都存在一个HashMap里面,遍历就可找到所有的

现在可以看到在线的好友头像点亮,不在线的头像是灰色 但是后面登录的人可以看到前面登录的人,前面登录的人看不到后面登录的人 下面是第8集 后面登录的人应该有责任去通知其他在线的人他上线了,然后去更改他们的好友在线情况

功能全部实现 至此,项目完结

参考视频: https://www.bilibili.com/video/BV174411w7SY?p=1

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/197211.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月4日 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档