仿QQ聊天室项目 完整代码见 https://github.com/skyerhxx/QQ-Project 完整项目结构 QQ_Client
QQ_Server
二者之间的连接简图
一些界面的程序的对应关系 QqClientLogin
QqFriendList
QqChat
MyServerFrame
开发过程 登录界面
创建普通Java项目 并创建model、view、tools、common 四个包
在view下创建QqClientLogin.java
/**
* 功能: 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); //设置让它可见
}
}
/**
* 功能: 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); //设置让它可见
}
}
/**
* 功能: 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
/*
我的好友列表,也包括陌生人和黑名单
*/
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);
}
}
/*
我的好友列表,也包括陌生人和黑名单
*/
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()
/*
这是与好友聊天的界面
*/
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);
}
}
接下来是 由它
到它
先写服务器,先不涉及数据库
/*
这是服务器端的控制界面,可以完成启动服务器,关闭服务器
可以管理和监控用户
*/
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://javaforall.cn/197211.html原文链接:https://javaforall.cn