java语言实践课内容:聊天室小程序或QQ
功能要求: 聊天室:使用图形用户界面,能实现一个聊天室中多人聊天,可以两人私聊。 QQ:实现类似QQ登录、聊天等功能。 注意:有一定等级。完全照搬别人的代码,不超过70分。 提示:使用socket通信 前面是逐步讲解,要是想看最终代码,请直接找到该文章的最下面 //
准备工作 建立包,类,文件 插入图片要创建一个文件夹,文件夹里保存的就是所需要的图片啦,比如我创建的文件夹为image; 两个设备上进行通信,要用到socket通信协议,即客户端的内容先传到服务器,在服务器上处理,传回客户端 image素材文件里存放的图片 链接:https://pan.baidu.com/s/1zns86NC6Qm80xKZHMIRSbA 提取码:3f6w
//
1.首先我们先建一个qq登陆界面
成品图如下: 详细代码及注释如下
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class QqClientlLogin extends JFrame{
JLabel jup;
JPanel jmid ;
JLabel jmid_num1,jmid_key1;
JTextField jmid_num2;
JPasswordField jmid_key2;
JCheckBox jmid_rember,jmid_automatic;
JPanel jdown;
JButton jdown_1,jdown_2;
public QqClientlLogin()
{
jup=new JLabel(new ImageIcon("image/up3.png"));
jmid=new JPanel(new GridLayout(3,3));
Font font = new Font("宋体", Font.PLAIN, 25);
jmid_num1=new JLabel("QQ号码:",JLabel.CENTER);
jmid_key1=new JLabel("QQ密码:",JLabel.CENTER);
jmid_num1.setFont(font); jmid_key1.setFont(font);
jmid_num2= new JTextField() ;
jmid_key2=new JPasswordField();
jmid_rember=new JCheckBox("自动登录");
jmid_automatic=new JCheckBox("记住密码");
jmid_rember.setFont(font); jmid_automatic.setFont(font);
jmid_rember.setForeground(Color.blue);
jmid_automatic.setForeground(Color.blue);
jmid.add(jmid_num1);
jmid.add(jmid_num2);
jmid.add(jmid_key1);
jmid.add(jmid_key2);
jmid.add(jmid_rember);
jmid.add(jmid_automatic);
jdown=new JPanel(new FlowLayout());
jdown_1=new JButton(new ImageIcon("image/denglu.png"));
jdown_2=new JButton(new ImageIcon("image/tuichu.png"));
jdown.add(jdown_1);
jdown.add(jdown_2);
setLocation(300,300);
add(jup,"North");
add(jmid,"Center");
add(jdown,"South");
setSize(700,540);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args)
{
QqClientlLogin qqClientlLogin=new QqClientlLogin();
}
}
//
2.好友列表界面
成品图如下:
要建立两个卡片的转换,即点击卡片一的"黑名单"转到第二个卡片界面,点击第二个卡片的"我的好友",转到第一个界面上 此时,就需要创建监听器的类,用到ActionListener接口 除此之外,我还建立了鼠标监听MouseListener接口,当鼠标停留在好友是,好友编号变红,离开时变回黑色,双击好友时,可得到该好友的编号(并进入与该好友的聊天界面) 详细代码及注释如下
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class QqFriendList extends JFrame implements ActionListener,MouseListener {
JPanel jup1,jmid1,jdown1;
JButton jup1_1,jdown1_1;
JScrollPane jmid1_1;
JPanel jup2,jup2_button,jmid2;
JButton jup2_1,jup2_2;
JScrollPane jmid2_1;
CardLayout cl;
public QqFriendList ()
{ Font font = new Font("宋体", Font.PLAIN, 35);
jup1=new JPanel(new BorderLayout());
jup1_1=new JButton("我的好友");
jup1_1.setFont(font);
jmid1=new JPanel(new GridLayout(50,1,4,4));
JLabel []jlist1=new JLabel [50];
for ( int i=0; i<jlist1.length ; i++ )
{
jlist1[i]=new JLabel(i+1+" ",new ImageIcon("image/touxiang.png"),JLabel.LEFT);
jlist1[i].addMouseListener(this);
jmid1.add(jlist1[i]);
}
jmid1_1=new JScrollPane(jmid1);
jdown1_1=new JButton("黑名单");
jdown1_1.addActionListener(this);
jdown1_1.setFont(font);
jdown1=new JPanel(new GridLayout(1,1));
jdown1.add(jdown1_1);
jup1.add(jup1_1,"North");
jup1.add(jmid1_1,"Center");
jup1.add(jdown1,"South");
jup2=new JPanel(new BorderLayout());
jup2_1=new JButton("我的好友");
jup2_1.addActionListener(this);
jup2_2=new JButton("黑名单");
jup2_1.setFont(font);
jup2_2.setFont(font);
jup2_button=new JPanel(new GridLayout(2,1));
jup2_button.add(jup2_1);
jup2_button.add(jup2_2);
jmid2=new JPanel(new GridLayout(20,1,4,4));
JLabel []jlist2=new JLabel [20];
for ( int i=0; i<jlist2.length ; i++ )
{
jlist2[i]=new JLabel(i+1+" ",new ImageIcon("image/heitou.png"),JLabel.LEFT);
jmid2.add(jlist2[i]);
}
jmid2_1=new JScrollPane(jmid2);
jup2.add(jup2_button,"North");
jup2.add(jmid2_1);
cl=new CardLayout();
setLayout(cl);
add(jup1,"1");
add(jup2,"2");
setLocation(300,300);
setSize(440,800);
setVisible(true);
}
public static void main(String[] args) {
QqFriendList qqFriendList=new QqFriendList();
}
public void actionPerformed(ActionEvent arg0)
{
if(arg0.getSource()==jdown1_1)
{
cl.show(this.getContentPane(), "2");
}
else
if(arg0.getSource()==jup2_1)
{
cl.show(this.getContentPane(), "1");
}
}
public void mouseEntered(MouseEvent arg0) {
JLabel jl=(JLabel)arg0.getSource();
jl.setForeground(Color.red);
}
public void mouseExited(MouseEvent arg0) {
JLabel jl=(JLabel)arg0.getSource();
jl.setForeground(Color.black);
}
public void mouseClicked(MouseEvent arg0) {
if(arg0.getClickCount()==2)
{
String friendNum=((JLabel)arg0.getSource()).getText();
}
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
}
}
3.聊天界面,用服务器判断登录qq,对象流
这部分的代码成果图:
注:正常是要有数据库来存qq账号密码信息的,秉着由简至难的原则,此处先不设计数据库,直接用服务器判断 有了上诉两个界面的设置,相信设置聊天界面应该很好模拟退出 聊天界面初步成果:
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class QqChat extends JFrame {
Font font = new Font("宋体", Font.PLAIN, 20);
JTextArea jta;
JTextField jtf;
JButton jb;
JPanel jp;
String ownerId;
String friendId;
public QqChat(String owner,String friend)
{
jta=new JTextArea();
jtf=new JTextField(25);
jb=new JButton("发送");
jb.setFont(font);
jp=new JPanel();
jp.add(jtf);
jp.add(jb);
add(jta,"Center");
add(jp,"South");
setTitle(owner+"正在和 "+friend+" 聊天");
setIconImage((new ImageIcon("image/qq.png").getImage()));
setLocation(800,400);
setSize(600, 500);
setVisible(true);
}
public static void main(String[] args) {
QqChat qqChat=new QqChat("1");
}
思考一下,如果是要与其余好友聊天应该如何表示呢? 在 QqFriendList中,我们双击得到好友的编号,只需把编号传到QqChat中即可 现在来实现登录操作:当用户点击登录后,把qq号码和密码发送给QqServer(服务器)去验证,如果该用户合法,返回true,否则返回false; 以对象流的方式读取客户端发来的账号和密码,在网络间传递对象流, 避免直接读入由特殊符号,空格,换行等干扰
对象流是一种高级流,可以方便我们将java中的任何对象进行读写操作。
java.io.objectoutputstream对象输出流,可以将对象转换为一组字节写出。
java.io.objectinputstream对象输入流,可以读取一组字节转换为原对象,
还原为原对象的条件是读取这个字节应该是对象输出流将一个对象转换的字节。
一个对象要想序列化,该类必须实现java.io.Serializable 接口
Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException 。
使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
在这里,我们还要用到socket socket是两台主机之间的一个连接 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。 建立网络通信连接需要一对socket,两个socket之间形成一个管道(通道),进行信息流的传输(联想IO流中文件和程序之间读写)。
ServerSocket与Socket入门详解 分别在Qqclient(客户端)和QqServe(服务端)项目里建立com.qq.common包,包里存放Message.java和User.java两个类 User类就是获得用户输入的账号和密码
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;
}
}
对发送服务端的信息规定一些规则 mesType为true 表明登陆成功 mesType为false 表明登录失败 所以Message就是用来判断的
package com.qq.common;
public class Message implements java.io.Serializable {
private String mesType;
public String getMesType()
{
return mesType;
}
public void setMesType(String mesType)
{
this.mesType =mesType;
}
}
主要思想 要在第一部分qq登录界面的代码中加上监听(登录按钮),将得到的账户和密码信息逐步传入到破服务器里面,再有服务器返回,判断是否能登录,如果能,打开好友列表界面, 否则,触发提示框"用户名或密码错误". 客户端 注意:我判断的是如果密码为"123456"即为正确
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.qq.client.model.*;
import com.qq.common.*;
public class QqClientlLogin extends JFrame implements ActionListener{
JLabel jup;
JPanel jmid ;
JLabel jmid_num1,jmid_key1;
JTextField jmid_num2;
JPasswordField jmid_key2;
JCheckBox jmid_rember,jmid_automatic;
JPanel jdown;
JButton jdown_1,jdown_2;
public QqClientlLogin()
{
jup=new JLabel(new ImageIcon("image/up3.png"));
jmid=new JPanel(new GridLayout(3,3));
Font font = new Font("宋体", Font.PLAIN, 25);
jmid_num1=new JLabel("QQ号码:",JLabel.CENTER);
jmid_key1=new JLabel("QQ密码:",JLabel.CENTER);
jmid_num1.setFont(font); jmid_key1.setFont(font);
jmid_num2= new JTextField() ;
jmid_key2=new JPasswordField();
jmid_rember=new JCheckBox("自动登录");
jmid_automatic=new JCheckBox("记住密码");
jmid_rember.setFont(font); jmid_automatic.setFont(font);
jmid_rember.setForeground(Color.blue);
jmid_automatic.setForeground(Color.blue);
jmid.add(jmid_num1);
jmid.add(jmid_num2);
jmid.add(jmid_key1);
jmid.add(jmid_key2);
jmid.add(jmid_rember);
jmid.add(jmid_automatic);
jdown=new JPanel(new FlowLayout());
jdown_1=new JButton(new ImageIcon("image/denglu.png"));
jdown_1.addActionListener(this);
jdown_2=new JButton(new ImageIcon("image/tuichu.png"));
jdown.add(jdown_1);
jdown.add(jdown_2);
setLocation(300,300);
add(jup,"North");
add(jmid,"Center");
add(jdown,"South");
setSize(700,540);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args)
{
QqClientlLogin qqClientlLogin=new QqClientlLogin();
}
public void actionPerformed(ActionEvent arg0)
{
if(arg0.getSource()==jdown_1);
{
User u=new User();
u. setUserId(jmid_num2.getText().trim());
u. setPasswd(new String (jmid_key2.getPassword()));
QqClientUser qqclientuser=new QqClientUser();
if(qqclientuser.checkUser(u))
{
new QqFriendList(u.getUserId());
this.dispose();
}
else
{
JOptionPane.showMessageDialog(this,"用户名或密码错误");
}
}
}
}
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class QqFriendList extends JFrame implements ActionListener,MouseListener {
String owner;
JPanel jup1,jmid1,jdown1;
JButton jup1_1,jdown1_1;
JScrollPane jmid1_1;
JPanel jup2,jup2_button,jmid2;
JButton jup2_1,jup2_2;
JScrollPane jmid2_1;
CardLayout cl;
public QqFriendList (String ownerId)
{
Font font = new Font("宋体", Font.PLAIN, 35);
owner=ownerId;
jup1=new JPanel(new BorderLayout());
jup1_1=new JButton("我的好友");
jup1_1.setFont(font);
jmid1=new JPanel(new GridLayout(50,1,4,4));
JLabel []jlist1=new JLabel [50];
for ( int i=0; i<jlist1.length ; i++ )
{
jlist1[i]=new JLabel(i+1+" ",new ImageIcon("image/touxiang.png"),JLabel.LEFT);
jlist1[i].addMouseListener(this);
jmid1.add(jlist1[i]);
}
jmid1_1=new JScrollPane(jmid1);
jdown1_1=new JButton("黑名单");
jdown1_1.addActionListener(this);
jdown1_1.setFont(font);
jdown1=new JPanel(new GridLayout(1,1));
jdown1.add(jdown1_1);
jup1.add(jup1_1,"North");
jup1.add(jmid1_1,"Center");
jup1.add(jdown1,"South");
jup2=new JPanel(new BorderLayout());
jup2_1=new JButton("我的好友");
jup2_1.addActionListener(this);
jup2_2=new JButton("黑名单");
jup2_1.setFont(font);
jup2_2.setFont(font);
jup2_button=new JPanel(new GridLayout(2,1));
jup2_button.add(jup2_1);
jup2_button.add(jup2_2);
jmid2=new JPanel(new GridLayout(20,1,4,4));
JLabel []jlist2=new JLabel [20];
for ( int i=0; i<jlist2.length ; i++ )
{
jlist2[i]=new JLabel(i+1+" ",new ImageIcon("image/heitou.png"),JLabel.LEFT);
jmid2.add(jlist2[i]);
}
jmid2_1=new JScrollPane(jmid2);
jup2.add(jup2_button,"North");
jup2.add(jmid2_1);
cl=new CardLayout();
setLayout(cl);
add(jup1,"1");
add(jup2,"2");
setTitle(ownerId);
setLocation(300,300);
setSize(440,800);
setVisible(true);
}
public static void main(String[] args) {
QqFriendList qqFriendList=new QqFriendList();
}
public void actionPerformed(ActionEvent arg0)
{
if(arg0.getSource()==jdown1_1)
{
cl.show(this.getContentPane(), "2");
}
else
if(arg0.getSource()==jup2_1)
{
cl.show(this.getContentPane(), "1");
}
}
public void mouseEntered(MouseEvent arg0) {
JLabel jl=(JLabel)arg0.getSource();
jl.setForeground(Color.red);
}
public void mouseExited(MouseEvent arg0) {
JLabel jl=(JLabel)arg0.getSource();
jl.setForeground(Color.black);
}
public void mouseClicked(MouseEvent arg0) {
if(arg0.getClickCount()==2)
{
String friendNum=((JLabel)arg0.getSource()).getText();
new QqChat(owner,friendNum);
}
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
}
}
package com.qq.client.model;
import com.qq.common.*;
public class QqClientUser {
public boolean checkUser(User u)
{
return new QqClientConServer().sendLoginInfotoSSErver(u);
}
}
package com.qq.client.model;
import java.util.*;
import java.net.*;
import java.io.*;
import com.qq.common.*;
public class QqClientConServer{
public boolean sendLoginInfotoSSErver(Object o)
{
boolean b=false;
try
{
Socket 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"))
b=true;
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
}
return b;
}
}
服务端 除了需要的Message.java和User.java两个类还需要
package com.qq.server.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.qq.server.model.MyQqServer;
public class ControlPanel extends JFrame implements ActionListener{
JPanel jp1;
JButton jstart,jend;
public ControlPanel()
{ Font font = new Font("宋体",Font.PLAIN,30);
jp1=new JPanel();
jstart=new JButton("启动服务器");
jstart.addActionListener(this);
jend=new JButton("关闭服务器");
jstart.setFont(font); jend.setFont(font);
jstart.setForeground(Color.BLUE); jend.setForeground(Color.BLUE);
jp1.add(jstart);
jp1.add(jend);
add(jp1);
setLocation(150,150);
setSize(900,900);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
ControlPanel controlpanel =new ControlPanel();
}
public void actionPerformed(ActionEvent arg0)
{
if(arg0.getSource()==jstart)
{
new MyQqServer();
}
}
}
package com.qq.server.model;
import java.io.*;
import java.net.*;
import java.util.*;
import com.qq.common.*;
public class MyQqServer {
public MyQqServer ()
{
try
{
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);
}
else
{
m.setMesType("2");
oos.writeObject(m);
s.close();
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
}
}
}
4.一对一的聊天
进程概念:进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。 线程概念:线程是进程的一个执行路径,一个进程中至少有一个线程,进程中的多个线程共享进程的资源。
此处要用线程用来接收客户端的消息,因为不仅仅一个用户(可实现多用户登录) 要在message类里面加入,用户编号,接受方,发送信息(即获得聊天界面文本框的内容)等 在chat类里面,加入读取,文本域中显示聊天代码等内容 在管理客户端线程中使用HashMap<关键字,值>记录发送者与服务器的socket,关键字记录用户编号,值记录socket
每个包(类)或多或少都有所更改,完整代码如下,希望对大家有所帮助,同时请大佬指正错误%%%
// 客户端代码
package com.qq.common;
public class Message implements java.io.Serializable {
private String mesType;
private String sender;
private String getter;
private String con;
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 getMesType()
{
return mesType;
}
public void setMesType(String mesType)
{
this.mesType =mesType;
}
}
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;
}
}
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.qq.client.model.*;
import com.qq.common.*;
public class QqClientlLogin extends JFrame implements ActionListener{
JLabel jup;
JPanel jmid ;
JLabel jmid_num1,jmid_key1;
JTextField jmid_num2;
JPasswordField jmid_key2;
JCheckBox jmid_rember,jmid_automatic;
JPanel jdown;
JButton jdown_1,jdown_2;
public QqClientlLogin()
{
jup=new JLabel(new ImageIcon("image/up3.png"));
jmid=new JPanel(new GridLayout(3,3));
Font font = new Font("宋体", Font.PLAIN, 25);
jmid_num1=new JLabel("QQ号码:",JLabel.CENTER);
jmid_key1=new JLabel("QQ密码:",JLabel.CENTER);
jmid_num1.setFont(font); jmid_key1.setFont(font);
jmid_num2= new JTextField() ;
jmid_key2=new JPasswordField();
jmid_rember=new JCheckBox("自动登录");
jmid_automatic=new JCheckBox("记住密码");
jmid_rember.setFont(font); jmid_automatic.setFont(font);
jmid_rember.setForeground(Color.blue);
jmid_automatic.setForeground(Color.blue);
jmid.add(jmid_num1);
jmid.add(jmid_num2);
jmid.add(jmid_key1);
jmid.add(jmid_key2);
jmid.add(jmid_rember);
jmid.add(jmid_automatic);
jdown=new JPanel(new FlowLayout());
jdown_1=new JButton(new ImageIcon("image/denglu.png"));
jdown_1.addActionListener(this);
jdown_2=new JButton(new ImageIcon("image/tuichu.png"));
jdown.add(jdown_1);
jdown.add(jdown_2);
setLocation(300,300);
add(jup,"North");
add(jmid,"Center");
add(jdown,"South");
setSize(700,540);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args)
{
QqClientlLogin qqClientlLogin=new QqClientlLogin();
}
public void actionPerformed(ActionEvent arg0)
{
if(arg0.getSource()==jdown_1);
{
User u=new User();
u. setUserId(jmid_num2.getText().trim());
u. setPasswd(new String (jmid_key2.getPassword()));
QqClientUser qqclientuser=new QqClientUser();
if(qqclientuser.checkUser(u))
{
QqFriendList qqList=new QqFriendList(u.getUserId());
this.dispose();
}
else
{
JOptionPane.showMessageDialog(this,"用户名或密码错误");
}
}
}
}
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class QqFriendList extends JFrame implements ActionListener,MouseListener {
String owner;
JPanel jup1,jmid1,jdown1;
JButton jup1_1,jdown1_1;
JScrollPane jmid1_1;
JPanel jup2,jup2_button,jmid2;
JButton jup2_1,jup2_2;
JScrollPane jmid2_1;
CardLayout cl;
public QqFriendList (String ownerId)
{
Font font = new Font("宋体", Font.PLAIN, 35);
owner=ownerId;
jup1=new JPanel(new BorderLayout());
jup1_1=new JButton("我的好友");
jup1_1.setFont(font);
jmid1=new JPanel(new GridLayout(50,1,4,4));
JLabel []jlist1=new JLabel [50];
for ( int i=0; i<jlist1.length ; i++ )
{
jlist1[i]=new JLabel(i+1+" ",new ImageIcon("image/touxiang.png"),JLabel.LEFT);
jlist1[i].addMouseListener(this);
jmid1.add(jlist1[i]);
}
jmid1_1=new JScrollPane(jmid1);
jdown1_1=new JButton("黑名单");
jdown1_1.addActionListener(this);
jdown1_1.setFont(font);
jdown1=new JPanel(new GridLayout(1,1));
jdown1.add(jdown1_1);
jup1.add(jup1_1,"North");
jup1.add(jmid1_1,"Center");
jup1.add(jdown1,"South");
jup2=new JPanel(new BorderLayout());
jup2_1=new JButton("我的好友");
jup2_1.addActionListener(this);
jup2_2=new JButton("黑名单");
jup2_1.setFont(font);
jup2_2.setFont(font);
jup2_button=new JPanel(new GridLayout(2,1));
jup2_button.add(jup2_1);
jup2_button.add(jup2_2);
jmid2=new JPanel(new GridLayout(20,1,4,4));
JLabel []jlist2=new JLabel [20];
for ( int i=0; i<jlist2.length ; i++ )
{
jlist2[i]=new JLabel(i+1+" ",new ImageIcon("image/heitou.png"),JLabel.LEFT);
jmid2.add(jlist2[i]);
}
jmid2_1=new JScrollPane(jmid2);
jup2.add(jup2_button,"North");
jup2.add(jmid2_1);
cl=new CardLayout();
setLayout(cl);
add(jup1,"1");
add(jup2,"2");
setTitle(ownerId);
setLocation(300,300);
setSize(440,800);
setVisible(true);
}
public static void main(String[] args) {
}
public void actionPerformed(ActionEvent arg0)
{
if(arg0.getSource()==jdown1_1)
{
cl.show(this.getContentPane(), "2");
}
else
if(arg0.getSource()==jup2_1)
{
cl.show(this.getContentPane(), "1");
}
}
public void mouseEntered(MouseEvent arg0) {
JLabel jl=(JLabel)arg0.getSource();
jl.setForeground(Color.red);
}
public void mouseExited(MouseEvent arg0) {
JLabel jl=(JLabel)arg0.getSource();
jl.setForeground(Color.black);
}
public void mouseClicked(MouseEvent arg0) {
if(arg0.getClickCount()==2)
{
String friendNum=((JLabel)arg0.getSource()).getText();
QqChat qqChat=new QqChat(owner,friendNum);
Thread t=new Thread(qqChat);
t.start();
}
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
}
}
package com.qq.client.view;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import com.qq.common.*;
import com.qq.client.model.*;
public class QqChat extends JFrame implements ActionListener,Runnable{
Font font = new Font("宋体", Font.PLAIN, 20);
JTextArea jta;
JTextField jtf;
JButton jb;
JPanel jp;
String ownerId;
String friendId;
public QqChat(String owner,String friend)
{
ownerId= owner;
friendId=friend;
jta=new JTextArea();
jtf=new JTextField(25);
jb=new JButton("发送");
jb.addActionListener(this);
jb.setFont(font);
jp=new JPanel();
jp.add(jtf);
jp.add(jb);
add(jta,"Center");
add(jp,"South");
setTitle(owner+"正在和 "+friend+" 聊天");
setIconImage((new ImageIcon("image/qq.png").getImage()));
setLocation(800,400);
setSize(600, 500);
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) {
if(arg0.getSource()==jb)
{
Message m=new Message();
m.setSender(this.ownerId);
m.setGetter(this.friendId);
m.setCon(jtf.getText());
try
{
ObjectOutputStream oos=new ObjectOutputStream(QqClientConServer.s.getOutputStream());
oos.writeObject(m);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public void run()
{
while(true)
{
try
{
ObjectInputStream ois=new ObjectInputStream(QqClientConServer.s.getInputStream());
Message m =(Message)ois.readObject();
String info=m.getSender()+"给"+m.getGetter()+"发送"+m.getCon()+"\r\n";
this.jta.append(info);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
package com.qq.client.model;
import com.qq.common.*;
public class QqClientUser {
public boolean checkUser(User u)
{
return new QqClientConServer().sendLoginInfotoSSErver(u);
}
}
package com.qq.client.model;
import java.util.*;
import java.net.*;
import java.io.*;
import com.qq.common.*;
public class QqClientConServer{
public static Socket s;
public boolean sendLoginInfotoSSErver(Object o)
{
boolean b=false;
try
{
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"))
b=true;
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
}
return b;
}
}
服务端代码(message,user与客户端一样,这里不在写出,直接复制过去就可以)
package com.qq.server.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.qq.server.model.MyQqServer;
public class ControlPanel extends JFrame implements ActionListener{
JPanel jp1;
JButton jstart,jend;
public ControlPanel()
{ Font font = new Font("宋体",Font.PLAIN,30);
jp1=new JPanel();
jstart=new JButton("启动服务器");
jstart.addActionListener(this);
jend=new JButton("关闭服务器");
jstart.setFont(font); jend.setFont(font);
jstart.setForeground(Color.BLUE); jend.setForeground(Color.BLUE);
jp1.add(jstart);
jp1.add(jend);
add(jp1);
setLocation(150,150);
setSize(900,900);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
ControlPanel controlpanel =new ControlPanel();
}
public void actionPerformed(ActionEvent arg0)
{
if(arg0.getSource()==jstart)
{
new MyQqServer();
}
}
}
package com.qq.server.model;
import java.io.*;
import java.net.*;
import java.util.*;
import com.qq.common.*;
public class MyQqServer {
public MyQqServer ()
{
try
{
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();
}
else
{
m.setMesType("2");
oos.writeObject(m);
s.close();
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
}
}
}
package com.qq.server.model;
import java.net.*;
import java.io.*;
import com.qq.common.*;
public class SerConClientThread extends Thread
{
Socket s;
public SerConClientThread(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());
SerConClientThread sc=ManageClientThread.getClientThread(m.getGetter());
ObjectOutputStream oos=new ObjectOutputStream(sc.s.getOutputStream());
oos.writeObject(m);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
package com.qq.server.model;
import java.util.*;
public class ManageClientThread {
public static HashMap hm=new HashMap<String, SerConClientThread>();
public static void addClientThread(String uid,SerConClientThread ct)
{
hm.put(uid, ct);
}
public static SerConClientThread getClientThread(String uid)
{
return (SerConClientThread) hm.get(uid);
}
}
|