public class QQlogin extends JFrame implements ActionListener{
JTextField User;
JTextField Pass;
QQlogin(){
//new组件
JLabel labUser = new JLabel("用户名");
JLabel labPass = new JLabel("密码");

User = new JTextField();
Pass = new JTextField();

JButton btnLogin = new JButton("登录");
JButton btnReg = new JButton("注册");
JButton btnCancel = new JButton("取消");

//布置输入面板
JPanel panInput = new JPanel();
panInput.setLayout(new GridLayout(2,2));

panInput.add(labUser);
panInput.add(User);

panInput.add(labPass);
panInput.add(Pass);

//布置按钮面板
JPanel panButton = new JPanel();
panButton.setLayout(new FlowLayout());

panButton.add(btnLogin);
panButton.add(btnReg);
panButton.add(btnCancel);

//布置窗体
this.setSize(250,125);
this.setLayout(new BorderLayout());
this.add(panInput,BorderLayout.CENTER);
this.add(panButton, BorderLayout.SOUTH);

//注册监听事件

btnLogin.addActionListener(this);
btnReg.addActionListener(this);
btnCancel.addActionListener(this);
}
public static void main(String[] args) {
QQlogin w1 = new QQlogin();
w1.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub

if (e.getActionCommand().equals("登录")) {
try {
 String  usern =User.getText();
 String  passn =Pass.getText();
            Socket s = new Socket("127.0.0.1",8000);
            
            OutputStream os = s.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(os);
            PrintWriter pw = new PrintWriter(osw,true);
            pw.println(usern+"%"+passn);
            //接受服务器发送回来的确认信息
            InputStream is = s.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String yorn = br.readLine();
            //显示主窗体
            if (yorn.equals("ok")) {
QQmain w = new QQmain();
w.setSocket(s);
w.setVisible(true);
                this.setVisible(false);}
                else{
                 JOptionPane.showMessageDialog(null, this, "对不起,用户名或者密码错误", 0);                 }
}
catch (Exception e2){}
}
if (e.getActionCommand().equals("注册")) {
System.out.println("gfdsdf");
}
if (e.getActionCommand().equals("取消")) {
this.setVisible(false);
}
}

}public class QQmain extends JFrame implements ActionListener,Runnable,WindowListener{
private Socket s;
public void setSocket(Socket value){
s = value;
//启动接受线程
Thread t = new Thread(this);
t.start();
}

JTextField txtMess = new JTextField();
JComboBox cmbUser = new JComboBox();//JCombobos 
JTextArea txtContent = new JTextArea();
QQmain(){
this.setSize(300,400);
//new组件
JButton btnSend = new JButton("发送");
JScrollPane spContent = new JScrollPane();
//注册监听事件
btnSend.addActionListener(this);
//布置小面板
JPanel panSmall = new JPanel();
panSmall.setLayout(new GridLayout(1,2));

panSmall.add(cmbUser);
panSmall.add(btnSend);

//布置大面板
JPanel panBig= new JPanel();
panBig.setLayout(new GridLayout(2,1));

panBig.add(txtMess);
panBig.add(panSmall);

//布置窗体
this.setLayout(new BorderLayout());

this.add(panBig,BorderLayout.NORTH);
this.add(spContent,BorderLayout.CENTER);
this.setVisible(true);//读聊天记录
try{
File f = new File("c:/work/聊天记录.qq");
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
while (br.ready()) {
txtContent.append(br.readLine()+"\n");
}
}catch(Exception e){}}
@Override
public void actionPerformed(ActionEvent e) {


// txtMess---->txtContent
txtContent.append(txtMess.getText()+"\n");


//将txtMess聊天记录存入聊天文件
try {
File f = new File("c:/work/聊天记录.qq");

FileWriter fw = new FileWriter(f);
PrintWriter pw =new PrintWriter(fw);

pw.println(txtMess.getText());

pw.close();
} catch (Exception e2) {
}


//发送信息到服务器
try {
 OutputStream os = s.getOutputStream();
    OutputStreamWriter osw = new OutputStreamWriter(os);
    PrintWriter pw =new PrintWriter(osw,true);
    pw.println(cmbUser.getSelectedItem()+txtMess.getText());
} catch (Exception e2) {
// TODO: handle exception
}
txtMess.setText("");
}
//接受线程
public void run(){
try {
InputStream is = s.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while(true){
String message = br.readLine();
String type = message.split("%")[0];
String mess = message.split("%")[1];
if (type.equals("add")) {
cmbUser.addItem(mess);
}
if (type.equals("exit")) {
cmbUser.removeItem(mess);

}
if (type.equals("mess")) {
txtContent.append(mess+"\n");
}
}
} catch (Exception e) {
// TODO: handle exception
}
}@Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub

}@Override
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub

}@Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub

}@Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub
try {
OutputStream os= s.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
PrintWriter pw = new PrintWriter(osw,true);

pw.println("{exit}");

//正常退出
System.exit(0);
} catch (Exception e2) {
// TODO: handle exception
}
}@Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub

}@Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub

}@Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub

}}
public class QQSever { public static void main(String[] args) {
// TODO Auto-generated method stub
try {

HashMap<String, Socket> hm = new HashMap<String, Socket>();
// 服务器在监听
ServerSocket ss = new ServerSocket(8000); while (true) {
System.out.println("正在监听");
Socket s = ss.accept();
MyService t = new MyService();
t.setSocket(s);
// 将HashMap的引用传入每个服务线程
t.setHashMap(hm);
t.start();
}
} catch (Exception e) {
}
}
}
class MyService extends Thread {// 因为继承了Thread所以MyService就是Thread.直接newMyService即可

// 传递参数的方法,s的声明再main函数里,使用在run方法里,作用域不一致,就需要传递s到MyService
private Socket s; public void setSocket(Socket s2) {
this.s = s;
} // 接受HashMap的引用
private HashMap<String, Socket> hm; public void setHashMap(HashMap hm) {
this.hm = hm;
} public void run() {
try {
// 接受客户端的信息
InputStream is = s.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String uandp = br.readLine();
System.out.println(uandp);
// 拆分用户名和密码
String u = uandp.split("%")[0];
String p = uandp.split("%")[1];
OutputStream os = s.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
PrintWriter pw = new PrintWriter(osw, true);
// 数据库中验证用户名和密码
Class.forName("com.mysql.jdbc.Driver");
Connection cn = DriverManager.getConnection("jdbc:mysql://localhost:3306/kdsd", "root", "root");
PreparedStatement ps = cn.prepareStatement("select * from user where username=? and password=?");
ps.setString(1, u);
ps.setString(2, p);
ResultSet rs = ps.executeQuery(); // 如果存在该用户
if (rs.next()) { // 发送正确信息到客户端
pw.println("ok"); // 将本人的名字发送给其它的用户
for (Socket ts : hm.values()) { 
OutputStream tos = ts.getOutputStream();
OutputStreamWriter tosw = new OutputStreamWriter(tos);
PrintWriter tpw = new PrintWriter(tosw, true);
tpw.println("add%" + u);//信息头,不然不知道是添加还是删除
} // 将其他人名字发给自己
for (String tu : hm.keySet()) {
pw.println("add%" + tu);
} // 将本人的用户名和Socket存入HashMap
hm.put(u, s); // 不断接收客户端消息
while (true) {
String message = br.readLine();
if (message.equals("{exit}")) { // 将该用户从HashMap删除
hm.remove(u);
// 通知所有人,本用户退出
for (Socket ts : hm.values()) {
OutputStream tos = s.getOutputStream();
OutputStreamWriter tosw = new OutputStreamWriter(tos);
PrintWriter tpw = new PrintWriter(tosw, true);
tpw.print("exit%" + u);
}
return;
} // 服务器转发信息
String to = message.split("%")[0];//用户
String mess = message.split("%")[1];//具体信息
Socket ts = hm.get(to);//某用户的Socket
OutputStream tos = ts.getOutputStream();
OutputStreamWriter tosw = new OutputStreamWriter(tos);
PrintWriter tpw = new PrintWriter(tosw, true);
                    //发给用户信息
tpw.println("mess%" + mess);
}
} else {
pw.println("err");
}
} catch (Exception e) {
}
}
}