6.面向对象程序设计(1)
com.langsin.LZChat.client 项目的代码
首先是client包的
1.ClientConServer.java
package client; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import model.ToolsCreateMsg; import model.ToolsParseMsg; import msg.MsgHead; import msg.MsgLogin; import msg.MsgLoginResp; import msg.MsgReg; import msg.MsgRegResp; import msg.MsgType; import tools.LogTools; /*** * 客户端与服务器的即时通信模块 * * @author Administrator * 1.登陆,注册接口调用; * 2.在独立线程中接收服务器消息 * 3.将接受到的信息交给ManageUI管理 */ public class ClientConServer extends Thread { private static ClientConServer ccs; // 本类单实例对象 private Socket client; // 与服务器连接对象 private DataOutputStream dous; // 输出流对象 private DataInputStream dis; // 输入流对象 private ArrayList<ClientMsgListener> listeners = new ArrayList<ClientMsgListener>(); /** 不需要创建对象,所以构造器私有 */ private ClientConServer() { } public static ClientConServer getCcs() { if (null == ccs) ccs = new ClientConServer(); return ccs; } /** 连结上服务器, 返回是否连结成功 */ public boolean ConServer() { try { client = new Socket(MsgType.serverIP, MsgType.serverPort); this.dous = new DataOutputStream(client.getOutputStream()); this.dis = new DataInputStream(client.getInputStream()); return true; } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } /** * 注册服务器 * * @param pwd * @param nickname * @param sex * @param icon * @return 注册结果 -1 失败 其他事注册到的qq号 */ public int regServer(String pwd, String nickname, String sex, byte icon) { try { MsgReg mr = new MsgReg(); mr.setTotalLen(4 + 1 + 4 + 4 + 10 + 10 + 10 + 1); mr.setType(MsgType.command_reg); mr.setDest(MsgType.SERVER_QQ_NUMBER); mr.setSrc(0); mr.setNickname(nickname); mr.setPwd(pwd); mr.setSex(sex); mr.setIcon(icon); this.sendMsg(mr); MsgRegResp mrr = (MsgRegResp) readFromServer(); LogTools.INFO(this.getClass(), mrr.toString()); if (mrr.getState() == 0) return mrr.getDest(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return -1; } /** * 登陆到服务器 * * @param qq * @param pwd * @return 是否登陆成功 */ public boolean loginServer(int qq, String pwd) { try { MsgLogin ml = new MsgLogin(); ml.setTotalLen(4 + 1 + 4 + 4 + 10); ml.setType(MsgType.command_login); ml.setDest(MsgType.SERVER_QQ_NUMBER); ml.setSrc(qq); ml.setPwd(pwd); ml.setQq(qq); this.sendMsg(ml); MsgLoginResp mlr = (MsgLoginResp) readFromServer(); LogTools.INFO(this.getClass(), mlr.toString()); if (mlr.getState() == 0) { return true; } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } @Override public void run() { while (true) { try { MsgHead msg = readFromServer(); for (ClientMsgListener listener : listeners) { System.out.println("run"+msg.getType()); listener.dealMsg(msg); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); break; } } } /** * 加入到监听列表中 * @param lisetener */ public void addMsgListener(ClientMsgListener lisetener){ this.listeners.add(lisetener); } /** * 从监控列表中删除 * @param lisetener */ public void removwMsgListenner(ClientMsgListener lisetener){ this.listeners.remove(lisetener); } /* * 下面是各个界面中写入类属性的代码 (不应在此处) * */ // public static void Find(){ // // //command_find // MsgHead msg = new MsgHead(); // msg.setTotalLen(4+1+4+4); // msg.setSrc(ClientConServer.ownerQQ); // msg.setDest(MsgType.SERVER_QQ_NUMBER); // msg.setType(MsgType.command_find); // // //command_addFriend // MsgAddFriend maf = new MsgAddFriend(); // maf.setTotalLen(4+1+4+4+30+4); // maf.setSrc(ClientConServer.ownerQQ); // maf.setDest(要加的人的qq); // maf.setType(MsgType.command_addFriend); // maf.setNote("备注"); // maf.setFriendQq(要加的人的qq); // // //command_addYouResp // MsgAddYouResp mayr = new MsgAddYouResp(); // mayr.setTotalLen(4+1+4+4+1); // mayr.setSrc(ClientConServer.ownerQQ); // mayr.setDest(要加你的人的qq); // mayr.setType(MsgType.command_addYouResp); // mayr.setState((byte)0同意 1不同意); // // //command_chatText command_chatFile(最后再说) // MsgChatText mct = new MsgChatText(); // int changdu = content.getBytes().size(); //计算String的字节长度 // mct.setTotalLen(4+1+4+4+20+changdu); // mct.setSrc(ClientConServer.ownerQQ); // mct.setDest(要加你的人的qq); // mct.setType(MsgType.command_chatText); // mct.setContent(content); //content是要发送的字符串 // mct.setTime("时间 字符串类型 最长20字节"); // // // //最后都调用 ClientConServer的发送方法(sendMse)将类发给服务器 // // } /** * 从输入流上读取一条服务器端发来的消息 这个方法会阻塞,必须在独立线程中 * * @return:读取到的消息对象 */ public MsgHead readFromServer() throws Exception { int totalLen = dis.readInt(); LogTools.INFO(this.getClass(), "客户端读到消息总长为:" + totalLen); byte[] data = new byte[totalLen - 4]; dis.readFully(data); // 读取数据块 MsgHead msg = ToolsParseMsg.parseMsg(data);// 解包为消息对象 LogTools.INFO(this.getClass(), "客户端收到消息:" + msg); return msg; } /** 发送一条消息到服务器的方法 */ public void sendMsg(MsgHead msg) throws Exception { LogTools.INFO(this.getClass(), "客户端发出消息:" + msg); byte[] data = ToolsCreateMsg.packMsg(msg);// 打包对象为数据块 this.dous.write(data);// 发送 this.dous.flush(); } // 关闭与一个客户机的连结 public void closeMe() { try { this.client.close(); } catch (Exception ef) { } } }
2.ClientMsgListener.java
1 package client; 2 3 import msg.MsgHead; 4 5 /*** 6 * 接受消息的接口 7 * @author Administrator 8 * 9 */ 10 public interface ClientMsgListener { 11 12 /** 13 * 从服务器接收到的一条信息 14 */ 15 public void dealMsg(MsgHead msg); 16 }
3.ManageUI
package client; import java.util.HashMap; import javax.swing.JFrame; import msg.MsgAddFriendResp; import msg.MsgAddYou; import msg.MsgChatFile; import msg.MsgChatText; import msg.MsgFindResp; import msg.MsgHead; import msg.MsgTeamList; import msg.MsgType; public class ManageUI { // 聊天界面 String是 “本人qq 他人qq” private static HashMap<String, JFrame> chats = new HashMap<String, JFrame>(); //得到服务器的数据 public static void getMsg(MsgHead msg){ switch (msg.getType()) { case MsgType.command_teamList: MsgTeamList mtl = (MsgTeamList) msg; break; case MsgType.command_chatText: MsgChatText mct = (MsgChatText) msg; // 在此处新建聊天窗口 并加入到chats里 break; case MsgType.command_chatFile: MsgChatFile mcf = (MsgChatFile) msg; // 同上 暂时未做 最后再说 break; case MsgType.command_find_resp: MsgFindResp mfr = (MsgFindResp) msg; // 此处新建 查询好友列表 break; case MsgType.command_addFriend_Resp: MsgAddFriendResp mafr = (MsgAddFriendResp) msg; // 新建添加成功界面 break; case MsgType.command_addYou: MsgAddYou may = (MsgAddYou) msg; // 新建 有人添加你的界面 break; case MsgType.command_onLine: // 提示好友上线 // 此处调用一个 QqClientFriendsList类里的方法 该方法改变界面的显示 break; case MsgType.command_offLine: // 提示好友下线 同上 break; default: break; } } }
model包的
1.TeamInfo.java
package model; import java.io.Serializable; import java.util.ArrayList; /*** * 好友分组 * @author Administrator * */ @SuppressWarnings("serial") public class TeamInfo implements Serializable{ private int id; //分组id private String name; //分组名字 private int ownerUser; //所有者 //在此分组内的好友列表 private ArrayList<UserInfo> friendList = new ArrayList<UserInfo>(); public TeamInfo(int id, String name, int ownerUser) { this.id = id; this.name = name; this.ownerUser = ownerUser; } /** * 为此分组加入一个成员 * @param info */ public void addFriend(UserInfo info){ this.friendList.add(info); } public TeamInfo(String name) { this.name = name; } //get set 方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getOwnerUser() { return ownerUser; } public void setOwnerUser(int ownerUser) { this.ownerUser = ownerUser; } public ArrayList<UserInfo> getFriendList() { return friendList; } public void setFriendList(ArrayList<UserInfo> friendList) { this.friendList = friendList; } }
2.ToolsCreateMsg.java
package model; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; import msg.MsgAddFriend; import msg.MsgAddFriendResp; import msg.MsgAddYou; import msg.MsgAddYouResp; import msg.MsgChatFile; import msg.MsgChatText; import msg.MsgFindResp; import msg.MsgHead; import msg.MsgLogin; import msg.MsgLoginResp; import msg.MsgPerData; import msg.MsgReg; import msg.MsgRegResp; import msg.MsgTeamList; import msg.MsgType; import tools.LogTools; /*** * 打包消息 * @author Administrator * */ public class ToolsCreateMsg { /** * 将消息对象打包成字节数组返回 * @param msg 要打包的消息对象 * @return 返回的字节数组 * @throws IOException */ public static byte[] packMsg(MsgHead msg) throws IOException{ ByteArrayOutputStream bous = new ByteArrayOutputStream(); DataOutputStream dous = new DataOutputStream(bous); writeHead(dous, msg); int msgType = msg.getType(); switch (msgType) { //注册 case MsgType.command_reg: MsgReg mr = (MsgReg)msg; writeString(dous, 10, mr.getNickname()); writeString(dous, 10, mr.getPwd()); writeString(dous, 10, mr.getSex()); dous.writeByte((byte)mr.getIcon()); break; //注册应答 case MsgType.command_reg_resp: MsgRegResp mrr = (MsgRegResp)msg; dous.writeByte(mrr.getState()); break; //登陆 case MsgType.command_login: MsgLogin ml = (MsgLogin) msg; writeString(dous, 10, ml.getPwd()); break; //登陆应答 case MsgType.command_login_resp: MsgLoginResp mlr = (MsgLoginResp) msg; dous.writeByte(mlr.getState()); break; //好友列表 case MsgType.command_teamList: MsgTeamList mtl = (MsgTeamList)msg; ArrayList<TeamInfo> teams = mtl.getTeamList(); int listCount = teams.size(); dous.writeInt(listCount); //写入分组个数 for (TeamInfo teamInfo : teams) { writeString(dous, 10, teamInfo.getName()); //写入分组名字 ArrayList<UserInfo> users = teamInfo.getFriendList(); dous.writeByte(users.size()); //写入一个分组的成员个数 for (UserInfo userInfo : users) { dous.writeInt(userInfo.getQq()); //写入qq号 writeString(dous, 10, userInfo.getNickname()); //写入昵称 writeString(dous, 10, userInfo.getSex()); //写入性别 dous.writeByte(userInfo.getIcon()); //写入头像 dous.writeByte(userInfo.getOnLine()); //写入是否在线 } } break; //返回在线qq号码 case MsgType.command_find_resp: MsgFindResp mfr = (MsgFindResp)msg; ArrayList<UserInfo> users = mfr.getUsers(); dous.writeInt(users.size()); //写入在线qq的数量 for (UserInfo userInfo : users) { dous.writeInt(userInfo.getQq()); //写入qq 昵称 性别 头像 writeString(dous, 10, userInfo.getNickname()); writeString(dous, 10, userInfo.getSex()); dous.writeByte(userInfo.getIcon()); } // for (int i = 0; i < count; i++) { // UserInfo userInfo = users.get(i); // dous.writeInt(userInfo.getQq()); // writeString(dous, 10, userInfo.getNickname()); // writeString(dous, 10, userInfo.getSex()); // } break; //添加好友 case MsgType.command_addFriend: MsgAddFriend maf = (MsgAddFriend) msg; dous.writeInt(maf.getFriendQq()); writeString(dous, 30, maf.getNote()); //!!!!!!30字节长度!!!!!! break; //添加好友应答 case MsgType.command_addFriend_Resp: MsgAddFriendResp magr = (MsgAddFriendResp) msg; dous.writeByte(magr.getState()); //对方是否同意 dous.writeInt(magr.getQq()); //对方qq writeString(dous, 10, magr.getNickName()); //对方昵称 writeString(dous, 10, magr.getSex()); //对方的性别 dous.writeByte(magr.getIcon()); break; //有人添加你为好友 case MsgType.command_addYou: MsgAddYou may = (MsgAddYou) msg; writeString(dous, 10, may.getNickname()); //昵称 writeString(dous, 10, may.getSex()); //性别 writeString(dous, 30, may.getNote()); //备注信息 break; //有人添加你为好友 的 回复 case MsgType.command_addYouResp: MsgAddYouResp mayr = (MsgAddYouResp) msg; dous.writeByte(mayr.getState()); break; //聊天信息 case MsgType.command_chatText: MsgChatText mct = (MsgChatText) msg; writeString(dous, 20, mct.getTime()); dous.write(mct.getContent().getBytes()); break; //文件传输 case MsgType.command_chatFile: MsgChatFile mcf = (MsgChatFile) msg; writeString(dous, 20, mcf.getTime()); writeString(dous, 256, mcf.getFileName()); dous.write(mcf.getFileData()); break; case MsgType.command_perdata: MsgPerData mpd = (MsgPerData) msg; writeString(dous, 10, mpd.getNickname()); writeString(dous, 10, mpd.getSex()); dous.writeByte(mpd.getIcon()); break; //返回在线qq号码请求 case MsgType.command_find: case MsgType.command_onLine: case MsgType.command_offLine: case MsgType.command_vibration: break; default: String logMsg="创建未知消息类型,无法打包:type:"+msgType; LogTools.ERROR(ToolsCreateMsg.class, logMsg); //记录日志 break; } dous.flush(); byte[] data = bous.toByteArray(); return data; } /** * 向流中写入消息头信息 * @param dous 要写入的流对象 * @param msg 消息头对象 * @throws IOException */ public static void writeHead(DataOutputStream dous,MsgHead msg) throws IOException{ dous.writeInt(msg.getTotalLen()); dous.writeByte(msg.getType()); dous.writeInt(msg.getSrc()); dous.writeInt(msg.getDest()); } /** * 向流中写入len长的字符串 * @param dous 要写入的输出流 * @param len 要写入字符串的长度 * @param s 要写入的字符串 * @throws IOException */ public static void writeString(DataOutputStream dous,int len,String s) throws IOException{ byte[] data = s.getBytes(); if(data.length>len) throw new IOException("写入长度为:"+len+",文本过长!"); dous.write(data); while(len>data.length){//如果短,需要补0 dous.writeByte('\0'); //补二进制的0 len--; } } }
3.ToolsParseMsg.java
package model; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; import msg.MsgAddFriend; import msg.MsgAddFriendResp; import msg.MsgAddYou; import msg.MsgAddYouResp; import msg.MsgChatFile; import msg.MsgChatText; import msg.MsgFindResp; import msg.MsgHead; import msg.MsgLogin; import msg.MsgLoginResp; import msg.MsgPerData; import msg.MsgReg; import msg.MsgRegResp; import msg.MsgTeamList; import msg.MsgType; import tools.LogTools; /*** * 解包消息 * * @author Administrator * */ public class ToolsParseMsg { public static MsgHead parseMsg(byte[] data) throws IOException { int totalLen = data.length + 4; // 算出消息总长 ByteArrayInputStream bis = new ByteArrayInputStream(data); DataInputStream dis = new DataInputStream(bis); byte msgType = dis.readByte(); int src = dis.readInt(); int dest = dis.readInt(); MsgHead msgHead = new MsgHead(); msgHead.setTotalLen(totalLen); msgHead.setType(msgType); msgHead.setSrc(src); msgHead.setDest(dest); //根据类型进行判断 switch (msgType) { //注册 case MsgType.command_reg: MsgReg mr = new MsgReg(); copyHead(msgHead, mr); String nickname = readString(dis, 10); mr.setNickname(nickname); String pwd = readString(dis, 10); mr.setPwd(pwd); String sex = readString(dis, 10); mr.setSex(sex); byte icon = dis.readByte(); mr.setIcon(icon); return mr; //注册应答 case MsgType.command_reg_resp: MsgRegResp mrr = new MsgRegResp(); copyHead(msgHead, mrr); mrr.setState(dis.readByte()); return mrr; //登陆 case MsgType.command_login: MsgLogin ml = new MsgLogin(); copyHead(msgHead, ml); ml.setPwd(readString(dis, 10)); return ml; //登陆应答 case MsgType.command_login_resp: MsgLoginResp mlr = new MsgLoginResp(); copyHead(msgHead, mlr); mlr.setState(dis.readByte()); return mlr; //好友列表 case MsgType.command_teamList: MsgTeamList mtl =new MsgTeamList(); copyHead(msgHead, mtl); int listCount = dis.readInt(); //得到分组个数 ArrayList<TeamInfo> teamList = new ArrayList<TeamInfo>(); for (int i = 0; i < listCount; i++) { String groupName = readString(dis, 10); //得到某一分组名字 TeamInfo teamInfo = new TeamInfo(groupName); byte usersCount = dis.readByte(); //得到某一分组的成员个数 for (int j = 0; j < usersCount; j++) { int qq = dis.readInt(); //得到qq号码 String nickname2 = readString(dis, 10); //得到昵称 String sex2 = readString(dis, 10); //得到性别 byte teamList_icon = dis.readByte(); //得到头像 byte onLine = dis.readByte(); //得到是否在线 UserInfo userInfo = new UserInfo(qq, nickname2, sex2); userInfo.setOnLine(onLine); userInfo.setIcon(teamList_icon); teamInfo.addFriend(userInfo); } teamList.add(teamInfo); } mtl.setTeamList(teamList); return mtl; //在线qq列表 返回 case MsgType.command_find_resp: MsgFindResp mfr = new MsgFindResp(); copyHead(msgHead, mfr); int count = dis.readInt(); for (int i = 0; i < count; i++) { int qq = dis.readInt(); String nickName = readString(dis, 10); String mfr_sex = readString(dis, 10); byte find_resp_icon = dis.readByte(); UserInfo userInfo = new UserInfo(qq, nickName, mfr_sex); userInfo.setIcon(find_resp_icon); mfr.addQq(userInfo); } return mfr; //添加好友 请求 case MsgType.command_addFriend: MsgAddFriend maf = new MsgAddFriend(); copyHead(msgHead, maf); maf.setFriendQq(dis.readInt()); String note = readString(dis, 30); //!!!!!!30字节长度!!!!!! maf.setNote(note); return maf; //添加好友 回复 case MsgType.command_addFriend_Resp: MsgAddFriendResp mafr = new MsgAddFriendResp(); copyHead(msgHead, mafr); mafr.setState(dis.readByte()); mafr.setQq(dis.readInt()); String nickName = readString(dis, 10); mafr.setNickName(nickName); String addFriend_Resp_sex = readString(dis, 10); //性别 mafr.setSex(addFriend_Resp_sex); mafr.setIcon(dis.readByte()); return mafr; //有人添加你为好友 case MsgType.command_addYou: MsgAddYou may = new MsgAddYou(); copyHead(msgHead, may); String addYou_nickname = readString(dis, 10); may.setNickname(addYou_nickname); String addYou_sex = readString(dis, 10); //性别 may.setSex(addYou_sex); String addYou_note = readString(dis, 30); //备注 may.setNote(addYou_note); return may; //有人添加你为好友 的 回复 case MsgType.command_addYouResp: MsgAddYouResp mayr = new MsgAddYouResp(); copyHead(msgHead, mayr); mayr.setState(dis.readByte()); return mayr; //聊天信息 case MsgType.command_chatText: MsgChatText mct = new MsgChatText(); copyHead(msgHead, mct); String time = readString(dis, 20); mct.setTime(time); int len = totalLen-4-1-4-4-20; String chat = readString(dis, len); mct.setContent(chat); return mct; //文件传输 case MsgType.command_chatFile: MsgChatFile mcf = new MsgChatFile(); copyHead(msgHead, mcf); String chatFile_time = readString(dis, 20); mcf.setTime(chatFile_time); String fileName = readString(dis, 256); mcf.setFileName(fileName); int filelen = totalLen-4-1-4-4-256-20; byte[] fileData = new byte[filelen]; dis.readFully(fileData); mcf.setFileData(fileData); return mcf; case MsgType.command_perdata: MsgPerData mpd = new MsgPerData(); copyHead(msgHead, mpd); String perdata_nickname = readString(dis, 10); mpd.setNickname(perdata_nickname); String perdata_sex = readString(dis, 10); mpd.setSex(perdata_sex); mpd.setIcon(dis.readByte()); return mpd; //返回在线qq号码请求 case MsgType.command_find: case MsgType.command_onLine: case MsgType.command_offLine: case MsgType.command_vibration: return msgHead; default: String logMsg = "解包未知消息类型,无法解包:type:" + msgType; LogTools.ERROR(ToolsParseMsg.class, logMsg); //记录日志信息 break; } return null; } /** * 复制消息头的数据 * @param head 消息头 * @param dest 要复制到的对象 */ public static void copyHead(MsgHead head,MsgHead dest){ dest.setTotalLen(head.getTotalLen()); dest.setType(head.getType()); dest.setSrc(head.getSrc()); dest.setDest(head.getDest()); } /** * 从流中读取len长度的字节 * @param dous 流数据 * @param len 长度 * @throws IOException */ public static String readString(DataInputStream dis,int len) throws IOException{ byte[] data = new byte[len]; dis.readFully(data); return new String(data); } }
4.UserDao.java
package model; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Collections; import java.util.HashMap; import java.util.Map; import tools.LogTools; /*** * 数据存储 * @author Administrator * */ @SuppressWarnings({ "unchecked", "rawtypes" }) public class UserDao { private static int maxQQNumber = 1000; private static final String dbFileName = "qq.dat"; private static Map<Integer, UserInfo> userDB = new HashMap<Integer,UserInfo>(); static{ try { File file = new File(dbFileName); if(file.exists()&&!file.isDirectory()){ ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)); userDB = (Map)ois.readObject(); LogTools.INFO(UserDao.class, "从数据文件读取数据成功!"); }else{ LogTools.ERROR(UserDao.class, "不存在数据文件,创建空表"); } } catch (Exception e) { // TODO: handle exception } } //用户登录 public static UserInfo checkLogin(int qq,String pwd){ UserInfo user = userDB.get(qq); if(null!=user && pwd.equals(user.getPwd())){ LogTools.INFO(UserDao.class, "登录成功!"); return user; } LogTools.ERROR(UserDao.class, "登录失败!"); return null; } //注册用户 public static int regUser(String pwd,String nickname,String sex){ if(userDB.size()>0){ maxQQNumber = Collections.max(userDB.keySet()); } maxQQNumber++; UserInfo user = new UserInfo(maxQQNumber); user.setPwd(pwd); user.setNickname(nickname); user.setSex(sex); userDB.put(maxQQNumber, user); saveDB(); return maxQQNumber; } //将内存中的数据保存到文件中 private static void saveDB(){ try { ObjectOutputStream ois = new ObjectOutputStream(new FileOutputStream(dbFileName)); ois.writeObject(userDB); ois.close(); LogTools.INFO(UserDao.class, "刷新数据文件成功!"); } catch (Exception e) { LogTools.ERROR(UserDao.class, "刷新数据文件失败:"+e); } } /** * 根据qq号码 得到用户的信息 * @param qq qq号码 * @return 用户的信息 */ public static UserInfo getUserInfo(int qq){ return userDB.get(qq); } /** * 添加好友的数据库操作 * @param qq1 * @param qq2 相互添加好友的号码 * @param groupName1 * @param groupName2 分别加入的群组 */ public static void addFriend(int qq1,int qq2,String groupName1,String groupName2){ UserInfo user1 = getUserInfo(qq1); UserInfo user2 = getUserInfo(qq2); //暂时默认添加到好友队列 user1.getTeams().get(0).addFriend(user2); user2.getTeams().get(0).addFriend(user1); //保存 saveDB(); } }
5.UserInfo.java
package model; import java.io.Serializable; import java.util.ArrayList; /*** * 用户类 * @author Administrator * */ @SuppressWarnings("serial") public class UserInfo implements Serializable{ private int qq; //qq号码 private String pwd; //密码 private String nickname; //用户昵称 private String sex; //用户性别 private byte icon; //头像 private byte onLine = 1; //用户是否在线 默认为1 即不在线 private ArrayList<TeamInfo> teams = new ArrayList<TeamInfo>(); //好友列表 public UserInfo(int qq){ this.qq = qq; init(); } public UserInfo(int qq,String nickname,String sex){ this.qq = qq; this.nickname = nickname; this.sex = sex; init(); } //初始化用户 public void init(){ TeamInfo team1,team2,team3; team1= new TeamInfo(0, "我的好友", this.qq); team2= new TeamInfo(1, "陌生人", this.qq); team3= new TeamInfo(2, "黑名单", this.qq); this.teams.add(team1); this.teams.add(team2); this.teams.add(team3); } public void addTeam(TeamInfo team){ this.teams.add(team); } //get set 方法 public int getQq() { return qq; } public byte getIcon() { return icon; } public void setIcon(byte icon) { this.icon = icon; } public byte getOnLine() { return onLine; } public void setOnLine(byte onLine) { this.onLine = onLine; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public void setQq(int qq) { this.qq = qq; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public ArrayList<TeamInfo> getTeams() { return teams; } public void setTeams(ArrayList<TeamInfo> teams) { this.teams = teams; } @Override public String toString() { return "UserInfo [qq=" + qq + ", nickname=" + nickname + ", sex=" + sex + ", icon=" + icon + "]"; } }
msg包代码
package msg; /*** * 消息:添加好友 * friendQq 此属性暂时没有作用 * @author Administrator * */ public class MsgAddFriend extends MsgHead{ private int friendQq; //好友qq号码 private String note; //备注 30字节长度!!!!!!!!!!!! public String getNote() { return note; } public void setNote(String note) { this.note = note; } public int getFriendQq() { return friendQq; } public void setFriendQq(int friendQq) { this.friendQq = friendQq; } @Override public String toString() { String head = super.toString(); return head+"MsgAddFriend [friendQq=" + friendQq + ", note=" + note + "]"; } }
package msg; /*** * 消息:好友添加 应答 * @author Administrator * */ public class MsgAddFriendResp extends MsgHead{ private byte state; //是否同意 private int qq; //好友qq号 private String nickName; //好友昵称 private String sex; //好友性别 private byte icon; public byte getIcon() { return icon; } public void setIcon(byte icon) { this.icon = icon; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public byte getState() { return state; } public void setState(byte state) { this.state = state; } public int getQq() { return qq; } public void setQq(int qq) { this.qq = qq; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } @Override public String toString() { String head = super.toString(); return head+"MsgAddFriendResp [state=" + state + ", qq=" + qq + ", nickName=" + nickName + ", sex=" + sex + ", icon=" + icon + "]"; } }
package msg; /** * 消息: 有人添加你 * @author Administrator * */ public class MsgAddYou extends MsgHead{ private String nickname; //要添加你的人的昵称 private String sex; //要添加你的人的性别 private String note; //验证信息 public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public String getNote() { return note; } public void setNote(String note) { this.note = note; } @Override public String toString() { String head = super.toString(); return head+"MsgAddYou [nickname=" + nickname + ", sex=" + sex + ", note=" + note + "]"; } }
package msg; /*** * 消息:发送聊天文本 * @author Administrator * */ public class MsgChatText extends MsgHead{ private String time; //发送时间 20 private String content; //聊天信息 public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { String head = super.toString(); return head+"MsgChatText [time=" + time + ", content=" + content + "]"; } }
package msg; import java.util.Arrays; /*** * 消息:文件传输 * @author Administrator * */ public class MsgChatFile extends MsgHead{ private String time; //发送时间 20 private String fileName; //文件名字 private byte[] fileData; //文件内容 public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public byte[] getFileData() { return fileData; } public void setFileData(byte[] fileData) { this.fileData = fileData; } @Override public String toString() { String head = super.toString(); return head+"MsgChatFile [fileName=" + fileName + ", fileData=" + Arrays.toString(fileData) + "]"; } }
package msg; /** * 消息:有人添加你 回复 * @author Administrator * */ public class MsgAddYouResp extends MsgHead{ private byte state; //是否同意添加你为好友 public byte getState() { return state; } public void setState(byte state) { this.state = state; } @Override public String toString() { String head = super.toString(); return head+"MsgAddYouResp [state=" + state + "]"; } }
package msg; /*** * 定义通讯用到的常量 * @author Administrator * */ public interface MsgType { String serverIP = "localhost"; int serverPort = 9999; int SERVER_QQ_NUMBER = 10000; //客户端请求操作的 成功与否 int state_success = 0; int state_false = 1; //消息类型的定义 byte command_reg = 0X01; //注册账号 byte command_reg_resp = 0X02; //注册账号应答 byte command_login=0x03; //登陆请求消息 byte command_login_resp=0x4; //登陆应答消息 byte command_teamList=0x05; //服务器发送在线好友列表 byte command_perdata=0x16; //个人信息 byte command_onLine=0x06; //服务器发送好友上线消息*无消息体 byte command_offLine=0x07; //服务器发送好友下线消息*无消息体 byte command_chatText=0x08; //聊天消息发送 byte command_chatFile=0x09; //文件传送发送 byte command_find=0x10; //查找用户请求 *无消息体 byte command_find_resp=0x11; //查找好友请求应答 byte command_addFriend=0x12; //添加好友请求 byte command_addFriend_Resp=0x13; //添加好友应答 byte command_addYou=0x14; //添加你为好友 byte command_addYouResp=0x15; //添加你为好友 的 回复 byte command_vibration=0x17; //发送震动窗口 }
package msg; import java.util.ArrayList; import model.TeamInfo; /** * 好友分组信息 * @author Administrator * */ public class MsgTeamList extends MsgHead{ //存放好友的队列 private ArrayList<TeamInfo> teamList = new ArrayList<TeamInfo>(); public ArrayList<TeamInfo> getTeamList() { return teamList; } public void setTeamList(ArrayList<TeamInfo> teamList) { this.teamList = teamList; } @Override public String toString() { @SuppressWarnings("unused") String head = super.toString(); return "MsgTeamList [teamList=" + teamList + "]"; } }
package msg; /*** * 消息:用户注册 应答 * @author Administrator * */ public class MsgRegResp extends MsgHead{ private byte state; ////注册状态 @Override public String toString() { String head = super.toString(); return head+"MsgRegResp [state=" + state + "]"; } public byte getState() { return state; } public void setState(byte state) { this.state = state; } }
package msg; /*** * 消息:用户注册 * @author Administrator * */ public class MsgReg extends MsgHead{ private String pwd; //用户密码 private String nickname; //用户昵称 private String sex; //用户性别 private byte icon; //头像 @Override public String toString() { String head = super.toString(); return head+"MsgReg [pwd=" + pwd + ", nickname=" + nickname + ", sex=" + sex + ", icon=" + icon + "]"; } public byte getIcon() { return icon; } public void setIcon(byte icon) { this.icon = icon; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } }
package msg; /*** * 登陆成功后 返回个人信息 * @author Administrator * */ public class MsgPerData extends MsgHead{ private String nickname; private String sex; private byte icon; public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public byte getIcon() { return icon; } public void setIcon(byte icon) { this.icon = icon; } @Override public String toString() { String head = super.toString(); return head+"MsgPerData [nickname=" + nickname + ", sex=" + sex + ", icon=" + icon + "]"; } }
package msg; /*** * 消息:登录 应答 * @author Administrator * */ public class MsgLoginResp extends MsgHead{ private byte state; ///登陆状态 0:成功 其它:失败代码 @Override public String toString() { String head = super.toString(); return head+"MsgLoginResp [state=" + state + "]"; } public byte getState() { return state; } public void setState(byte state) { this.state = state; } }
package msg; /*** * 消息:用户登录 * @author Administrator * */ public class MsgLogin extends MsgHead{ private int qq; //账号 private String pwd; //密码 public int getQq() { return qq; } public void setQq(int qq) { this.qq = qq; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { String head = super.toString(); return head+"MsgLogin [qq=" + qq + ", pwd=" + pwd + "]"; } }
package msg; /*** * 所有消息的头部 * @author Administrator * */ public class MsgHead { private int totalLen;//消息总长度 private byte type; //消息类型 private int src; //发送用户的号码 private int dest; //目标用户的号码 @Override public String toString() { return "MsgHead [totalLen=" + totalLen + ", type=" + type + ", src=" + src + ", dest=" + dest + "]"; } //get set 方法 public int getTotalLen() { return totalLen; } public void setTotalLen(int totalLen) { this.totalLen = totalLen; } public byte getType() { return type; } public void setType(byte type) { this.type = type; } public int getSrc() { return src; } public void setSrc(int src) { this.src = src; } public int getDest() { return dest; } public void setDest(int dest) { this.dest = dest; } }
package msg; import java.util.ArrayList; import model.UserInfo; /*** * 消息:放回在线的所有qq号码 * @author Administrator * */ public class MsgFindResp extends MsgHead{ //在线列表 private ArrayList<UserInfo> users = new ArrayList<UserInfo>(); //向在线列表中添加 public void addQq(UserInfo user){ this.users.add(user); } public ArrayList<UserInfo> getUsers() { return users; } @Override public String toString() { String head = super.toString(); return head+"MsgFindResp [users=" + users + "]"; } }
tools包
package tools; import java.awt.*; import javax.swing.*; @SuppressWarnings("serial") public class RoundButton extends JButton { public RoundButton(String label) { super(label); // 调用父类构造函数 setContentAreaFilled(false); // 不自行绘制按钮背景 } // 绘制圆和标签 protected void paintComponent(Graphics g) { if (getModel().isArmed()) { // 鼠标点击时 g.setColor(Color.lightGray); // 颜色为灰色 } else { g.setColor(getBackground()); // 置按钮颜色 } g.fillOval(0, 0, getSize().width, getSize().height); // 绘制圆 super.paintComponent(g); // 调用父类函数,绘制其余部分 } // 绘制边框 protected void paintBorder(Graphics g) { g.setColor(getForeground()); // 设置边框颜色 g.drawOval(0, 0, getSize().width - 1, getSize().height - 1); // 在边界上绘制一个椭圆 } }
package tools; import java.util.Random; public class RandomGetYanzheng { Random ran; String str; String yanzhengma; public String randomGetFiveBitYanzheng() { ran = new Random(); str = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"; yanzhengma = ""; for (int i = 0; i < 5; i++) { // System.out.println("随机出来的下标是:" + ran.nextInt(36)); // System.out.println("对应下标的数是:" + str.charAt(ran.nextInt(36))); yanzhengma = yanzhengma + str.charAt(ran.nextInt(36)); } System.out.println(yanzhengma); return yanzhengma; } public void changeGetFiveBitYanzheng() { ran = new Random(); str = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"; yanzhengma = ""; for (int i = 0; i < 5; i++) { yanzhengma = yanzhengma + str.charAt(ran.nextInt(36)); } } public static void main(String[] args) { new RandomGetYanzheng().randomGetFiveBitYanzheng(); } }
package tools; public class MyMouseEvent { /** * * @Title: getMouseEvent * @Description: TODO(传入鼠标X,Y坐标以及图片的X,Y坐标 以确定鼠标事件的范围) * @param @param mouseX 鼠标的X坐标 * @param @param mouseY 鼠标的Y坐标 * @param @param imageX 图片的X坐标 * @param @param imageY 图片的Y坐标 * @param @return flag 鼠标是否存在此区? * @return boolean 返回类型 * @throws */ public static boolean getMouseEvent(int mouseX, int mouseY, int imageX, int imageY) { boolean flag; if (mouseX >= imageX && mouseX <= imageX + 78 && mouseY >= imageY && mouseY <= imageY + 44) { flag = true; } else { flag = false; } return flag; } }
package tools; import java.text.SimpleDateFormat; import java.util.Date; /*** * 系统日志记录工具类 * * @author Administrator * */ public class LogTools { private static boolean isDebug = true; // 是否打印标志 // 禁止输出日志信息 public static void disDebug() { isDebug = false; } /** * 记录一般日志信息 * * @param c * 消息所在类 * @param msg * 消息对象 */ public static void INFO(@SuppressWarnings("rawtypes") Class c, Object msg) { if (!isDebug) return; SimpleDateFormat sdf = new SimpleDateFormat("HH-mm-ss"); String t = sdf.format(new Date()); System.out.println("INFO:" + t + " " + c.getSimpleName() + " " + msg); } /** * 记录出错日志信息 * * @param c * 消息所在类 * @param msg * 消息对象 */ public static void ERROR(@SuppressWarnings("rawtypes") Class c, Object msg) { if (!isDebug) return; SimpleDateFormat sdf = new SimpleDateFormat("hh-FF-ss"); String t = sdf.format(new Date()); System.out.println("INFO:" + t + " " + c.getSimpleName() + " " + msg); } }
package tools; import java.util.Random; import javax.swing.JFrame; public class Dancing implements Runnable { JFrame wind = null; Random rd = new Random(); public JFrame getWind() { return wind; } public void setWind(JFrame wind) { this.wind = wind; } public Dancing(JFrame wind) { this.wind = wind; } @SuppressWarnings("static-access") public void run() { for (int i = 0; i < 8; i++) { wind.setLocation(450 + rd.nextInt(15), 130 + rd.nextInt(15)); try { Thread.currentThread().sleep(100); } catch (Exception e) { e.printStackTrace(); } } } }