您的位置:首页 > 移动开发 > 微信开发

Java练手小程序——QQ聊天

2017-11-16 19:51 211 查看

1.思路图

       


2.主要功能

        实现一对一聊天
实现多对多聊天
好友上线自动刷新功能

3.知识点

      界面布局:一是流布局,二是卡片布局(现在应该都不用了)
 socket通信之对象流objectinput/outputStream

         将线程里面的信息显示到界面上

4.项目代码

       4.1服务端

          


            common下有三个类:

            Message.java

            package com.qq.common;

public class Message implements java.io.Serializable{

private String mesType;

private String sender;
private String getter;
private String con;
private String sendTime;

public String getSender() {
return sender;
}

public void setSender(String sender) {
this.sender = sender;
}

public String getGetter() {
return getter;
}

public void setGetter(String getter) {
this.getter = getter;
}

public String getCon() {
return con;
}

public void setCon(String con) {
this.con = con;
}

public String getSendTime() {
return sendTime;
}

public void setSendTime(String sendTime) {
this.sendTime = sendTime;
}

public String getMesType() {
return mesType;
}

public void setMesType(String mesType) {
this.mesType = mesType;
}
}
            
            接口MessageType.java

            /**
* 定义包的种类
*/
package com.qq.common;

public interface MessageType {

String message_succeed="1";//表明是登陆成功
String message_login_fail="2";//表明登录失败
String message_comm_mes="3";//普通信息包
String message_get_onLineFriend="4";//要求在线好友的包
String message_ret_onLineFriend="5";//返回在线好友的包
}

             User.java

 /**
* 这是用户信息类
*/
package com.qq.common;

public class User implements java.io.Serializable {

private String userId;
private String passwd;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
}
       
            Model下面有三个类:

            ManageClientThread.java

            package com.qq.server.model;

import java.util.*;
public class ManageClientThread {

public static HashMap hm=new HashMap<String, SerConClientThread>();

//向hm中添加一个客户端通讯线程
public static void addClientThread(String uid,SerConClientThread ct)
{
hm.put(uid, ct);
}

public static SerConClientThread getClientThread(String uid)
{
return (SerConClientThread)hm.get(uid);
}

//返回当前在线的人的情况
public static String getAllOnLineUserid()
{
//使用迭代器完成
Iterator it=hm.keySet().iterator();
String res="";
while(it.hasNext())
{
res+=it.next().toString()+" ";
}
return res;
}
}

            MyQqServer.java

/**
* 这是qq服务器,它在监听,等待某个qq客户端,来连接
*/
package com.qq.server.model;
import com.qq.common.*;
import java.net.*;
import java.io.*;
import java.util.*;
public class MyQqServer {

public MyQqServer()
{

try {

//在9999监听
System.out.println("我是服务器,在9999监听");
ServerSocket ss=new ServerSocket(9999);
//阻塞,等待连接
while(true)
{
Socket s=ss.accept();

//接收客户端发来的信息.

ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
User u=(User)ois.readObject();
System.out.println("服务器接收到用户id:"+u.getUserId()+" 密码:"+u.getPasswd());
Message m=new Message();
ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
if(u.getPasswd().equals("123456"))
{
//返回一个成功登陆的信息报

m.setMesType("1");
oos.writeObject(m);

//这里就单开一个线程,让该线程与该客户端保持通讯.
SerConClientThread scct=new SerConClientThread(s);
ManageClientThread.addClientThread(u.getUserId(), scct);
//启动与该客户端通信的线程.
scct.start();

//并通知其它在线用户.
scct.notifyOther(u.getUserId());
}else{
m.setMesType("2");
oos.writeObject(m);
//关闭Socket
s.close();

}

}

} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}finally{

}

}

}


                     SerConClientThread.java
/**
* 功能:是服务器和某个客户端的通信线程
*/
package com.qq.server.model;

import java.util.*;
import java.net.*;
import java.io.*;
import com.qq.common.*;
public class SerConClientThread extends Thread{

Socket s;

public SerConClientThread(Socket s)
{
//把服务器和该客户端的连接赋给s
this.s=s;
}

//让该线程去通知其它用户
public void notifyOther(String iam)
{
//得到所有在线的人的线程
HashMap hm=ManageClientThread.hm;
Iterator it=hm.keySet().iterator();

while(it.hasNext())
{
Message m=new Message();
m.setCon(iam);
m.setMesType(MessageType.message_ret_onLineFriend);
//取出在线人的id
String onLineUserId=it.next().toString();
try {
ObjectOutputStream oos=new ObjectOutputStream(ManageClientThread.getClientThread(onLineUserId).s.getOutputStream());
m.setGetter(onLineUserId);
oos.writeObject(m);
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}

}
}

public void run()
{

while(true)
{

//这里该线程就可以接收客户端的信息.
try {
ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
Message m=(Message)ois.readObject();

// System.out.println(m.getSender()+" 给 "+m.getGetter()+" 说:"+m.getCon());

//对从客户端取得的消息进行类型判断,然后做相应的处理
if(m.getMesType().equals(MessageType.message_comm_mes))
{
//一会完成转发.
//取得接收人的通信线程
SerConClientThread sc=ManageClientThread.getClientThread(m.getGetter());
ObjectOutputStream oos=new ObjectOutputStream(sc.s.getOutputStream());
oos.writeObject(m);
}else if(m.getMesType().equals(MessageType.message_get_onLineFriend))
{
System.out.println(m.getSender()+" 要他的好友");
//把在服务器的好友给该客户端返回.
String res=ManageClientThread.getAllOnLineUserid();
Message m2=new Message();
m2.setMesType(MessageType.message_ret_onLineFriend);
m2.setCon(res);
m2.setGetter(m.getSender());
ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
oos.writeObject(m2);
}

} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}

}

}
}


                   view下有一个类
            MySererFrame.java

                   /**
* 这是服务器端的控制界面,可以完成启动服务器,关闭服务器
* 可以管理和监控用户.
*/
package com.qq.server.view;

import javax.swing.*;

import com.qq.server.model.MyQqServer;

import java.awt.*;
import java.awt.event.*;
public class MyServerFrame extends JFrame implements ActionListener {

JPanel jp1;
JButton jb1,jb2;

public static void main(String[] args) {
// TODO Auto-generated method stub
MyServerFrame mysf=new MyServerFrame();
}

public MyServerFrame()
{
jp1=new JPanel();
jb1=new JButton("启动服务器");
jb1.addActionListener(this);
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);
}

public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if(arg0.getSource()==jb1)
{
new MyQqServer();
}
}

}


            4.2客户端

            


             common下面有三个类

             Message.java

             package com.qq.common;

public class Message implements java.io.Serializable{

private String mesType;

private String sender;
private String getter;
private String con;
private String sendTime;
public String getSender() {
return sender;
}

public void setSender(String sender) {
this.sender = sender;
}

public String getGetter() {
return getter;
}

public void setGetter(String getter) {
this.getter = getter;
}

public String getCon() {
return con;
}

public void setCon(String con) {
this.con = con;
}

public String getSendTime() {
return sendTime;
}

public void setSendTime(String sendTime) {
this.sendTime = sendTime;
}

public String getMesType() {
return mesType;
}

public void setMesType(String mesType) {
this.mesType = mesType;
}
}

            MessageType.java

            /**
* 定义包的种类
*/
package com.qq.common;

public interface MessageType {

String message_succeed="1";//表明是登陆成功
String message_login_fail="2";//表明登录失败
String message_comm_mes="3";//普通信息包
String message_get_onLineFriend="4";//要求在线好友的包
String message_ret_onLineFriend="5";//返回在线好友的包
}

            User.java

/**
* 这是用户信息类
*/
package com.qq.common;

public class User implements java.io.Serializable {

private String userId;
private String passwd;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
}


            Model里面有两个类
            QqClientConServer.java

/**
* 这是客户端连接服务器的后台
*/
package com.qq.client.model;
import com.qq.client.tools.*;
import java.util.*;
import java.net.*;
import java.io.*;
import com.qq.common.*;
public class QqClientConServer {

public Socket s;

//发送第一次请求
public boolean sendLoginInfoToServer(Object o)
{
boolean b=false;
try {
System.out.println("kk");
s=new Socket("127.0.0.1",9999);
ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
oos.writeObject(o);

ObjectInputStream ois=new ObjectInputStream(s.getInputStream());

Message ms=(Message)ois.readObject();
//这里就是验证用户登录的地方
if(ms.getMesType().equals("1"))
{
//就创建一个该qq号和服务器端保持通讯连接得线程
ClientConServerThread ccst=new ClientConServerThread(s);
//启动该通讯线程
ccst.start();
ManageClientConServerThread.addClientConServerThread
(((User)o).getUserId(), ccst);
b=true;
}else{
//关闭Scoket
s.close();
}

} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}finally{

}
return b;
}

public void SendInfoToServer(Object o)
{
/*try {
Socket s=new Socket("127.0.0.1",9999);

} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}finally{

}*/
}
}


             QqClientUser.java
package com.qq.client.model;

import com.qq.common.*;
public class QqClientUser {

public boolean checkUser(User u)
{
return new QqClientConServer().sendLoginInfoToServer(u);
}

}


            Tools里面有四个类
            ClientConServerThread.java

/**
* 这是客户端和服务器端保持通讯的线程.
*/
package com.qq.client.tools;

import java.io.*;
import java.net.*;

import com.qq.client.view.QqChat;
import com.qq.client.view.QqFriendList;
import com.qq.common.*;
public class ClientConServerThread extends Thread {

private Socket s;

//构造函数
public ClientConServerThread(Socket s)
{
this.s=s;
}

public void run()
{
while(true)
{
//不停的读取从服务器端发来的消息
try {

ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
Message m=(Message)ois.readObject();
/* System.out.println("读取到从服务发来的消息"+ m.getSender() +" 给 "+m.getGetter()+" 内容"+
m.getCon());*/

if(m.getMesType().equals(MessageType.message_comm_mes))
{

//把从服务器获得消息,显示到该显示的聊天界面
QqChat qqChat=ManageQqChat.getQqChat(m.getGetter()+" "+m.getSender());
//显示
qqChat.showMessage(m);
}else if(m.getMesType().equals(MessageType.message_ret_onLineFriend))
{
System.out.println("客户端接收到"+m.getCon());
String con=m.getCon();
String friends[]=con.split(" ");
String getter=m.getGetter();
System.out.println("getter="+getter);
//修改相应的好友列表.
QqFriendList qqFriendList=ManageQqFriendList.getQqFriendList(getter);

// if(qqFriendList)
//更新在线好友.
if(qqFriendList!=null)
{
qqFriendList.upateFriend(m);
}
}
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
}
}

public Socket getS() {
return s;
}

public void setS(Socket s) {
this.s = s;
}

}


             ManageClientConServerThread.java
/**
* 这是一个管理客户端和服务器保持通讯的线程类
*/
package com.qq.client.tools;

import java.util.*;
public class ManageClientConServerThread {

private static HashMap hm=new HashMap<String, ClientConServerThread>();

//把创建好的ClientConServerThread放入到hm
public static void addClientConServerThread(String qqId,ClientConServerThread ccst)
{
hm.put(qqId, ccst);
}

//可以通过qqId取得该线程
public static ClientConServerThread getClientConServerThread(String qqId)
{
return (ClientConServerThread)hm.get(qqId);
}
}


             ManageQqChat.java
/**
* 这是一个管理用户聊天界面的类
*/
package com.qq.client.tools;

import java.util.*;
import com.qq.client.view.*;
public class ManageQqChat {

private static HashMap hm=new HashMap<String, QqChat>();

//加入
public static void addQqChat(String loginIdAnFriendId,QqChat qqChat)
{
hm.put(loginIdAnFriendId, qqChat);
}
//取出
public static QqChat getQqChat(String loginIdAnFriendId )
{
return (QqChat)hm.get(loginIdAnFriendId);
}

}


           ManageQqFriendList.java
/**
* 管理好友、黑名单..界面类
*/
package com.qq.client.tools;

import java.util.*;
import java.io.*;
import com.qq.client.view.*;
public class ManageQqFriendList {

private static HashMap hm=new HashMap<String, QqFriendList>();

public static void addQqFriendList(String qqid,QqFriendList qqFriendList){

hm.put(qqid, qqFriendList);
}

public static QqFriendList getQqFriendList(String qqId)
{
return (QqFriendList)hm.get(qqId);
}
}


 

            View里面有三个类
            QqChat.java
/**
* 这是与好友聊天的界面
* 因为客户端,要处于读取的状态,因此我们把它做成一个线程
*/
package com.qq.client.view;

import com.qq.client.tools.*;
import com.qq.client.model.*;
import com.qq.common.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class QqChat extends JFrame implements ActionListener{

JTextArea jta;
JTextField jtf;
JButton jb;
JPanel jp;
String ownerId;
String friendId;
public static void main(String[] args) {
// TODO Auto-generated method stub
//QqChat qqChat=new QqChat("1");
}

public QqChat(String ownerId,String friend)
{
this.ownerId=ownerId;
this.friendId=friend;
jta=new JTextArea();
jtf=new JTextField(15);
jb=new JButton("发送");
jb.addActionListener(this);
jp=new JPanel();
jp.add(jtf);
jp.add(jb);

this.add(jta,"Center");
this.add(jp,"South");
this.setTitle(ownerId+" 正在和 "+friend+" 聊天");
this.setIconImage((new ImageIcon("image/qq.gif").getImage()));
this.setSize(300, 200);
this.setVisible(true);

}

//写一个方法,让它显示消息
public void showMessage(Message m)
{
String info=m.getSender()+" 对 "+m.getGetter()+" 说:"+m.getCon()+"\r\n";
this.jta.append(info);
}

public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if(arg0.getSource()==jb)
{
//如果用户点击了,发送按钮
Message m=new Message();
m.setMesType(MessageType.message_comm_mes);
m.setSender(this.ownerId);
m.setGetter(this.friendId);
m.setCon(jtf.getText());
m.setSendTime(new java.util.Date().toString());
//发送给服务器.
try {
ObjectOutputStream oos=new ObjectOutputStream
(ManageClientConServerThread.getClientConServerThread(ownerId).getS().getOutputStream());
oos.writeObject(m);
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}

}

}

}


             QqClientLogin.java
/**
* 功能:qq客户端登录界面
*/
package com.qq.client.view;
import com.qq.common.*;
import com.qq.client.tools.*;
import java.io.*;
import javax.swing.*;

import com.qq.client.model.QqClientUser;
import com.qq.common.User;

import java.awt.*;
import java.awt.event.*;
public class QqClientLogin extends JFrame implements ActionListener{

//定义北部需要的组件

JLabel jbl1;

//定义中部需要的组件
//.中部有三个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) {
// TODO Auto-generated method stub
QqClientLogin qqClientLogin=new QqClientLogin();
}

public QqClientLogin()
{
//处理北部
jbl1=new JLabel(new ImageIcon("image/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("image/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("image/denglu.gif"));
//响应用户点击登录
jp1_jb1.addActionListener(this);
jp1_jb2=new JButton(new ImageIcon("image/quxiao.gif"));

jp1_jb3=new JButton(new ImageIcon("image/xiangdao.gif"));

//把三个按钮放入到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);
}

public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
//如果用户点击登录
if(arg0.getSource()==jp1_jb1)
{
QqClientUser qqClientUser=new QqClientUser();
User u=new User();
u.setUserId(jp2_jtf.getText().trim());
u.setPasswd(new String(jp2_jpf.getPassword()));

if(qqClientUser.checkUser(u))
{
try {
//把创建好友列表的语句提前.
QqFriendList qqList=new QqFriendList(u.getUserId());
ManageQqFriendList.addQqFriendList(u.getUserId(), qqList);

//发送一个要求返回在线好友的请求包.
ObjectOutputStream oos=new ObjectOutputStream
(ManageClientConServerThread.getClientConServerThread(u.getUserId()).getS().getOutputStream());

//做一个Message
Message m=new Message();
m.setMesType(MessageType.message_get_onLineFriend);
//指明我要的是这个qq号的好友情况.
m.setSender(u.getUserId());
oos.writeObject(m);
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}

//关闭掉登录界面
this.dispose();
}else{
JOptionPane.showMessageDialog(this,"用户名密码错误");
}
}
}

}


            QqFriendList.java
/**
* 我的好友列表,(也包括陌生人,黑名单)
*/
package com.qq.client.view;

import com.qq.client.tools.*;
import com.qq.common.Message;

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;
public class QqFriendList extends JFrame implements ActionListener,MouseListener{

//处理第一张卡片.

JPanel jphy1,jphy2,jphy3;
JButton jphy_jb1,jphy_jb2,jphy_jb3;
JScrollPane jsp1;
String owner;
//处理第二张卡片(陌生人).

JPanel jpmsr1,jpmsr2,jpmsr3;
JButton jpmsr_jb1,jpmsr_jb2,jpmsr_jb3;
JScrollPane jsp2;
JLabel []jb1s;
//把整个JFrame设置成CardLayout
CardLayout cl;
public static void main(String[] args) {
// TODO Auto-generated method stub
// QqFriendList qqFriendList=new QqFriendList();
}

//更新在线的好友情况
public void upateFriend(Message m)
{
String onLineFriend[]=m.getCon().split(" ");

for(int i=0;i<onLineFriend.length;i++)
{

jb1s[Integer.parseInt(onLineFriend[i])-1].setEnabled(true);
}
}

public QqFriendList(String ownerId)
{
this.owner=ownerId;
//处理第一张卡片(显示好友列表)
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好友.
jb1s =new JLabel[50];

for(int i=0;i<jb1s.length;i++)
{
jb1s[i]=new JLabel(i+1+"",new ImageIcon("image/mm.jpg"),JLabel.LEFT);
jb1s[i].setEnabled(false);
if(jb1s[i].getText().equals(ownerId))
{
jb1s[i].setEnabled(true);
}
jb1s[i].addMouseListener(this);
jphy2.add(jb1s[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,初始化20陌生人.
JLabel []jb1s2=new JLabel[20];

for(int i=0;i<jb1s2.length;i++)
{
jb1s2[i]=new JLabel(i+1+"",new ImageIcon("image/mm.jpg"),JLabel.LEFT);
jpmsr2.add(jb1s2[i]);
}

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

jsp2=new JScrollPane(jpmsr2);

//对jphy1,初始化
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.setTitle(ownerId);
this.setSize(140, 400);
this.setVisible(true);

}

public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
//如果点击了陌生人按钮,就显示第二张卡片
if(arg0.getSource()==jphy_jb2)
{
cl.show(this.getContentPane(), "2");
}else if(arg0.getSource()==jpmsr_jb1){
cl.show(this.getContentPane(), "1");
}
}

public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
//响应用户双击的事件,并得到好友的编号.
if(arg0.getClickCount()==2)
{
//得到该好友的编号
String friendNo=((JLabel)arg0.getSource()).getText();
//System.out.println("你希望和 "+friendNo+" 聊天");
QqChat qqChat=new QqChat(this.owner,friendNo);

//把聊天界面加入到管理类
ManageQqChat.addQqChat(this.owner+" "+friendNo, qqChat);

}
}

public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
JLabel jl=(JLabel)arg0.getSource();
jl.setForeground(Color.red);
}

public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
JLabel jl=(JLabel)arg0.getSource();
jl.setForeground(Color.black);
}

public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub

}

public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub

}

}

4.结语

      一个小程序挺有意思,也了解了一下socket机制,线程的运用很巧妙,挺锻炼思维,希望小编与读者可以共同交流成长。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息