资源描述
package mytalk;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import .ServerSocket;
import .Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Server {
Map<String,ClientThread> clients = new HashMap<String,ClientThread>(); //创建一个Map,记录客户端线程
Connection con = null;
Statement sta = null;
ResultSet rs = null;
Server() throws Exception{
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/qq?useUnicode=true&characterEncoding=utf8","root","root");
sta = con.createStatement();
}
catch(Exception e){
System.out.println("找不到驱动程序类 ,加载驱动失败!");
}
ServerSocket ss = new ServerSocket(9000); //服务器端口
while(true){
System.out.println("链接成功");
Socket s = ss.accept(); //服务器启动监听
rs = sta.executeQuery("select * from people");
while(rs.next()){
String nickname = rs.getString(2);
String chlog = rs.getString(5);
String cnk = rs.getString(7);
if(chlog.equals("true")){//过滤没启动的客户端
if(cnk.equals("null")){//过滤已启动的客户端
ClientThread ct = new ClientThread(s,nickname);
clients.put(nickname,ct);//把当前客户端加入集合
new Thread(ct).start();
}
}
}
}
}
class ClientThread implements Runnable{
Socket s = null; //记录与服务器链接的客户端端口号
DataInputStream is = null; //输入字节流
DataOutputStream os = null; //输出字节流
String str = null; //记录客户端名称
String nickname = null; //登陆昵称
ClientThread(Socket s,String nickname){
this.s = s;
this.nickname = nickname;
}
public void run() {
try {
while(true){
if(s.isConnected()){
is = new DataInputStream(s.getInputStream()); //获得输入流
str = is.readUTF(); //从输入流中得到数据
String stalk = null; //确定是否私聊
ResultSet rs0 = sta.executeQuery("select * from people where nickname='"+nickname+"'");
while(rs0.next()){
stalk = rs0.getString(6);
}
if(stalk.equals("null")){
Iterator it = clients.entrySet().iterator(); //设置一个遍历器,遍历Map
while(it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
ClientThread c = (ClientThread)entry.getValue(); //获得Map的值
c.sendMsg(str); //获得客户端的信息并发送给所有的客户端
}
}else{
ClientThread c = clients.get(stalk); //得到私聊对象
c.sendMsg(str); //获得客户端的信息并发送给指定客户段端
}
}else{
clients.remove(nickname);break; //当一个客户端结束后,移出Map
}
}
} catch (Exception e) {
}
}
public void sendMsg(String str) {
try {
os = new DataOutputStream(this.s.getOutputStream()); //获得输出流
os.writeUTF(str); //将字符串添加到输出流上并发送出去
} catch (IOException e) {
}
}
}
public static void main(String [] args) throws Exception{
new Server();
}
}
package mytalk;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import .Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class Client extends JFrame implements ListSelectionListener{
Connection con = null;
Statement sta = null;
ResultSet rs = null;
Socket s = null;
DataInputStream is = null;
DataOutputStream os = null;
JTextArea jt = new JTextArea();//输入框
JTextArea jta = new JTextArea();//群聊框
JTextArea sjta = new JTextArea();//私聊框
JScrollPane jsp0 = new JScrollPane(jta);//群聊框
JScrollPane jsp1 = new JScrollPane(sjta);//私聊框
JScrollPane jsp3 = new JScrollPane(jt);//输入框
JPanel jp1 = new JPanel();
JPanel eastPanel = new JPanel(new BorderLayout());
JPanel jp = new JPanel(new GridLayout(3, 1));
JButton jb = new JButton("发送私聊");
JButton jbq = new JButton("发送群聊");
JButton refhButton = new JButton("刷新列表");
JLabel title = new JLabel("我的在线好友");
DefaultListModel listModel = new DefaultListModel();// 用户列表
JList fri = new JList(listModel);
JScrollPane js = new JScrollPane(fri);
Vector items = new Vector();
JComboBox jcb = new JComboBox(items);
JRadioButton jc = new JRadioButton("私聊",false);
JRadioButton jq = new JRadioButton("群聊",false);
ButtonGroup bg = new ButtonGroup();
JMenuItem menuItem;
JMenuItem cMenuItem;
String nickname = null;
String str1 = null;//私聊对象
Client(final String nkname,String ip) throws Exception{
s = new Socket(ip,9000);
nickname = nkname;
this.setTitle(nkname);
this.setLocation(100, 0);
jt.setLineWrap(true);//设置文本自动换行
jta.setLineWrap(true);//设置文本自动换行
sjta.setLineWrap(true);//设置文本自动换行
jta.setEditable(false);//设置文本不可编辑
sjta.setEditable(false);//设置文本不可编辑
js.setPreferredSize(new Dimension(150, 400));
js.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);// 设置滚动条什么时候出现
js.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jsp0.setBorder(BorderFactory.createTitledBorder("群聊区"));
jsp0.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);// 设置滚动条什么时候出现
jsp0.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jsp1.setBorder(BorderFactory.createTitledBorder("私聊区"));
jsp1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);// 设置滚动条什么时候出现
jsp1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jsp3.setBorder(BorderFactory.createTitledBorder("输入框 群聊不要使用@符号"));
jsp3.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);// 设置滚动条什么时候出现
jsp3.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
fri.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);// 设置单选还是多选
fri.addListSelectionListener(this);
jcb.setPreferredSize(new Dimension(160, 25));
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://"+ip+":3306/qq?useUnicode=true&characterEncoding=utf8","root","root");
sta = con.createStatement();
}
catch(Exception e){
System.out.println("找不到驱动程序类 ,加载驱动失败!");
}
jp.add(jsp0);
jp.add(jsp1);
jp.add(jsp3);
jp1.add(jc);
jp1.add(jcb);
jp1.add(jb);
jp1.add(jq);
jp1.add(jbq);
eastPanel.add(title, BorderLayout.NORTH);
eastPanel.add(js, BorderLayout.CENTER);
eastPanel.add(refhButton, BorderLayout.SOUTH);
bg.add(jc);
bg.add(jq);
this.add(jp, BorderLayout.CENTER);
this.add(jp1, BorderLayout.SOUTH);
this.add(eastPanel, BorderLayout.WEST);
this.createPopupMenu();
this.setSize(1000, 741);
this.setVisible(true);
is = new DataInputStream(s.getInputStream());
os = new DataOutputStream(s.getOutputStream());
os.writeUTF(nickname+"上线了!!!");
this.addWindowListener(
new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
try {
sta.executeUpdate("update people set chlog='false' where nickname='"+nkname+"'");
sta.executeUpdate("update people set cnk='null' where nickname='"+nkname+"'");
sta.executeUpdate("update people set stalk='null' where nickname='"+nkname+"'");
os.writeUTF(nickname+"离开了!!!");
} catch (Exception e1) {
}
System.exit(0);
}
}
);
new ReceiveThread().start();
new Relist().start();
jcb.addItemListener(new ItemListener(){
@Override
public void itemStateChanged(ItemEvent e) {
str1 = (String) jcb.getSelectedItem();//私聊对象
bg.clearSelection();
}
});
jc.addActionListener(new ActionListener(){//私聊单选
@Override
public void actionPerformed(ActionEvent e) {
if(jc.isSelected()){
try {
sta.executeUpdate("update people set stalk='"+str1+"' where nickname='"+nickname+"'");
} catch (SQLException e2) {
}
}
}
});
jb.addActionListener(new ActionListener(){//发送私聊按钮监听 //客户端输入框
public void actionPerformed(ActionEvent e) {
try {
if(jq.isSelected()){
}else if(jc.isSelected()){
String str0 = jt.getText();//要说的话
os.writeUTF(nickname+"@"+str1+"说 :"+str0);
sjta.append(nickname+"@"+str1+"说:"+str0+"\n");
sjta.setCaretPosition(sjta.getText().length());//自动滾動到底端
jt.setText("");
jt.requestFocus();//获得焦点
}
} catch (Exception e1) {
}
}
});
jq.addActionListener(new ActionListener(){//群聊单选
@Override
public void actionPerformed(ActionEvent e) {
try {
if(jq.isSelected()){
sta.executeUpdate("update people set stalk='null' where nickname='"+nickname+"'");
}
} catch (Exception e1) {
}
}
});
jbq.addActionListener(new ActionListener(){//发送群聊按钮监听 //客户端输入框
public void actionPerformed(ActionEvent e) {
try {
if(jc.isSelected()){
}else if(jq.isSelected()){
String str = jt.getText();
os.writeUTF(nickname+":"+str);
jt.setText("");
jt.requestFocus();//获得焦点
}
} catch (IOException e1) {
}
}
});
refhButton.addActionListener(new ActionListener(){//刷新按钮监听
public void actionPerformed(ActionEvent e) {
listModel.clear(); // 清空列表
items.clear();// 清空列表
new Relist().start();
}
});
}
class ReceiveThread extends Thread{//客户端聊天框
String str = null;
public void run() {
try {
while(true){
str = is.readUTF();
String[] sendname = str.split("@",2);
String[] user = str.split(":",2);
if(str.contains("@")){
sjta.append(sendname[0]+"@"+nickname+"说:"+user[1]+"\n");
sjta.setCaretPosition(sjta.getText().length());//自动滾動到底端
}else{
jta.append(str+"\n");
jta.setCaretPosition(jta.getText().length());//自动滾動到底端
}
}
} catch (Exception e) {
}
}
}
class Relist extends Thread{//刷新好友列表
@Override
public void run() {
try {
rs = sta.executeQuery("select * from people");
while(rs.next()){
String nkname = rs.getString(2);
String chlog = rs.getString(5);
String sex = rs.getString(3);
if(chlog.equals("true")){
items.add(nkname);
listModel.addElement(nkname+" "+sex);
}
}
} catch (SQLException e) {
}
}
}
@Override
public void valueChanged(ListSelectionEvent e) {//设置好友列表选取的对象和私聊对象一致
String select = (String) fri.getSelectedValue();
String[] userInfo = select.split(" ");
String name = userInfo[0].trim(); // 提取名字
if (select != null) // 确保选择非空
{
if(!name.equals(nickname)){// 不能添加自己
jcb.setSelectedItem(name);
}
}
}
public void createPopupMenu(){//右击菜单
final JPopupMenu popup = new JPopupMenu();
menuItem = new JMenuItem("清空群聊区信息");
menuItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
jta.setText("");
}
});
popup.add(menuItem); // 鼠标右击显示
cMenuItem = new JMenuItem("清空私聊区信息");
cMenuItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
sjta.setText("");
}
});
popup.add(cMenuItem);
jta.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
popup.show(jta, e.getX(), e.getY());
}
}
});
sjta.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
popup.show(sjta, e.getX(), e.getY());
}
}
});
}
}
package mytalk;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class Log extends JFrame {
Connection con = null;
Statement sta = null;
ResultSet rs = null;
ImageIcon image = new ImageIcon("./Login_background.jpg");
JLabel ltel = new JLabel("手机号:");
JLabel jl = new JLabel(image);
JLabel lpw = new JLabel("密码:");
JLabel laddr = new JLabel("地址:");
JTextField addr = new JTextField(10);
JTextField tel = new JTextField(10);
JPasswordField pw = new JPasswordField(10);
JButton log = new JButton("登录");
JButton regi = new JButton("注册");
JButton exit = new JButton("退出");
String ip = null;
Log(){
super("登录");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setBounds(500, 200, 400, 219);
this.setLayout(null);
jl.setBounds(0, -80, 400, 300);
ltel.setBounds(50, 40, 60, 30);
lpw.setBounds(50, 80, 60, 30);
laddr.setBounds(50, 120, 60, 30);
tel.setBounds(120, 40, 200, 30);
pw.setBounds(120, 80, 200, 30);
addr.setBounds(120, 120, 200, 30);
log.setBounds(80, 169, 60, 30);
regi.setBounds(180, 169, 60, 30);
exit.setBounds(280, 169, 60, 30);
log.setContentAreaFilled(false); //设置按钮透明
regi.setContentAreaFilled(false);
exit.setContentAreaFilled(false);
tel.setOpaque(false); //设置文本框透明
pw.setOpaque(false);
addr.setOpaque(false);
this.add(ltel);
this.add(lpw);
this.add(laddr);
this.add(addr);
this.add(tel);
this.add(pw);
this.add(log);
this.add(regi);
this.add(exit);
this.add(jl);
this.setResizable(false); //设置窗口大小不可改变
this.setUndecorated(true); //设置标题栏不可见
this.setVisible(true);
exit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
regi.addActionListener(new ActionListener(){
public void actionPerformed(Act
展开阅读全文