[
  {
    "path": ".classpath",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"src\" path=\"src\"/>\n\t<classpathentry kind=\"con\" path=\"org.eclipse.jdt.launching.JRE_CONTAINER\"/>\n\t<classpathentry kind=\"lib\" path=\"lib/AbsoluteLayout.jar\"/>\n\t<classpathentry kind=\"lib\" path=\"lib/mysql-connector-java-5.0.4-bin.jar\"/>\n\t<classpathentry kind=\"lib\" path=\"lib/swing-layout-1.0.3.jar\"/>\n\t<classpathentry kind=\"output\" path=\"bin\"/>\n</classpath>\n"
  },
  {
    "path": ".gitignore",
    "content": "*.class\nbin"
  },
  {
    "path": ".project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>myqq</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t</buildSpec>\n\t<natures>\n\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": ".settings/org.eclipse.jdt.core.prefs",
    "content": "eclipse.preferences.version=1\norg.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\norg.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7\norg.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve\norg.eclipse.jdt.core.compiler.compliance=1.7\norg.eclipse.jdt.core.compiler.debug.lineNumber=generate\norg.eclipse.jdt.core.compiler.debug.localVariable=generate\norg.eclipse.jdt.core.compiler.debug.sourceFile=generate\norg.eclipse.jdt.core.compiler.problem.assertIdentifier=error\norg.eclipse.jdt.core.compiler.problem.enumIdentifier=error\norg.eclipse.jdt.core.compiler.source=1.7\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 小茗同学\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "﻿# 说明\n\nJava版SWing“高”仿QQ即时通聊天系统\n\n原贴地址：http://tieba.baidu.com/p/1933997044\n\n首先说明这是一个很老很老的小项目，还是12年的时候写的，代码真的很low很low，low到什么级别呢？low到很多变量都是用中文命名的！这次之所以重新整理上传到GitHub，是因为12年的时候曾把这个发到网上，然后竟然还有很多人想要代码，当时是上传到CSDN还设置了积分，不方便下载。虽然没什么技术含量，但感觉对新人应该还是有一点借鉴的地方的。\n\n用的是`Oracle`数据库（为方便安装，后来改为`MySQL`），`Swing`作界面。界面上高仿腾讯QQ的（特别是登录窗体,几乎与腾讯QQ2011没有区别 ），包括客户端和服务端，包含创建数据库的SQL命令，目前主要实现的功能包括私聊、表情发送、图片发送、文件传输、截图、群聊天室、系统公告、桌面弹窗、声音提醒、离线消息发送与接收等……\n\n![](capture/00.jpg)\n\n重要说明：\n\n1. 不会继续更新和维护，因为过去很多年了；\n2. 本身也有很多bug，仅限拿来玩玩；\n3. 代码质量不代表真实水平，毕竟，还是学生时代的作品。\n\n# 安装运行\n\n环境要求：`jdk1.7` + `mysql`。\n\n## 导入数据库\n\n本地新建一个名为`myqq`的数据库，utf-8编码，导入`myqq.sql`即可，其实这里面很简单，就2个表。\n\n## 导入Eclipse\n\n项目是一个JavaSE项目，使用Eclipse3.7开发，按普通项目导入Eclipse即可。如果导入之后有关`sun.audio.AudioPlayer.player`部分报如下错误：\n\n\tAccess restriction: The method start(InputStream) from the type AudioPlayer is not accessible due to restriction on required library D:\\GreenSoft\\Java\\jre7\\lib\\rt.jar\n\n可以先构建路径移除`JRE System Library`，然后再通过`Add Library`把`JRE System Library`添加回来即可。\n\n## 修改配置\n\n打开`com.MyTools.java`，修改服务器IP（本地测试时就是127.0.0.1）、服务器端口、数据库地址、数据库密码等。\n\n## 启动\n\n首先启动服务端：`server.frame.MainWindow.java`，记得要点击界面上的“启动MyQQ服务器”按钮，然后启动客户端：`client.control.Login.java`，要测试的话可以多启动几个客户端用不同账号测试。\n\n内置的3个测试账号：小茗同学、马化腾、吴阳阳，密码都是`123`。当然也可以自己注册一个。\n\n# 部分截图\n\n主窗体：\n\n![](capture/02.jpg)\n\n发起聊天：\n\n![](capture/03.jpg)\n\n互相聊天：\n\n![](capture/04.jpg)\n\n表情发送：\n\n![](capture/05.jpg)\n\n简单的聊天室：\n\n![](capture/06.jpg)\n\n系统弹窗公告：\n\n![](capture/07.jpg)\n\n进入聊天室：\n\n![](capture/08.jpg)\n\n非常简陋的后台：\n\n![](capture/09.jpg)\n"
  },
  {
    "path": "myqq.sql",
    "content": "/*\nNavicat MySQL Data Transfer\n\nSource Server         : localhost\nSource Server Version : 50505\nSource Host           : localhost:3306\nSource Database       : myqq\n\nTarget Server Type    : MYSQL\nTarget Server Version : 50505\nFile Encoding         : 65001\n\nDate: 2017-05-10 15:15:06\n*/\n\nSET FOREIGN_KEY_CHECKS=0;\n\n-- ----------------------------\n-- Table structure for `msg`\n-- ----------------------------\nDROP TABLE IF EXISTS `msg`;\nCREATE TABLE `msg` (\n  `msg_id` int(11) NOT NULL AUTO_INCREMENT,\n  `msg_content` varchar(2000) DEFAULT NULL,\n  `msg_sendfrom` int(11) DEFAULT NULL,\n  `msg_sendto` int(11) DEFAULT NULL,\n  `msg_sendtime` datetime DEFAULT NULL,\n  `msg_remark` varchar(3000) DEFAULT NULL,\n  `msg_type` varchar(10) DEFAULT NULL,\n  PRIMARY KEY (`msg_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n\n-- ----------------------------\n-- Records of msg\n-- ----------------------------\n\n-- ----------------------------\n-- Table structure for `users`\n-- ----------------------------\nDROP TABLE IF EXISTS `users`;\nCREATE TABLE `users` (\n  `u_id` int(11) NOT NULL AUTO_INCREMENT,\n  `u_name` varchar(50) DEFAULT NULL,\n  `u_pwd` varchar(50) DEFAULT NULL,\n  `u_ip` varchar(50) DEFAULT NULL,\n  `u_state` varchar(50) DEFAULT NULL,\n  `u_gender` varchar(50) DEFAULT NULL,\n  `u_email` varchar(50) DEFAULT NULL,\n  `u_last_login` datetime DEFAULT NULL,\n  `u_last_exit` datetime DEFAULT NULL,\n  `u_remarke` varchar(3000) DEFAULT NULL,\n  `u_signature` varchar(100) DEFAULT NULL,\n  `u_head_img` varchar(100) DEFAULT NULL,\n  `u_type` varchar(50) DEFAULT NULL,\n  `u_birthday` date DEFAULT NULL,\n  PRIMARY KEY (`u_id`)\n) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;\n\n-- ----------------------------\n-- Records of users\n-- ----------------------------\nINSERT INTO `users` VALUES ('1', '小茗同学', '123', '127.0.0.1', '-1', '男', 'jfs@qq.com', '2017-05-10 14:49:23', '2017-05-10 14:52:22', null, '大家好，我是小茗同学！', '0', null, '1992-07-28');\nINSERT INTO `users` VALUES ('2', '马化腾', '123', '127.0.0.1', '-1', '男', 'ss@qq.com', '2017-05-10 14:49:09', '2017-05-10 14:52:25', null, '哈哈，我是马化腾！', '3', null, '1992-07-28');\nINSERT INTO `users` VALUES ('3', '吴阳阳', '123', '172.16.4.97', '0', '男', 'fjs@qq.com ', '2015-04-21 18:01:57', null, null, '我与徐婷婷不得不说的事儿', '4', null, '1992-07-28');\n"
  },
  {
    "path": "src/client/common/ComboBoxRenderer.java",
    "content": "﻿package client.common;\n\nimport java.awt.Component;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.Image;\n\nimport javax.swing.ImageIcon;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.ListCellRenderer;\n\npublic class ComboBoxRenderer extends JLabel implements ListCellRenderer\n{\n\tprivate Font uhOhFont;\n\tprivate ImageIcon[] images=null;\n\tprivate String[] imageNames=null;\n\tpublic ComboBoxRenderer(ImageIcon[] images,String[] imageNames)\n\t{\n\t\tsetOpaque(true);\n\t\tsetHorizontalAlignment(CENTER);\n\t\tsetVerticalAlignment(CENTER);\n\t\tthis.imageNames=imageNames;\n\t\tthis.images=images;\n\t}\n\n\t/*\n\t * This method finds the image and text corresponding to the selected value\n\t * and returns the label, set up to display the text and image.\n\t */\n\tpublic Component getListCellRendererComponent(JList list, Object value,\n\t\t\tint index, boolean isSelected, boolean cellHasFocus)\n\t{\n\t\t// Get the selected index. (The index param isn't\n\t\t// always valid, so just use the value.)\n\t\tint selectedIndex = ((Integer) value).intValue();\n\n\t\tif (isSelected)\n\t\t{\n\t\t\tsetBackground(list.getSelectionBackground());\n\t\t\tsetForeground(list.getSelectionForeground());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsetBackground(list.getBackground());\n\t\t\tsetForeground(list.getForeground());\n\t\t}\n\n\t\t// Set the icon and text. If icon was null, say so.\n\t\tImageIcon icon = images[selectedIndex];\n\t\tString pet = imageNames[selectedIndex];\n\t\tsetIcon(icon);\n\t\tif (icon != null)\n\t\t{\n\t\t\tsetText(pet);\n\t\t\tsetFont(list.getFont());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsetUhOhText(pet + \" (没有有效的图片)\", list.getFont());\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t// Set the font and text when no image was found.\n\tprotected void setUhOhText(String uhOhText, Font normalFont)\n\t{\n\t\tif (uhOhFont == null)\n\t\t{ // lazily create this font\n\t\t\tuhOhFont = normalFont.deriveFont(Font.ITALIC);\n\t\t}\n\t\tsetFont(uhOhFont);\n\t\tsetText(uhOhText);\n\t}\n}\n"
  },
  {
    "path": "src/client/common/MyLabel.java",
    "content": "﻿package client.common;\n\nimport java.awt.Color;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JLabel;\n\nimport com.MyTools;\n\npublic class MyLabel\n{\n\t//规定：常规状态图片索引为1，鼠标进入为2，鼠标按下为3，鼠标释放还是2\n\tJLabel jLabel=null;\n\tString fileName=\"\";\n\tString extension=\"\";\n\tint mode=1;//模式为1表示用图片，模式为2表示用Boder\n\tColor backColor=null;//Label的父容器的背景色\n\t/**\n\t * 根据指定的若干张图片来实例化一个Label\n\t * @param fileName 图片的路径,不包括图片索引和扩展名，例如\n\t * 如果图片名为img/QQ_1.png，则写成\"../img/QQ\"\n\t * @param extension 扩展名，不包括前面的点\".\"\n\t */\n\tpublic MyLabel(JLabel jLabel,String fileName,String extension)\n\t{\n\t\tthis.jLabel=jLabel;\n\t\tthis.fileName=fileName;\n\t\tthis.extension=extension;\n\t}\n\tpublic MyLabel(JLabel jLabel)\n\t{\n\t\tthis.jLabel=jLabel;\n\t\tthis.mode=0;\n\t\tbackColor=this.jLabel.getParent().getBackground();\n\t\tsetEtchedBorder(backColor);//将label的默认边框颜色设置的和背景色一样，以达到不现实边框的作用\n\t}\n\tpublic MyLabel(JLabel jLabel,Color color)\n\t{\n\t\tthis.jLabel=jLabel;\n\t\tthis.mode=0;\n\t\tbackColor=color;\n\t\tsetEtchedBorder(backColor);\n\t}\n\n\t/**\n\t * 设置成一种边框，中文翻译作什么我也不知道\n\t * @param color\n\t */\n\tpublic void setEtchedBorder(Color color)\n\t{\n\t\tjLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder(color, color));\n\t}\n\t/**\n\t * 给jLabel添加事件\n\t */\n\tpublic void addEvent()\n\t{\n\t\tjLabel.addMouseListener(new MouseAdapter()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void mouseEntered(MouseEvent e)\n\t\t\t{\n\t\t\t\tif(mode==1)\n\t\t\t\t\tjLabel.setIcon(MyTools.getIcon(fileName+\"_2.\"+extension));\n\t\t\t\telse \n\t\t\t\t\tsetEtchedBorder(Color.red);\n\t\t\t}\n\t\t\t@Override\n\t\t\tpublic void mouseExited(MouseEvent e)\n\t\t\t{\n\t\t\t\tif(mode==1)\n\t\t\t\t\tjLabel.setIcon(MyTools.getIcon(fileName+\"_1.\"+extension));\n\t\t\t\telse \n\t\t\t\t\tsetEtchedBorder(backColor);\n\t\t\t}\n\t\t\t@Override\n\t\t\tpublic void mousePressed(MouseEvent e)\n\t\t\t{\n\t\t\t\tif(mode==1)\n\t\t\t\t\tjLabel.setIcon(MyTools.getIcon(fileName+\"_3.\"+extension));\n\t\t\t\telse \n\t\t\t\t\tjLabel.setBorder(javax.swing.BorderFactory.createBevelBorder(\n\t\t\t\t\t\t\tjavax.swing.border.BevelBorder.LOWERED));\n\t\t\t}\n\t\t\t@Override\n\t\t\tpublic void mouseReleased(MouseEvent e)\n\t\t\t{\n\t\t\t\tif(mode==1)\n\t\t\t\t\tjLabel.setIcon(MyTools.getIcon(fileName+\"_2.\"+extension));\n\t\t\t\telse \n\t\t\t\t\tsetEtchedBorder(Color.red);\n\t\t\t}\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "src/client/common/MyTextPane.java",
    "content": "﻿package client.common;\n\nimport java.awt.Color;\nimport java.awt.Image;\nimport java.text.DateFormat;\nimport java.util.Date;\n\nimport javax.swing.ImageIcon;\nimport javax.swing.JTextPane;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.SimpleAttributeSet;\nimport javax.swing.text.StyleConstants;\nimport javax.swing.text.StyledDocument;\n\nimport com.MyTools;\n\npublic class MyTextPane\n{\n\tJTextPane textPane=null;\n\tStyledDocument  document=null;\n\t\n\tpublic MyTextPane(JTextPane textPane)\n\t{\n\t\tthis.textPane=textPane;\n\t\tdocument=this.textPane.getStyledDocument();\n\t}\n\tpublic void addText(String text,SimpleAttributeSet font)\n\t{\n\t\ttry\n\t\t{\n\t\t\tdocument.insertString(document.getLength(), text, font);\n\t\t\tStyleConstants.setIcon(getMyAttribute(), MyTools.getIcon(\"../img/QQ_64.png\"));\n\t\t}\n\t\tcatch (BadLocationException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\tpublic void addIcon(String imagePath,String friendName)\n\t{\n\t\ttry\n\t\t{\n\t\t\tString time= DateFormat.getTimeInstance().format(new Date());\n\t\t\tdocument.insertString(document.getLength(), friendName+\" \"+time+\"\\n\", MyTextPane.getTimeAttribute());\n\t\t\ttextPane.setCaretPosition(document.getLength());\n\t\t\ttextPane.insertIcon(MyTools.getIcon(imagePath));\n\t\t\tdocument.insertString(document.getLength(), \"\\n\", getFriendAttribute());\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t/**\n\t * 临时写的，以后改进\n\t * @param imagePath\n\t * @param friendName\n\t */\n\tpublic void addIcon(Image image,String friendName)\n\t{\n\t\ttry\n\t\t{\n\t\t\tString time= DateFormat.getTimeInstance().format(new Date());\n\t\t\tdocument.insertString(document.getLength(), friendName+\" \"+time+\"\\n\", MyTextPane.getTimeAttribute());\n\t\t\ttextPane.setCaretPosition(document.getLength());\n\t\t\ttextPane.insertIcon(new ImageIcon(image));\n\t\t\tdocument.insertString(document.getLength(), \"\\n\", getFriendAttribute());\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t/**\n\t * 获取某种字体\n\t * @param name 字体名称\n\t * @param size 字体大小\n\t * @param color 字体颜色\n\t * @param bold 是否加粗\n\t * @param underline 是否加下划线\n\t * @return 返回获取的字体\n\t */\n\tpublic static SimpleAttributeSet getFontAttribute(String name, int size, Color color,\n\t\t\tboolean bold, boolean underline)\n\t{\n\t\tSimpleAttributeSet attribute = new SimpleAttributeSet();\n\t\tStyleConstants.setFontFamily(attribute, name);\n\t\tStyleConstants.setFontSize(attribute, size);\n\t\tStyleConstants.setForeground(attribute, color);\n\t\tStyleConstants.setBold(attribute, bold);\n\t\tStyleConstants.setUnderline(attribute, underline);\n\t\treturn attribute;\n\t}\n\tpublic static SimpleAttributeSet getMyAttribute()\n\t{\n\t\treturn getFontAttribute(\"楷体\", 22, Color.red, false, true);\n\t}\n\tpublic static SimpleAttributeSet getFriendAttribute()\n\t{\n\t\treturn getFontAttribute(\"黑体\", 16, Color.blue, false, false);\n\t}\n\tpublic static SimpleAttributeSet getTimeAttribute()\n\t{\n\t\treturn getFontAttribute(\"黑体\", 14, Color.DARK_GRAY, false, false);\n\t}\n}\n"
  },
  {
    "path": "src/client/common/MyTreeIcon.java",
    "content": "﻿package client.common;\n\nimport java.awt.Component;\nimport java.awt.Image;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\n\nimport javax.imageio.ImageIO;\nimport javax.swing.GrayFilter;\nimport javax.swing.ImageIcon;\nimport javax.swing.JTree;\nimport javax.swing.tree.DefaultTreeCellRenderer;\n\nimport client.control.Main;\n\nimport com.MyTools;\n\npublic class MyTreeIcon extends DefaultTreeCellRenderer \n{\n\t//如果是：用户名;图片路径，那么就是好友节点\n\t//如果是：用户名;图片路径1;图片路径2,那么表示分组节点，\n\t//图片路径1表示未展开的分组，图片路径2表示展开了的分组\n\tArrayList<String> nodeImages=null;\n    public MyTreeIcon(ArrayList<String> nodeImages)\n    {\n    \tthis.nodeImages=nodeImages;\n    }\n\n    public Component getTreeCellRendererComponent(\n                        JTree tree,\n                        Object value,\n                        boolean sel,\n                        boolean expanded,\n                        boolean leaf,\n                        int row,\n                        boolean hasFocus) \n    {\n        super.getTreeCellRendererComponent(tree, value, sel,expanded,\n        \t\tleaf, row, hasFocus);\n        for(String str:nodeImages)\n        {\n        \tString[] temp=str.split(MyTools.SPLIT1);\n        \tif(value.toString().startsWith(temp[0])&&!temp[0].equals(\"\"))//注意Value一定要toString()\n        \t{\n        \t\t try\n\t\t\t\t{\n\t\t\t\t\t//Image grayImage = GrayFilter.createDisabledImage(ImageIO.read(Main.class.getResource(temp[1])));\n\t\t\t\t\tif(temp.length==2)//如果是：用户名;图片路径，那么就是好友节点\n\t        \t\t\t//this.setIcon(new ImageIcon(grayImage));\n\t\t\t\t\t\tthis.setIcon(MyTools.getIcon(temp[1]));\n\t        \t\telse if(temp.length==3)//如果是：用户名;图片路径1;图片路径2,那么表示分组节点，\n\t        \t\t{\n\t        \t\t\tif(!expanded)\n\t        \t\t\t\tthis.setIcon(MyTools.getIcon(temp[1]));\n\t        \t\t\telse \n\t        \t\t\t\tthis.setIcon(MyTools.getIcon(temp[2]));\n\t        \t\t}\n\t\t\t\t}\n\t\t\t\tcatch (Exception e)\n\t\t\t\t{\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n        \t\t\n        \t}\n        }\n        return this;\n    }\n}\n\n"
  },
  {
    "path": "src/client/control/Chat.java",
    "content": "﻿package client.control;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Toolkit;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.KeyListener;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.net.DatagramPacket;\nimport java.net.DatagramSocket;\nimport java.net.InetAddress;\nimport java.net.ServerSocket;\nimport java.net.Socket;\nimport java.net.SocketException;\nimport java.net.UnknownHostException;\nimport java.text.DateFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.Calendar;\nimport java.util.Date;\nimport javax.imageio.ImageIO;\nimport javax.swing.ImageIcon;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JOptionPane;\nimport javax.swing.filechooser.FileFilter;\nimport javax.swing.text.AttributeSet;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.SimpleAttributeSet;\nimport javax.swing.text.StyleConstants;\nimport javax.swing.text.StyledDocument;\n\nimport com.MyTools;\nimport com.MyTools.Flag;\nimport com.socket.TCP;\nimport com.socket.UDP;\n\nimport client.common.MyLabel;\nimport client.common.MyTextPane;\nimport client.control.Main;\nimport client.frame.ChatFrame;\nimport client.frame.FaceFrame;\nimport client.frame.ScreenFram;\nimport client.frame.SendFileFrame;\nimport client.socket.CC_TCP;\nimport client.socket.CS_TCP;\nimport client.socket.S_TCP;\nimport client.socket.UDPChat;\n\n/**\n * @author LXA 聊天的窗体，继承自ChatFrame\n */\npublic class Chat extends ChatFrame\n{\n\t\n\tpublic String friendIP = null;// 好友的IP地址\n\tpublic int friendTCPPort=0;//好友的TCP端口\n\tpublic String friendName=\"\";//好友的名字\n\tpublic String myName=\"\";//自己的名字\n\tpublic CC_TCP cc_TCP=null;//发起聊天的TCP\n\tpublic TCP tcp=null;//接收聊天的TCP\n\t\n\tpublic UDPChat chatUDP=null;\n\tint width = 680;// 窗体宽度\n\tint height = 600;// 窗体高度\n\tprivate StyledDocument receiveDocument = null;// 用来存放接收框的文本或图片\n\tprivate StyledDocument sendDocument = null;// 用来存放发送框的文本或图片\n\t\n\t\n\tpublic ServerSocket getFileServer=null;\n\tpublic int myGetFilePort=10000;\n\tpublic int friendGetFilePort=0;\n\t\n\t\n\tpublic CS_TCP cs_TCP=null;//用来当对方不在线时给服务器发送离线消息\n\t\n\tpublic String ImgPath = \"\";\n\tString screenCutImgName = \"\";\n\n\tpublic int faceIdx=-1;//表情的索引\n\t/**\n\t * 通过UDP构造聊天窗体\n\t */\n\t/*public Chat(String friendIP,String friendName,String myName)\n\t{\n\t\tchatUDP=new UDPChat(friendIP,this);//实例化一个已经封装好的ChatUDP类\n\t\tinit();\n\t}*/\n\t/**\n\t * 通过TCP主动发起聊天\n\t * @param friendIP\n\t * @param friendTCPPort\n\t * @param friendName\n\t * @param myName\n\t */\n\tpublic Chat(String friendIP,int friendTCPPort,String friendName,String myName)\n\t{\n\t\tthis.friendIP=friendIP;\n\t\tthis.friendTCPPort=friendTCPPort;\n\t\tthis.friendName=friendName;\n\t\tthis.myName=myName;\n\t\ttry\n\t\t{\n\t\t\tcc_TCP=new CC_TCP(this.friendIP, this.friendTCPPort,this);\n\t\t\tcc_TCP.sendMessage(Flag.START_CHAT+MyTools.FLAGEND+myName);//发起聊天请求\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\tinit();\n\t\tinitGetFileServer();//初始化接收文件的服务\n\t}\n\t/**\n\t * 通过TCP被动接受聊天\n\t * @param tcp\n\t * @param friendName\n\t * @param myName\n\t */\n\tpublic Chat(TCP tcp,String friendName,String myName)\n\t{\n\t\tthis.tcp=tcp;\n\t\tthis.friendName=friendName;\n\t\tthis.myName=myName;\n\t\tinit();\n\t\tinitGetFileServer();//初始化接收文件的服务\n\t}\n\t\n\t/**\n\t * 发送离线消息时的构造方法\n\t * @param cs_TCP\n\t * @param friendName\n\t */\n\tpublic Chat(CS_TCP cs_TCP,String friendName)\n\t{\n\t\tthis.cs_TCP=cs_TCP;\n\t\tthis.friendName=friendName;\n\t\tinit();\n\t\tsetTitle(\"给\"+friendName+\"发送离线消息中……\");\n\t}\n\t\n\tpublic void init()\n\t{\n\t\tthis.setMinimumSize(new Dimension(width, height));// 设置窗体的最小大小\n\t\tif(cc_TCP!=null)//如果是发起方则直接设置标题，接收方因为对方IP还未知，所以这里还不能设置\n\t\t\tsetTitle(\"与\" + friendName+\"(\"+friendIP+\":\"+friendTCPPort+\")聊天中\");// 设置窗体标题\n\t\tinitLabelEvent();// 初始化窗体上所有Label的鼠标移动事件\n\t\tMyTools.setWindowsMiddleShow(this,width,height);//设置窗体居中显示\n\t\tjButton发送.setMnemonic(KeyEvent.VK_ENTER);// 设置发送按钮的快捷键为Alt+Enter\n\t\t\n\t\treceiveDocument = jTextPane接收框.getStyledDocument();\n\t\tsendDocument = jTextPane发送框.getStyledDocument();\n\t\tjTextPane接收框.insertIcon(MyTools.getIcon(\"../img/warning.png\"));\n\t\tString warning=\"交谈中请勿轻信汇款、中奖信息、陌生电话，勿使用外挂软件。\\n\";\n\t\ttry\n\t\t{\n\t\t\tSimpleAttributeSet warn=MyTextPane.getFontAttribute(\"黑体\", 12, Color.blue, false, false);\n\t\t\treceiveDocument.insertString(receiveDocument.getLength(), warning, warn);\n\t\t\t// 设置窗体的顶部图标\n\t\t\tthis.setIconImage(ImageIO.read(Main.class.getResource(\"../img/QQ_64.png\")));\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t\n\t/**\n\t * 初始化接收文件的服务\n\t */\n\tpublic void initGetFileServer()\n\t{\n\t\twhile (true)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tgetFileServer = new ServerSocket(myGetFilePort);\n\t\t\t\tSystem.out.println(\"已开启文件接收监听！\");\n\t\t\t\tif(cc_TCP!=null)\n\t\t\t\t\tcc_TCP.sendMessage(Flag.SENDFILE+MyTools.FLAGEND+myGetFilePort);\n\t\t\t\telse\n\t\t\t\t\ttcp.sendMessage(Flag.SENDFILE+MyTools.FLAGEND+myGetFilePort);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcatch (Exception e)\n\t\t\t{\n\t\t\t\tmyGetFilePort++;\n\t\t\t}\n\t\t}\n\t\tRunnable runnable=new Runnable()\n\t\t{\n\t\t\t\n\t\t\t@Override\n\t\t\tpublic void run()\n\t\t\t{\n\t\t\t\t//tcp.sendMessage(Flag.GETFILE_OK+MyTools.FLAGEND+TCP.getLocalHostIP()+MyTools.SPLIT1+myPort);\n\t\t\t\tRecieveThread recieveThread;\n\t\t\t\twhile (true)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tSocket socket = getFileServer.accept();\n\t\t\t\t\t\tSystem.out.println(\"与文件发送方连接成功！\");\n\t\t\t\t\t\trecieveThread = new RecieveThread(new SendFileFrame(), socket);\n\t\t\t\t\t\trecieveThread.start();\n\t\t\t\t\t}\n\t\t\t\t\tcatch (IOException e)\n\t\t\t\t\t{\n\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tnew Thread(runnable).start();\n\t}\n\t\n\t/**\n\t * 初始化窗体上所有Label的鼠标移动事件\n\t */\n\tpublic void initLabelEvent()\n\t{\n\t\tnew MyLabel(jLabel字体).addEvent();\n\t\tnew MyLabel(jLabel表情).addEvent();\n\t\tnew MyLabel(jLabel音乐).addEvent();\n\t\tnew MyLabel(jLabel图片).addEvent();\n\t\tnew MyLabel(jLabel截图).addEvent();\n\t\tnew MyLabel(jLabel聊天记录).addEvent();\n\t\tnew MyLabel(jLabel视频).addEvent();\n\t\tnew MyLabel(jLabel语音).addEvent();\n\t\tnew MyLabel(jLabel发送文件).addEvent();\n\t\tnew MyLabel(jLabelQQ空间).addEvent();\n\t\tnew MyLabel(jLabel我的好友).addEvent();\n\t\tnew MyLabel(jLabel加好友).addEvent();\n\t}\n\n\t/*\n\t * 给好友发送消息\n\t */\n\t@Override\n\tpublic void sendMessage()\n\t{\n\t\t//发送的是文本信息\n\t\tif (\"\".equals(ImgPath) && \"\".equals(screenCutImgName))\n\t\t{\n\t\t\tif(faceIdx<0)\n\t\t\t{\n        \t\tif(cc_TCP!=null)//如果是发起聊天的一方\n        \t\t\tcc_TCP.sendMessage(Flag.MESSAGE+MyTools.FLAGEND+jTextPane发送框.getText());\n        \t\telse if(tcp!=null)//如果是接收聊天的一方\n        \t\t\ttcp.sendMessage(Flag.MESSAGE+MyTools.FLAGEND+jTextPane发送框.getText());\n        \t\telse if(cs_TCP!=null)//发送未读消息\n        \t\t\tcs_TCP.sendMessage(Flag.UNDERLINE_MESSAGE+MyTools.FLAGEND+friendName+MyTools.SPLIT1+jTextPane发送框.getText());\n        \t\tsetReceivePaneText(true,jTextPane发送框.getText());//将用户发送的消息显示在聊天框中\n        \t\tjTextPane发送框.setText(\"\");// 清空发送框\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(cc_TCP!=null)//如果是发起聊天的一方\n\t    \t\t\tcc_TCP.sendMessage(Flag.FACE+MyTools.FLAGEND+faceIdx);\n\t    \t\telse if(tcp!=null)//如果是接收聊天的一方\n\t    \t\t\ttcp.sendMessage(Flag.FACE+MyTools.FLAGEND+faceIdx);\n\t\t\t\tnew MyTextPane(jTextPane接收框).addIcon(MyTools.getFaceByIdx(faceIdx), myName);\n\t\t\t\tjTextPane发送框.setText(\"\");// 清空发送框\n\t\t\t\tfaceIdx=-1;//图片表情发完后置为默认\n\t\t\t}\n    \t\t\n\t\t}\n\t\t//发送的是图片\n\t\telse  if(!\"\".equals(ImgPath))\n\t\t{\n\t\t\ttry\n\t\t\t{   \n\t\t\t\t//置空发送框\n\t\t\t\tjTextPane发送框.setText(\"\");\n\t\t\t\t//接收框显示图片\n\t\t\t\tjTextPane接收框.insertIcon(new ImageIcon(ImageIO\n\t\t\t\t\t\t.read(new FileInputStream(ImgPath))));\n\t\t\t\t//发送图片给对方\n\t\t\t\tcc_TCP.sendImg(ImgPath);\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t//发送完图片后置空图片路径\n\t\t\t\tImgPath =\"\";\n\t\t\t}\n\t\t\tcatch (FileNotFoundException e)\n\t\t\t{\n\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\tcatch (IOException e)\n\t\t\t{\n\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t\telse if(!\"\".equals(screenCutImgName))\n\t\t{\n\t\t\ttry\n\t\t\t{    //置空发送框\n\t\t\t\tjTextPane发送框.setText(\"\");\n\t\t\t\t//接收框显示图片\n\t\t\t\tjTextPane接收框.insertIcon(new ImageIcon(ImageIO\n\t\t\t\t\t\t.read(new FileInputStream(\"./screenCut/snap.jpg\"))));\n\t\t\t\t//发送图片给对方\n\t\t\t\tcc_TCP.sendImg(\"./screenCut/snap.jpg\");\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t//发送完图片后置空图片路径\n\t\t\t\tscreenCutImgName =\"\";\n\t\t\t}\n\t\t\tcatch (FileNotFoundException e)\n\t\t\t{\n\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\tcatch (IOException e)\n\t\t\t{\n\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t\t\n\t}\n\n\t/**\n\t * 设置发送框文本\n\t * \n\t * @param text\n\t *            需要设置的文本\n\t */\n\tpublic void setSendPaneText(String text)\n\t{\n\t\ttry\n\t\t{\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\t/**\n\t * 设置接收框的文本\n\t * \n\t * @param text\n\t *            需要设置的文本\n\t */\n\tpublic void setReceivePaneText(boolean isFromMyself, String text)\n\t{\n\t\tif (isFromMyself)\n\t\t{\n\t\t\tString time= DateFormat.getTimeInstance().format(new Date());\n\t\t\tnew MyTextPane(jTextPane接收框).addText(myName+\" \"+time+ \"\\n\",MyTextPane.getTimeAttribute());\n\t\t\tnew MyTextPane(jTextPane接收框).addText(text+ \"\\n\",MyTextPane.getMyAttribute());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tString time= DateFormat.getTimeInstance().format(new Date());\n\t\t\tnew MyTextPane(jTextPane接收框).addText(friendName+\" \"+time+ \"\\n\",MyTextPane.getTimeAttribute());\n\t\t\tnew MyTextPane(jTextPane接收框).addText(text+ \"\\n\",MyTextPane.getFriendAttribute());\n\t\t}\n\t}\n\t/**\n\t * 发送文件\n\t */\n\tpublic void sendFile()\n\t{\n\t\tSystem.out.println(\"对方已开启文件接收监听！\");\n\t\tSendFileFrame sendFileFrame=new SendFileFrame();\n\t\tsendFileFrame.lblProgress.setText(\"正在等待文件被接收....\");\n\t\tString filePath = sendFileFrame.showDialog(JFileChooser.FILES_ONLY);\n\t\tsendFileFrame.setVisible(true);\n\t\tSendTread sendThread;\n\t\t//sendThread = new SendTread(sendFileFrame, filePath,message.split(MyTools.SPLIT1)[0],Integer.parseInt(message.split(MyTools.SPLIT1)[1]));\n\t\tsendThread = new SendTread(sendFileFrame, filePath,friendIP,friendGetFilePort);\n\t\tsendThread.start();\n\t}\n\t/* \n\t * 发生在窗体关闭之前\n\t */\n\tpublic void beforeClose()\n\t{\n\t\t\n\t}\n\tpublic void selectFace()\n\t{\n\t\tnew FaceFrame(this);\n\t}\n\t/*\n\t * 发送图片\n\t */\n\tpublic void sendImg()\n\t{\n\t\tJFileChooser chooser = new JFileChooser();\n\n\t\t// 添加过滤器\n\t\tchooser.addChoosableFileFilter(new FileFilter()\n\t\t{\n\n\t\t\t@Override\n\t\t\tpublic String getDescription()\n\t\t\t{\n\t\t\t\t// TODO Auto-generated method stub\n\t\t\t\treturn \".jpg/.png/.bmp\";\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic boolean accept(File file)\n\t\t\t{\n\t\t\t\t// 获取文件名\n\t\t\t\tString fileName = file.getName();\n\t\t\t\tif (file.isDirectory())\n\t\t\t\t\treturn true;\n\n\t\t\t\t// 过滤文件名\n\t\t\t\tif (fileName.endsWith(\".jpg\") || fileName.endsWith(\".png\")\n\t\t\t\t\t\t|| fileName.endsWith(\".bmp\"))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\n\t\tint result = chooser.showOpenDialog(null);\n\n\t\t// 选择打开时\n\t\tif (result == JFileChooser.APPROVE_OPTION)\n\t\t{\n\t\t\tString filePath = chooser.getSelectedFile().getAbsolutePath();\n\t\t\t// 给图片添加；路径\n\t\t\tImgPath = filePath;\n\t\t\ttry\n\t\t\t{\n\n\t\t\t\tjTextPane发送框.insertIcon(new ImageIcon(ImageIO\n\t\t\t\t\t\t.read(new FileInputStream(filePath))));\n\t\t\t}\n\t\t\tcatch (FileNotFoundException e)\n\t\t\t{\n\t\t\t\tSystem.out.println(\"文件未找到\");\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\tcatch (IOException e)\n\t\t\t{\n\t\t\t\tSystem.out.println(\"io异常\");\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\n\t\t}\n\t\t// 选择关闭是\n\t\telse\n\t\t{\n\t\t\tdispose();\n\t\t}\n\n\t}\n\t\n\t\n\t/* \n\t * @截图\n\t */\n\t@Override\n\tpublic void screenFram()\n\t{\n\t\ttry\n\t\t{\n\t\t\tScreenFram.main();\n\t\t\tSystem.out.println(\"截图的名字是\"+screenCutImgName);\n\t\t\tjTextPane发送框.insertIcon(new ImageIcon(ImageIO\n\t\t\t\t\t.read(new FileInputStream(\"./screenCut/snap.jpg\"))));\n\t\t\tscreenCutImgName=\"snap\";\n\t\t}\n\t\tcatch (FileNotFoundException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t}\n\t\n}\n"
  },
  {
    "path": "src/client/control/Login.java",
    "content": "package client.control;\n\n\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\n\nimport javax.swing.JOptionPane;\nimport com.MyTools;\nimport com.MyTools.Flag;\n\nimport client.common.MyLabel;\nimport client.frame.LoginFrame;\nimport client.frame.RegisterFrame;\nimport client.socket.CS_TCP;\nimport com.sun.awt.AWTUtilities;//这个导入很重要，不导入报错，导入但又警告，所以不要理警告\n/**\n * @author LXA\n * 登录窗体，继承自LoginFrame\n */\npublic class Login extends LoginFrame\n{\n\t/**\n\t * \n\t */\n\tprivate static final long serialVersionUID = 5055331246882705423L;\n\tint width=350;\n\tint height=266;\n\tprivate Point lastPoint = null;//存放按下鼠标时的坐标点\n\tpublic CS_TCP cs_TCP=null;//声明一个客户端TCP\n\tpublic Main main; //声明一个主窗体\n\tpublic RegisterFrame registerFrame=null;\n\t/**\n\t * 程序的主入口\n\t * @param args\n\t */\n\tpublic static void main(String[] args)\n\t{\n\t\tMyTools.changeSkin();//更换皮肤\n\t\tnew Login();\n\t}\n\t\n\t\n\t/**\n\t * 登录窗体的构造方法\n\t */\n\tpublic Login()\n\t{\n\t\tinit();\n\t}\n\n\t/**\n\t * 初始化\n\t */\n\tpublic void init()\n\t{\n\t\tMyTools.setWindowsMiddleShow(this,width,height);//设置窗体居中显示\n\t\tnew MyLabel(lbl登录, \"../img/button/button_login\", \"png\").addEvent();\n\t\tnew MyLabel(lbl最小化, \"../img/button/login_minsize\", \"png\").addEvent();\n\t\tnew MyLabel(lbl退出, \"../img/button/login_exit\", \"png\").addEvent();\n\t\tnew MyLabel(lbl多账号, \"../img/button/login_duozhanghao\", \"png\").addEvent();\n\t\tnew MyLabel(lbl设置, \"../img/button/login_setting\", \"png\").addEvent();\n\t\tnew MyLabel(lbl注册账号).addEvent();\n\t\tinitUserStatus();\n\t\tAWTUtilities.setWindowOpaque(this, false);//设置窗体完全透明\n\t\taddEvent();\n\t\tthis.setVisible(true);\n\t\tmain=new Main();\n\t}\n\t/**\n\t * 初始化用户是否在线等状态\n\t */\n\tpublic void initUserStatus()\n\t{\n\t\tcomboBox状态.removeAllItems();\n\t\tcomboBox状态.addItem(MyTools.getIcon(\"../img/status/status_online_12.png\"));\n\t\tcomboBox状态.addItem(MyTools.getIcon(\"../img/status/status_qme_12.png\"));\n\t\tcomboBox状态.addItem(MyTools.getIcon(\"../img/status/status_leave_12.png\"));\n\t\tcomboBox状态.addItem(MyTools.getIcon(\"../img/status/status_busy_12.png\"));\n\t\tcomboBox状态.addItem(MyTools.getIcon(\"../img/status/status_invisible_12.png\"));\n\t}\n\t\n\n\t/**\n\t * 登录到服务器\n\t */\n\tpublic void login()\n\t{\n\t\tString name=textField用户名.getText();\n\t\tString password=new String(pwd密码.getPassword());\n\t\tif(name.equals(\"\")||password.equals(\"\"))\n\t\t\tJOptionPane.showMessageDialog(this, \"用户名和密码不能为空！\",\"错误\",JOptionPane.ERROR_MESSAGE);\n\t\telse \n\t\t{\n\t\t\ttry\n    \t\t{\n    \t\t\tif(cs_TCP==null)\n    \t\t\t\tcs_TCP=new CS_TCP(MyTools.QQServerIP, MyTools.QQServerPort,this,main);\n    \t\t\tSystem.out.println(\"开始检测用户名和密码……\");\n    \t\t\t\n    \t\t\tcs_TCP.sendMessage(Flag.LOGIN+MyTools.FLAGEND+name+MyTools.SPLIT1+password+MyTools.SPLIT1+main.getServerPort()+MyTools.SPLIT1+comboBox状态.getSelectedIndex());\n    \t\t}\n    \t\tcatch (Exception e)\n    \t\t{\n    \t\t\tJOptionPane.showMessageDialog(null, \"连接服务器失败！请检查网络连接或确保QQ服务器已启动！\");\n    \t\t}\n\t\t}\n\t}\n\t\n\t/**\n\t * 处理窗体的鼠标按下事件\n\t * @param e\n\t */\n\tpublic void mousePress(MouseEvent e)\n\t{\n\t\tlastPoint = e.getLocationOnScreen();\n\t}\n\t/**\n\t * 处理窗体的拖拽事件\n\t * @param e\n\t */\n\tpublic void mouseDrag(MouseEvent e)\n\t{\n\t\tPoint point = e.getLocationOnScreen();\n\t\tint offsetX = point.x - lastPoint.x;\n\t\tint offsetY = point.y - lastPoint.y;\n\t\tRectangle bounds = this.getBounds();\n\t\tbounds.x += offsetX;\n\t\tbounds.y += offsetY;\n\t\tthis.setBounds(bounds);\n\t\tlastPoint = point;\n\t}\n\t\n\t/**\n\t * 给窗体添加事件\n\t */\n\tpublic void addEvent()\n\t{\n\t\tlbl登录.addMouseListener(new MouseAdapter()\n\t\t{\n\t\t\t//登录按钮的单击事件\n\t\t\t@Override\n\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t{\n\t\t\t\tlogin();\n\t\t\t}\n\t\t});\n\t\tthis.addMouseListener(new MouseAdapter()\n\t\t{\n\t\t\t//窗体的鼠标按下事件\n\t\t\t@Override\n\t\t\tpublic void mousePressed(MouseEvent e)\n\t\t\t{\n\t\t\t\tmousePress(e);\n\t\t\t}\n\t\t});\n\t\tthis.addMouseMotionListener(new MouseAdapter()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void mouseDragged(MouseEvent e)\n\t\t\t{\n\t\t\t\tmouseDrag(e);\n\t\t\t};\n\t\t});\n\t\tlbl退出.addMouseListener(new MouseAdapter()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t{\n\t\t\t\tSystem.exit(0);\n\t\t\t}\n\t\t});\n\t\tlbl最小化.addMouseListener(new MouseAdapter()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t{\n\t\t\t\tJOptionPane.showMessageDialog(null, \"功能暂未实现！敬请期待！\", \"温馨提示\", JOptionPane.INFORMATION_MESSAGE);\n\t\t\t}\n\t\t});\n\t\tlbl多账号.addMouseListener(new MouseAdapter()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t{\n\t\t\t\tJOptionPane.showMessageDialog(null, \"功能暂未实现！敬请期待！\", \"温馨提示\", JOptionPane.INFORMATION_MESSAGE);\n\t\t\t}\n\t\t});\n\t\tlbl设置.addMouseListener(new MouseAdapter()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t{\n\t\t\t\tJOptionPane.showMessageDialog(null, \"功能暂未实现！敬请期待！\", \"温馨提示\", JOptionPane.INFORMATION_MESSAGE);\n\t\t\t}\n\t\t});\n\t\tlbl注册账号.addMouseListener(new MouseAdapter()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t{\n\t\t\t\tnew Register();\n\t\t\t}\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "src/client/control/Main.java",
    "content": "﻿package client.control;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\n\nimport javax.swing.JOptionPane;\nimport javax.swing.tree.DefaultMutableTreeNode;\n\nimport com.MyTools;\nimport com.MyTools.Flag;\nimport com.socket.TCPServer;\n\nimport client.common.*;\nimport client.control.MyTree;\nimport client.frame.MainFrame;\nimport client.socket.CC_TCP;\nimport client.socket.CS_TCP;\nimport client.socket.S_TCP;\n\npublic class Main extends MainFrame\n{\n\tpublic CS_TCP cs_TCP=null;\n\tpublic S_TCP s_TCP=null;\n\tprivate int serverPort=5000;//端口从5000开始分配\n\tfinal int width=350;//窗体宽度\n\tfinal int height=630;//窗体高度\n\tpublic QunChat qunChat;//群聊天室\n\tpublic Main() \n\t{     \n\t\tinit();\n\t}\n\t\n\tpublic Main(CS_TCP cs_TCP)\n\t{\n\t\tthis.cs_TCP=cs_TCP;\n\t\tinit();\n\t}\n\t\n\t/**\n\t * 初始化主窗体\n\t */\n\tpublic void init()\n\t{\n\t\tnew MyLabel(lbl设置,\"../img/button/QQ_settings\",\"png\").addEvent();//给最底下的设置按钮添加事件\n\t\tMyTools.setWindowsMiddleShow(this,width,height);//设置窗体居中显示\n\t\tinitUserStatus();//初始化用户是否在线等状态\n\t\ts_TCP=new S_TCP(serverPort,this);\n\t}\n\t\n\t/**\n\t * 当登录成功后，将登录窗体的CS_TCP传给主窗体\n\t * @param cs_TCP\n\t */\n\tpublic void setCS_TCP(CS_TCP cs_TCP)\n\t{\n\t\tthis.cs_TCP=cs_TCP;\n\t}\n\tpublic int getServerPort()\n\t{\n\t\treturn s_TCP.getServerPort();\n\t}\n\t/**\n\t * 初始化用户是否在线等状态\n\t */\n\tpublic void initUserStatus()\n\t{\n\t\tcomboBox状态.removeAllItems();\n\t\tcomboBox状态.addItem(MyTools.getIcon(\"../img/status/status_online.png\"));\n\t\tcomboBox状态.addItem(MyTools.getIcon(\"../img/status/status_qme.png\"));\n\t\tcomboBox状态.addItem(MyTools.getIcon(\"../img/status/status_leave.png\"));\n\t\tcomboBox状态.addItem(MyTools.getIcon(\"../img/status/status_busy.png\"));\n\t\tcomboBox状态.addItem(MyTools.getIcon(\"../img/status/status_invisible.png\"));\n\t}\n\t/**\n\t * 初始化好友列表\n\t */\n\tpublic void initjTree(String[] groupNames,ArrayList<String[]> friendNames)\n\t{\n\t\tnew MyTree(tree, groupNames, friendNames);\n\t}\n\n\t/* \n\t * 开始给对方好友聊天\n\t */\n\t@Override\n\tpublic void startChat(ActionEvent e)\n\t{\n\t\tif(tree.getSelectionPath().getPathCount()==3)\n\t\t{\n\t\t\tString str=tree.getSelectionPath().getLastPathComponent().toString();\n\t\t\tString friendName=str.substring(0,str.indexOf(\"(\"));\n\t\t\tString friendIP=str.substring(str.indexOf(\"(\")+1,str.indexOf(\":\"));\n\t\t\tint friendPort=Integer.parseInt(str.substring(str.indexOf(\":\")+1,str.indexOf(\")\")));\n\t\t\tif(!friendIP.equals(\"下线或隐身\"))\n\t\t\t{\t\n\t\t\t\tChat chat=new Chat(friendIP,friendPort,friendName,this.lbl用户名.getText());\n\t\t\t\tchat.setVisible(true);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tChat chat=new Chat(cs_TCP, friendName);\n\t\t\t\tchat.setVisible(true);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tJOptionPane.showMessageDialog(null, \"对不起，您未选中任何好友！\");\n\t\t}\n\t}\n\t/* \n\t * 请求获取好友资料\n\t */\n\t@Override\n\tpublic void getFriendInfo(ActionEvent e)\n\t{\n\t\tString str=tree.getSelectionPath().getLastPathComponent().toString();\n\t\tString userName=str.substring(0,str.indexOf(\"(\"));\n\t\tcs_TCP.sendMessage(Flag.GET_FRIEND_INFO+MyTools.FLAGEND+userName);\n\t}\n\t/**\n\t * 发送文件\n\t * @param e\n\t */\n\t@Override\n\tpublic void sendFile(ActionEvent e)\n\t{\n\t}\n\t/**\n\t * 删除好友\n\t * @param e\n\t */\n\tpublic void deleteFriend(ActionEvent e)\n\t{\n\t\tDefaultMutableTreeNode node=(DefaultMutableTreeNode)tree.getLastSelectedPathComponent();\n\t\tnode.removeFromParent();\n\t\tJOptionPane.showMessageDialog(null, \"删除好友成功！请关闭并打开当前分组以刷新好友列表！\");\n\t}\n\t/**\n\t * 进入聊天室\n\t */\n\t@Override\n\tpublic void gotoChatRoom()\n\t{\n\t\tqunChat=new QunChat(this);\n\t}\n\t/**\n\t * 新建聊天室\n\t */\n\t@Override\n\tpublic void buildNewChatRoom()\n\t{\n\t\tJOptionPane.showMessageDialog(null, \"新建聊天室属于会员专属功能，您还不是会员，是否想要加入会员，更多功能等你玩转，仅需10元每月哦！\",\"提示\",JOptionPane.YES_NO_CANCEL_OPTION);\n\t}\n}\n"
  },
  {
    "path": "src/client/control/MyTree.java",
    "content": "﻿package client.control;\n\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\n\nimport javax.swing.JTree;\nimport javax.swing.tree.DefaultMutableTreeNode;\nimport javax.swing.tree.DefaultTreeModel;\nimport javax.swing.tree.TreePath;\nimport javax.swing.tree.TreeSelectionModel;\n\nimport com.MyTools;\n\nimport client.common.MyTreeIcon;\n\npublic class MyTree\n{\n\tprivate JTree tree;//存放好友列表的树\n\tprivate DefaultTreeModel treeModel;//好友树的数据\n\tprivate String[] groupNames=null;//好友分组信息\n\tArrayList<String> nodeImages;//存放节点的头像，示例：张三;02_100.jpg\n\tprivate ArrayList<String[]> friendInfos=new ArrayList<String[]>();//每个分组的好友信息\n\tpublic MyTree(JTree tree,String[] groupNames,ArrayList<String[]> friendInfos)\n\t{\n\t\tthis.tree=tree;\n\t\tthis.groupNames=groupNames;\n\t\tthis.friendInfos=friendInfos;\n\t\tinit();//初始化\n\t\taddEvent();//添加事件\n\t}\n\tpublic MyTree(JTree tree)\n\t{\n\t\tthis.tree=tree;\n\t\ttreeModel=(DefaultTreeModel) tree.getModel();\n\t\t\n\t}\n\t/**\n\t * 初始化\n\t */\n\tpublic void init()\n\t{\t\n\t\ttree.setRootVisible(false);//设置根节点不可见\n        tree.setAutoscrolls(true);//设置自动滚动\n        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);//设置单选模式\n        \n        nodeImages=new ArrayList<String>();\n        nodeImages.add(\"所有在线用户\"+MyTools.SPLIT1+\"../img/face/f023.png\"+MyTools.SPLIT1+\"../img/face/f019.png\");\n        nodeImages.add(\"所有不在线用户\"+MyTools.SPLIT1+\"../img/face/f035.png\"+MyTools.SPLIT1+\"../img/face/f033.png\");\n        nodeImages.add(\"我的好友\"+MyTools.SPLIT1+\"../img/face/f051.png\"+MyTools.SPLIT1+\"../img/face/f049.png\");\n        DefaultMutableTreeNode root=new DefaultMutableTreeNode(\"root\");\n        treeModel=new DefaultTreeModel(root);//新建一个用于存放好友树的Model\n        for(int i=0;i<groupNames.length;i++)\n        {\n        \tDefaultMutableTreeNode node=new DefaultMutableTreeNode(groupNames[i]);\n        \n        \tfor(int j=0;j<friendInfos.get(i).length;j++)\n        \t{\n        \t\tString[] temp=friendInfos.get(i)[j].split(MyTools.SPLIT3);\n        \t\t//System.out.println(friendInfos.get(i)[j]);\n        \t\tString friendName=temp[0];//好友用户名\n        \t\tString ip=temp[1];//好友IP地址\n        \t\tString port=temp[2];//好友的端口号\n        \t\tString headImage=temp[3];//好友头像\n        \t\tString state=temp[4];//状态\n        \t\tnodeImages.add(friendName+MyTools.SPLIT1+\"../img/headImage/small/\"+headImage+\"_32.jpg\");\n        \t\tnode.add(new DefaultMutableTreeNode(friendName+\"(\"+ip+\":\"+port+\")\"));\n        \t}\n        \troot.add(node);\n        }\n        tree.setCellRenderer(new MyTreeIcon(nodeImages));\n        tree.setModel(treeModel);  \n\t}\n\t\n\t/**\n\t * 以最简单的方式设置树的节点的三种状态的图标，没什么用暂且当做示例代码留在这里\n\t */\n\tpublic void setNodeImage()\n\t{\n        /*DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();\n        renderer.setLeafIcon(GetIcon.getIcon(\"../img/f051.png\"));//设置叶子节点的图标\n        renderer.setClosedIcon(GetIcon.getIcon(\"../img/f021.png\"));//设置未展开的节点的图标\n        renderer.setOpenIcon(GetIcon.getIcon(\"../img/f019.png\"));//设置已展开的节点图标\n        tree.setCellRenderer(renderer);*/ \n\t}\n\t/**\n\t * 添加事件\n\t */\n\tpublic void addEvent()\n\t{\n\t\ttree.addMouseListener(new MouseAdapter()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t{\n\t\t\t\tint selRow = tree.getRowForLocation(e.getX(), e.getY());\n\t\t         TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());\n\t\t         if(selRow != -1) \n\t\t         {\n\t\t             /*if(e.getClickCount() == 1) {\n\t\t            \t JOptionPane.showMessageDialog(null, \"单击：\"+selRow+\",\"+selPath);\n\t\t             }\n\t\t             else if(e.getClickCount() == 2) {\n\t\t                // myDoubleClick(selRow, selPath);\n\t\t            \t JOptionPane.showMessageDialog(null, \"双击：\"+selRow+\",\"+selPath);\n\t\t             }*/\n\t\t        \t if(selPath.toString().split(\",\").length>2)//selPath的结果示例：“root,我的好友”\n\t\t        \t {\n\t\t        \t }\n\t\t        \t \n\t\t         }\n\t\t        // System.out.println(tree.getSelectionPath());\n\t\t         \n\t\t\t}\n\t\t\n\t\t});\n\t}\n\n\t/**\n\t * 添加新的好友分组到树\n\t * @param groupName 分组名字\n\t */\n\tpublic void addGroupToTree(String groupName)\n\t{\n\t\tDefaultMutableTreeNode childNode=new DefaultMutableTreeNode(groupName);\n\t\tDefaultMutableTreeNode parent=(DefaultMutableTreeNode) treeModel.getRoot();\n\t\ttreeModel.insertNodeInto(childNode, parent, parent.getChildCount());\n\t}\n\t/**\n\t * 添加新的好友到指定的分组\n\t * @param groupIndex 分组\n\t * @param friendName 要添加的好友的名字\n\t */\n\tpublic  void addFriendToTree(String groupName,String friendName)\n\t{\n\t\tint groupIndex=treeModel.getIndexOfChild((DefaultMutableTreeNode)treeModel.getRoot(), new DefaultMutableTreeNode(groupName));\n\t\tDefaultMutableTreeNode childNode=new DefaultMutableTreeNode(friendName);\n\t\tif(groupIndex!=-1)\n\t\t{\t\n\t\t\tDefaultMutableTreeNode parent=(DefaultMutableTreeNode) treeModel.getChild(treeModel.getRoot(), groupIndex);\n\t\t\ttreeModel.insertNodeInto(childNode, parent, parent.getChildCount());\n\t\t}\n\t\telse\n\t\t\tSystem.out.println(\"好友组“\"+groupName+\"”不存在！\");\n\t\t \t\n\t}\n\t/**\n\t * 删除树里面的某个好友\n\t */\n\tpublic void deleteFriend(String groupName,String friendName)\n\t{\n\t\tDefaultMutableTreeNode root=(DefaultMutableTreeNode) treeModel.getRoot();\n\t\tfor(int i=0;i<root.getChildCount();i++)\n\t\t{\n\t\t\tif(root.getChildAt(i).toString().startsWith(groupName))\n\t\t\t{\n\t\t\t\tfor(int j=0;j<root.getChildAt(i).getChildCount();j++)\n\t\t\t\t{\n\t\t\t\t\tif(root.getChildAt(i).getChildAt(j).toString().startsWith(friendName))\n\t\t\t\t\t{\n\t\t\t\t\t\tSystem.out.println(root.getChildAt(i).getChildAt(j));\n\t\t\t\t\t\tDefaultMutableTreeNode node=(DefaultMutableTreeNode)root.getChildAt(i).getChildAt(j);\n\t\t\t\t\t\tnode.removeFromParent();\n\t\t\t\t\t\tSystem.out.println(\"删除成功！\");\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\t/**\n\t * 打开某个好友分组\n\t * @param groupName\n\t */\n\tpublic void openGroup(String groupName)\n\t{\n\t\tDefaultMutableTreeNode childNode=new DefaultMutableTreeNode(groupName);\n\t\ttree.scrollPathToVisible(new TreePath(childNode.getPath()));//自动打开到当前节点\n\t}\n}\n"
  },
  {
    "path": "src/client/control/QunChat.java",
    "content": "﻿package client.control;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.text.DateFormat;\nimport java.util.Date;\n\nimport javax.swing.JTree;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.SimpleAttributeSet;\nimport javax.swing.text.StyledDocument;\nimport javax.swing.tree.TreeModel;\n\nimport com.MyTools;\nimport com.MyTools.Flag;\n\nimport client.common.MyTextPane;\nimport client.common.MyTreeIcon;\nimport client.frame.QunChatFrame;\nimport client.socket.CS_TCP;\n\npublic class QunChat extends QunChatFrame\n{\n\tCS_TCP cs_TCP=null;\n\tMain main=null;\n\t\n\tpublic QunChat(Main main)\n\t{\n\t\tthis.main=main;\n\t\tthis.tree.setModel(main.tree.getModel());\n\t\tthis.tree.setCellRenderer(main.tree.getCellRenderer());\n\t\tthis.cs_TCP=main.cs_TCP;\n\t\tMyTools.setWindowsMiddleShow(this);\n\t\tthis.setTitle(\"MyQQ官方聊天室(当前用户：\"+main.lbl用户名.getText()+\")\");\n\t\taddEvent();\n\t\tthis.setVisible(true);\n\t}\n\tpublic void addEvent()\n\t{\n\t\tbtn发送.addActionListener(new ActionListener()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void actionPerformed(ActionEvent e)\n\t\t\t{\n\t\t\t\tString nowTime= DateFormat.getTimeInstance().format(new Date());\n\t\t\t\tcs_TCP.sendMessage(Flag.QUN_CHAT+MyTools.FLAGEND+main.lbl用户名.getText()+MyTools.SPLIT1+nowTime+MyTools.SPLIT1+textPane发送.getText());\n\t\t\t\ttextPane发送.setText(\"\");\n\t\t\t}\n\t\t});\n\t\tbtn关闭.addActionListener(new ActionListener()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void actionPerformed(ActionEvent e)\n\t\t\t{\n\t\t\t\tdispose();//关闭聊天室\n\t\t\t}\n\t\t});\n\t}\n\tpublic void receiveMessage(String message)\n\t{\n\t\tString[] temp=message.split(MyTools.SPLIT1);\n\t\tif(temp[0].equals(main.lbl用户名.getText()))\n\t\t{\n\t\t\tnew MyTextPane(textPane接收框).addText(temp[0]+\" \"+temp[1]+\"\\n\", MyTextPane.getTimeAttribute());\n\t\t\tnew MyTextPane(textPane接收框).addText(temp[2]+\"\\n\", MyTextPane.getMyAttribute());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tnew MyTextPane(textPane接收框).addText(temp[0]+\" \"+temp[1]+\"\\n\", MyTextPane.getTimeAttribute());\n\t\t\tnew MyTextPane(textPane接收框).addText(temp[2]+\"\\n\", MyTextPane.getFriendAttribute());\n\t\t}\n\t}\n\tpublic void showPublicMessage(String message)\n\t{\n\t\ttextArea群公告.setText(message);\n\t}\n}\n"
  },
  {
    "path": "src/client/control/RecieveThread.java",
    "content": "package client.control;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.net.ServerSocket;\nimport java.net.Socket;\nimport java.net.UnknownHostException;\n\nimport javax.swing.JFileChooser;\nimport javax.swing.JOptionPane;\n\nimport client.frame.SendFileFrame;\n\n\npublic class RecieveThread extends Thread\n{\n\tprivate SendFileFrame fram;\n\tprivate Socket socket;\n\tprivate DataInputStream in;\n\tprivate DataOutputStream fileOut;\n\tprivate ServerSocket ss;\n\tprivate String serverPort;\n\n\tpublic RecieveThread(SendFileFrame fram, Socket socket)\n\t{\n\t\tthis.fram = fram;\n\t\tthis.socket = socket;\n\t\t\n\t}\n\n\t@Override\n\tpublic void run()\n\t{\n\t\tsuper.run();\n\t\trecieveFile();\n\t}\n\n\tpublic void recieveFile()\n\t{\n\t\ttry\n\t\t{\n\t\t\t// ss = new ServerSocket(Integer.parseInt(serverPort));\n\t\t\t// socket = ss.accept();\n\t\t\t// TODO 测试连接是否成功\n//\t\t\tJOptionPane.showMessageDialog(null, \"接收端已成功连接！\");\n\n\t\t\t// socket = new Socket(ConnInfor.SERVER_IP, ConnInfor.CONN_PORT);\n\t\t\tin = new DataInputStream(socket.getInputStream());\n\t\t\tString filePath = null;\n\t\t\t// 读取发过来的文件名和文件长度\n\t\t\tString fileName = in.readUTF();\n\t\t\tlong fileLen = in.readLong();\n\t\t\t// 弹出接收对话\n\t\t\tint result = JOptionPane.showConfirmDialog(null, \"是否接收文件？\" + fileName,\n\t\t\t\t\t\"提示\", JOptionPane.YES_NO_CANCEL_OPTION);\n\t\t\t// 选择对话框中的取消按钮的相应操作\n\t\t\tif (result == JOptionPane.CANCEL_OPTION)\n\t\t\t{\n\n\t\t\t}\n\t\t\t// 选择对话框中的否按钮的相应操\n\t\t\telse if (result == JOptionPane.NO_OPTION)\n\t\t\t{\n\t\t\t\tcloseRecieve();\n\t\t\t}\n\t\t\t// 选择对话框中的是按钮的相应操\n\t\t\telse if (result == JOptionPane.OK_OPTION)\n\t\t\t{\n\t\t\t\t\n\t\t\t\tfilePath = fram.showDialog(JFileChooser.DIRECTORIES_ONLY);\n\t\t\t\tfram.setVisible(true);\n\t\t\t\tfileOut = new DataOutputStream(new FileOutputStream(filePath\n\t\t\t\t\t\t+ \"/\"+fileName));\n\n\t\t\t\tbyte[] buff = new byte[1024];\n\n\t\t\t\tint len = 0;\n\n\t\t\t\tlong passLen = 0;\n\n\t\t\t\tlong startTime = System.currentTimeMillis();\n\t\t\t\tlong endTime = 0;\n\t\t\t\tlong passTime = 0;\n\n\t\t\t\twhile (true)\n\t\t\t\t{\n\t\t\t\t\tif (in != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tlen = in.read(buff);\n\t\t\t\t\t\tpassLen += len;\n\t\t\t\t\t}\n\t\t\t\t\tendTime = System.currentTimeMillis();\n\t\t\t\t\tpassTime = endTime - startTime;\n\t\t\t\t\tif (len == -1)\n\t\t\t\t\t{\n\t\t\t\t\t\tfram.updateProgressBar(fram.progressBar, fileLen,\n\t\t\t\t\t\t\t\tfileLen, fram.lblProgress, passTime);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tfram.updateProgressBar(fram.progressBar, passLen,\n\t\t\t\t\t\t\tfileLen, fram.lblProgress, passTime);\n\t\t\t\t\tfileOut.write(buff, 0, len);\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\t\tcatch (UnknownHostException e)\n\t\t{\n\t\t\t// TODO Auto-generated catch block\n\t\t\te.printStackTrace();\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\t// TODO Auto-generated catch block\n\t\t\te.printStackTrace();\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tcloseRecieve();\n\t\t}\n\t}\n\n\t/**\n\t * 关闭接收连接\n\t * \n\t */\n\tpublic void closeRecieve()\n\t{\n\n\t\ttry\n\t\t{\n\t\t\tif (fileOut != null)\n\t\t\t\tfileOut.close();\n\t\t\tif (in != null)\n\t\t\t{\n\t\t\t\tin.close();\n\t\t\t}\n\t\t\tif (socket != null)\n\t\t\t{\n\t\t\t\tsocket.close();\n\t\t\t}\n\t\t\tif (ss != null)\n\t\t\t{\n\t\t\t\tss.close();\n\t\t\t}\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\t// TODO Auto-generated catch block\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n}"
  },
  {
    "path": "src/client/control/Register.java",
    "content": "﻿package client.control;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\n\nimport javax.swing.ImageIcon;\nimport javax.swing.JOptionPane;\n\nimport com.MyTools;\nimport com.MyTools.Flag;\nimport client.frame.LoginFrame;\nimport client.frame.RegisterFrame;\nimport client.socket.CS_TCP;\n\nimport server.common.JDBC;\nimport server.dao.UserDao;\nimport server.entity.Users;\n\n/**\n * @author Administrator\n *注册最后得到的是一个user对象\n *user对象内容为用户名,密码,头像,生日,签名,E-mail.\n */\npublic class Register extends RegisterFrame\n{\n\t//UserDao ud = new UserDao();\n\t\n\tpublic CS_TCP cs_TCP;//客户端与服务器的TCP连接\n\t\n\tpublic Register()\n\t{\n\t\t\n\t\tMyTools.setWindowsMiddleShow(this);\n\t\tinitHeadImage();\n\t\taddEvent();\n\t\tsetVisible(true);\n\t\t\n\t}\n\t/**\n\t * 初始化头像\n\t */\n\tpublic void initHeadImage()\n\t{\n\t\tfor(int i=0;i<=15;i++)\n\t\t{\n\t\t\tcomboBoxHeadImage.addItem(MyTools.getIcon(\"../img/headImage/big/\"+i+\"_100.jpg\"));\n\t\t}\n\t}\n\tpublic void addEvent()\n\t{\n\t\tbtnRegister.addActionListener(new ActionListener()\n\t\t{\t\t\t\n\t\t\t@Override\n\t\t\tpublic void actionPerformed(ActionEvent e)\n\t\t\t{\n\t\t\t\tif(txtName.getText().equals(\"\"))\n\t\t\t\t\tJOptionPane.showMessageDialog(null, \"用户名不能为空！\",\"错误\",JOptionPane.ERROR_MESSAGE);\n\t\t\t\telse if(new String(pwd.getPassword()).equals(\"\"))\n\t\t\t\t\tJOptionPane.showMessageDialog(null, \"密码不能为空！\",\"错误\",JOptionPane.ERROR_MESSAGE);\n\t\t\t\telse if(!new String(pwd.getPassword()).equals(new String(pwdRe.getPassword())))\n\t\t\t\t\tJOptionPane.showMessageDialog(null, \"两次输入的密码不一致，请重新输入！\",\"错误\",JOptionPane.ERROR_MESSAGE);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttry\n    \t\t\t\t{\n    \t\t\t\t\tif(cs_TCP==null)\n    \t\t\t\t\t\tcs_TCP=new CS_TCP(MyTools.QQServerIP, MyTools.QQServerPort);\n    \t\t\t\t\tString sex=\"男\";\n    \t\t\t\t\tif(comGender.getSelectedIndex()==1)\n    \t\t\t\t\t\tsex=\"女\";\n    \t\t\t\t\tcs_TCP.sendMessage(Flag.REGISTER+MyTools.FLAGEND//注册标志\n    \t\t\t\t\t\t\t+txtName.getText()+MyTools.SPLIT1//用户名\n    \t\t\t\t\t\t\t+new String(pwd.getPassword())+MyTools.SPLIT1//密码\n    \t\t\t\t\t\t\t+sex+MyTools.SPLIT1//性别\n    \t\t\t\t\t\t\t+txtEmail.getText()+MyTools.SPLIT1//电子邮件\n    \t\t\t\t\t\t\t+txtbirthday.getText()+MyTools.SPLIT1//生日\n    \t\t\t\t\t\t\t+txtSignat.getText()+MyTools.SPLIT1//个性签名\n    \t\t\t\t\t\t\t+comboBoxHeadImage.getSelectedIndex());//头像索引\n    \t\t\t\t}\n    \t\t\t\tcatch (Exception ee)\n    \t\t\t\t{\n    \t\t\t\t\tJOptionPane.showMessageDialog(null, \"连接服务器失败！请检查您的网络连接或确保服务器已启动！\",\"错误\",JOptionPane.ERROR_MESSAGE);\n    \t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t * 在窗体关闭之前需要做的事\n\t */\n\t@Override\n\tpublic void beforeClose()\n\t{\n\t\tif(cs_TCP!=null)\n\t\t\tcs_TCP.closeSocket();\n\t}\n\t/**\n\t * 取消按钮事件\n\t */\n\t@Override\n\tpublic void cancle()\n\t{\n\t\tif(cs_TCP!=null)\n\t\t\tcs_TCP.closeSocket();\n\t\tthis.dispose();\n\t}\n\tpublic void actionPerformed(ActionEvent e) \n\t{\n\t\t// TODO Auto-generated method stub\n\t\t/*String btnStr = e.getActionCommand();\n\t\tif (\"注册\".equals(btnStr)) \n\t\t{\n\t\t\tif ((new String(registerFrame.pwd.getPassword()))\n\t\t\t\t\t.equals(new String(registerFrame.pwdRe.getPassword()))) {\n\t\t\t\tUsers user = new Users();\n\t\t\t\tString userCheck = registerFrame.txtName.getText();\n\t\t\t\tif (ud.queryByName(userCheck) != null) {\n\t\t\t\t\tJOptionPane.showMessageDialog(null, \"用户名已存在\");\n\t\t\t\t} else {\n\t\t\t\t\tud = new UserDao();\n\t\t\t\t\tuser.setName(registerFrame.txtName.getText());\n\t\t\t\t\tuser.setPwd(new String(registerFrame.pwd.getPassword()));\n\t\t\t\t\tuser.setGender(String.valueOf(registerFrame.comGender\n\t\t\t\t\t\t\t.getSelectedItem()));\n\t\t\t\t\tuser.setEmail(registerFrame.txtEmail.getText());\n\t\t\t\t\tuser.setState(\"离线\");\n\t\t\t\t\ttry {\n\t\t\t\t\t\tuser.setBirthday(java.sql.Date\n\t\t\t\t\t\t\t\t.valueOf(registerFrame.txtbirthday.getText()));\n\t\t\t\t\t\tuser.setSignature(registerFrame.txtSignat.getText());\n\t\t\t\t\t\tuser.setHeadImg(headImg);\n\t\t\t\t\t\tSystem.out.println(user.getName() + user.getEmail());\n\t\t\t\t\t\tud.add(user);//添加到了数据库\n\t\t\t\t\t} catch (Exception e2) {\n\t\t\t\t\t\t// TODO: handle exception\n\t\t\t\t\t\tJOptionPane.showMessageDialog(null, \"生日格式为1900-11-11,不能为空\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}*/\n\t}\n}\n"
  },
  {
    "path": "src/client/control/SendTread.java",
    "content": "﻿package client.control;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.net.ServerSocket;\nimport java.net.Socket;\n\nimport javax.swing.JOptionPane;\n\nimport client.frame.SendFileFrame;\n\n\npublic class SendTread extends Thread\n{\n\tprivate SendFileFrame fram;\n\tprivate String FilePath;\n\n\tprivate Socket socket;\n\n\tprivate DataInputStream fileIn;\n\tprivate DataOutputStream out;\n\tprivate String connIP;\n\tprivate int clientPort;\n\tpublic SendTread(SendFileFrame fram, String Filepath,String connIP,int clientPort)\n\t{\n\t\tthis.fram = fram;\n\t\tthis.FilePath = Filepath;\n\t\tthis.connIP = connIP;\n\t\tthis.clientPort = clientPort;\n\t}\n\n\t@Override\n\tpublic void run()\n\t{\n\t\tsuper.run();\n\t\tstartSend( FilePath);\n\t}\n\n\tpublic void startSend(String filepath)\n\t{\n\t\ttry\n\t\t{\n//\t\t\t ss = new ServerSocket(ConnInfor.CONN_PORT);\n//\t\t\t socket = ss.accept();\n\t\t\tsocket = new Socket(connIP, clientPort);\n//\t\t\tJOptionPane.showMessageDialog(null, \"发送端已成功建立连接！\");\n\t\t\tFile file = new File(filepath);\n\t\t\tout = new DataOutputStream(socket.getOutputStream());\n\t\t\tString fileName = file.getName();\n\t\t\tlong FileLen = file.length();\n\t\t\tout.writeUTF(fileName);\n\t\t\tout.flush();\n\t\t\tout.writeLong(FileLen);\n\t\t\tout.flush();\n\n\t\t\tfileIn = new DataInputStream(new FileInputStream(file));\n\t\t\tbyte[] buff = new byte[1024];\n\t\t\tint len = 0;\n\t\t\tlong passLen = 0;\n\t\t\tlong startTime = System.currentTimeMillis();\n\t\t\tlong endTime = 0;\n\t\t\tdouble passTime = 0;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tif (fileIn != null)\n\t\t\t\t{\n\t\t\t\t\tlen = fileIn.read(buff);\n\t\t\t\t\tpassLen += len;\n\t\t\t\t}\n\t\t\t\tendTime = System.currentTimeMillis();\n\t\t\t\tpassTime = endTime -startTime;\n\t\t\t\tif (len == -1)\n\t\t\t\t{\n\t\t\t\t\tfram.updateProgressBar(fram.progressBar, FileLen,\n\t\t\t\t\t\t\tFileLen, fram.lblProgress,passTime);\n\t\t\t\t\t//fram.afterSendFile() ;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tfram.updateProgressBar(fram.progressBar, passLen, FileLen,\n\t\t\t\t\t\tfram.lblProgress,passTime);\n\t\t\t\tout.write(buff, 0, len);\n\t\t\t}\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tcloseSend();\n\t\t}\n\t}\n\n\tpublic void closeSend()\n\t{\n\t\ttry\n\t\t{\n\t\t\tif (out != null)\n\t\t\t\tout.close();\n\t\t\tif (fileIn != null)\n\t\t\t\tfileIn.close();\n\t\t\tif (socket != null)\n\t\t\t\tsocket.close();\n\t\t\t\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "src/client/frame/ChatFrame.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.3\" maxVersion=\"1.5\" type=\"org.netbeans.modules.form.forminfo.JFrameFormInfo\">\n  <Properties>\n    <Property name=\"defaultCloseOperation\" type=\"int\" value=\"2\"/>\n    <Property name=\"title\" type=\"java.lang.String\" value=\"&#x804a;&#x5929;\"/>\n    <Property name=\"background\" type=\"java.awt.Color\" editor=\"org.netbeans.beaninfo.editors.ColorEditor\">\n      <Color blue=\"ff\" green=\"ff\" red=\"cc\" type=\"rgb\"/>\n    </Property>\n  </Properties>\n  <SyntheticProperties>\n    <SyntheticProperty name=\"formSizePolicy\" type=\"int\" value=\"1\"/>\n  </SyntheticProperties>\n  <Events>\n    <EventHandler event=\"windowClosing\" listener=\"java.awt.event.WindowListener\" parameters=\"java.awt.event.WindowEvent\" handler=\"formWindowClosing\"/>\n  </Events>\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n              <Component id=\"jPanel左侧面板\" max=\"32767\" attributes=\"0\"/>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jPanel右侧面板\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Component id=\"jPanel右侧面板\" alignment=\"0\" max=\"32767\" attributes=\"0\"/>\n          <Component id=\"jPanel左侧面板\" alignment=\"1\" max=\"32767\" attributes=\"0\"/>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Container class=\"javax.swing.JPanel\" name=\"jPanel&#x53f3;&#x4fa7;&#x9762;&#x677f;\">\n      <Properties>\n        <Property name=\"background\" type=\"java.awt.Color\" editor=\"org.netbeans.beaninfo.editors.ColorEditor\">\n          <Color blue=\"ff\" green=\"ff\" red=\"cc\" type=\"rgb\"/>\n        </Property>\n      </Properties>\n\n      <Layout>\n        <DimensionLayout dim=\"0\">\n          <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n              <Component id=\"jLabelQQ秀_对方\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jLabelQQ秀_自己\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n        </DimensionLayout>\n        <DimensionLayout dim=\"1\">\n          <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n              <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                  <Component id=\"jLabelQQ秀_对方\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <EmptySpace type=\"separate\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"jLabelQQ秀_自己\" min=\"-2\" pref=\"251\" max=\"-2\" attributes=\"0\"/>\n                  <EmptySpace max=\"32767\" attributes=\"0\"/>\n              </Group>\n          </Group>\n        </DimensionLayout>\n      </Layout>\n      <SubComponents>\n        <Component class=\"javax.swing.JLabel\" name=\"jLabelQQ&#x79c0;_&#x5bf9;&#x65b9;\">\n          <Properties>\n            <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n              <Image iconType=\"3\" name=\"/client/img/qqshow/qqshow_girl_02_180.jpg\"/>\n            </Property>\n          </Properties>\n          <AuxValues>\n            <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n          </AuxValues>\n        </Component>\n        <Component class=\"javax.swing.JLabel\" name=\"jLabelQQ&#x79c0;_&#x81ea;&#x5df1;\">\n          <Properties>\n            <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n              <Image iconType=\"3\" name=\"/client/img/qqshow/qqshow_boy_01.jpg\"/>\n            </Property>\n          </Properties>\n        </Component>\n      </SubComponents>\n    </Container>\n    <Container class=\"javax.swing.JPanel\" name=\"jPanel&#x5de6;&#x4fa7;&#x9762;&#x677f;\">\n      <Properties>\n        <Property name=\"background\" type=\"java.awt.Color\" editor=\"org.netbeans.beaninfo.editors.ColorEditor\">\n          <Color blue=\"ff\" green=\"ff\" red=\"cc\" type=\"rgb\"/>\n        </Property>\n      </Properties>\n\n      <Layout>\n        <DimensionLayout dim=\"0\">\n          <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n              <Component id=\"jPanel顶部面板\" alignment=\"0\" max=\"32767\" attributes=\"0\"/>\n              <Component id=\"jPanel发送面板\" alignment=\"0\" max=\"32767\" attributes=\"0\"/>\n              <Component id=\"jPanel聊天面板\" alignment=\"0\" pref=\"486\" max=\"32767\" attributes=\"0\"/>\n          </Group>\n        </DimensionLayout>\n        <DimensionLayout dim=\"1\">\n          <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n              <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                  <Component id=\"jPanel顶部面板\" min=\"-2\" pref=\"89\" max=\"-2\" attributes=\"0\"/>\n                  <EmptySpace max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"jPanel聊天面板\" pref=\"260\" max=\"32767\" attributes=\"0\"/>\n                  <EmptySpace max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"jPanel发送面板\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n          </Group>\n        </DimensionLayout>\n      </Layout>\n      <SubComponents>\n        <Container class=\"javax.swing.JPanel\" name=\"jPanel&#x9876;&#x90e8;&#x9762;&#x677f;\">\n          <Properties>\n            <Property name=\"background\" type=\"java.awt.Color\" editor=\"org.netbeans.beaninfo.editors.ColorEditor\">\n              <Color blue=\"ff\" green=\"cc\" red=\"33\" type=\"rgb\"/>\n            </Property>\n          </Properties>\n\n          <Layout>\n            <DimensionLayout dim=\"0\">\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"jLabel头像\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace type=\"unrelated\" max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"jLabel视频\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"jLabel语音\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"jLabel发送文件\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace type=\"unrelated\" max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"jLabelQQ空间\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace min=\"-2\" pref=\"13\" max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"jLabel我的好友\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace pref=\"23\" max=\"32767\" attributes=\"0\"/>\n                      <Component id=\"jLabel加好友\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                  </Group>\n              </Group>\n            </DimensionLayout>\n            <DimensionLayout dim=\"1\">\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                      <Group type=\"103\" groupAlignment=\"1\" attributes=\"0\">\n                          <Component id=\"jLabel头像\" alignment=\"1\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <Group type=\"103\" alignment=\"1\" groupAlignment=\"0\" attributes=\"0\">\n                              <Component id=\"jLabel视频\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jLabel语音\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jLabel发送文件\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jLabelQQ空间\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jLabel我的好友\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jLabel加好友\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          </Group>\n                      </Group>\n                      <EmptySpace max=\"32767\" attributes=\"0\"/>\n                  </Group>\n              </Group>\n            </DimensionLayout>\n          </Layout>\n          <SubComponents>\n            <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x5934;&#x50cf;\">\n              <Properties>\n                <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                  <Image iconType=\"3\" name=\"/client/img/QQ_64.png\"/>\n                </Property>\n              </Properties>\n            </Component>\n            <Component class=\"javax.swing.JLabel\" name=\"jLabelQQ&#x7a7a;&#x95f4;\">\n              <Properties>\n                <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                  <Image iconType=\"3\" name=\"/client/img/chat/fun_qzone_54.png\"/>\n                </Property>\n              </Properties>\n              <AuxValues>\n                <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n              </AuxValues>\n            </Component>\n            <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x6211;&#x7684;&#x597d;&#x53cb;\">\n              <Properties>\n                <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                  <Image iconType=\"3\" name=\"/client/img/chat/fun_myfeeds_54.png\"/>\n                </Property>\n              </Properties>\n              <AuxValues>\n                <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n              </AuxValues>\n            </Component>\n            <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x89c6;&#x9891;\">\n              <Properties>\n                <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                  <Image iconType=\"3\" name=\"/client/img/chat/fun_video_54.png\"/>\n                </Property>\n                <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"&#x5f00;&#x59cb;&#x89c6;&#x9891;\"/>\n              </Properties>\n              <AuxValues>\n                <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n              </AuxValues>\n            </Component>\n            <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x8bed;&#x97f3;\">\n              <Properties>\n                <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                  <Image iconType=\"3\" name=\"/client/img/chat/fun_voice_54.png\"/>\n                </Property>\n                <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"&#x5f00;&#x59cb;&#x8bed;&#x97f3;\"/>\n              </Properties>\n              <AuxValues>\n                <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n              </AuxValues>\n            </Component>\n            <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x53d1;&#x9001;&#x6587;&#x4ef6;\">\n              <Properties>\n                <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                  <Image iconType=\"3\" name=\"/client/img/chat/fun_sendfile_54.png\"/>\n                </Property>\n                <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"&#x53d1;&#x9001;&#x6587;&#x4ef6;\"/>\n              </Properties>\n              <Events>\n                <EventHandler event=\"mouseClicked\" listener=\"java.awt.event.MouseListener\" parameters=\"java.awt.event.MouseEvent\" handler=\"jLabel&#x53d1;&#x9001;&#x6587;&#x4ef6;MouseClicked\"/>\n              </Events>\n              <AuxValues>\n                <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n              </AuxValues>\n            </Component>\n            <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x52a0;&#x597d;&#x53cb;\">\n              <Properties>\n                <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                  <Image iconType=\"3\" name=\"/client/img/chat/fun_add_54.png\"/>\n                </Property>\n              </Properties>\n              <AuxValues>\n                <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n              </AuxValues>\n            </Component>\n          </SubComponents>\n        </Container>\n        <Container class=\"javax.swing.JPanel\" name=\"jPanel&#x804a;&#x5929;&#x9762;&#x677f;\">\n\n          <Layout class=\"org.netbeans.modules.form.compat2.layouts.DesignBorderLayout\"/>\n          <SubComponents>\n            <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane1\">\n              <AuxValues>\n                <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n              </AuxValues>\n              <Constraints>\n                <Constraint layoutClass=\"org.netbeans.modules.form.compat2.layouts.DesignBorderLayout\" value=\"org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription\">\n                  <BorderConstraints direction=\"Center\"/>\n                </Constraint>\n              </Constraints>\n\n              <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n              <SubComponents>\n                <Component class=\"javax.swing.JTextPane\" name=\"jTextPane&#x63a5;&#x6536;&#x6846;\">\n                  <Properties>\n                    <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n                  </Properties>\n                  <AuxValues>\n                    <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n                  </AuxValues>\n                </Component>\n              </SubComponents>\n            </Container>\n          </SubComponents>\n        </Container>\n        <Container class=\"javax.swing.JPanel\" name=\"jPanel&#x53d1;&#x9001;&#x9762;&#x677f;\">\n          <Properties>\n            <Property name=\"background\" type=\"java.awt.Color\" editor=\"org.netbeans.beaninfo.editors.ColorEditor\">\n              <Color blue=\"ff\" green=\"ff\" red=\"cc\" type=\"rgb\"/>\n            </Property>\n          </Properties>\n\n          <Layout>\n            <DimensionLayout dim=\"0\">\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"jPanel工具面板\" alignment=\"0\" max=\"32767\" attributes=\"0\"/>\n                  <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n                      <EmptySpace pref=\"321\" max=\"32767\" attributes=\"0\"/>\n                      <Component id=\"jButton关闭\" min=\"-2\" pref=\"76\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"jButton发送\" min=\"-2\" pref=\"77\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace min=\"-2\" pref=\"5\" max=\"-2\" attributes=\"0\"/>\n                  </Group>\n                  <Component id=\"jScrollPane3\" alignment=\"0\" pref=\"486\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n            </DimensionLayout>\n            <DimensionLayout dim=\"1\">\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n                      <Component id=\"jPanel工具面板\" min=\"-2\" pref=\"36\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"jScrollPane3\" min=\"-2\" pref=\"96\" max=\"-2\" attributes=\"1\"/>\n                      <EmptySpace min=\"-2\" pref=\"10\" max=\"-2\" attributes=\"0\"/>\n                      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                          <Component id=\"jButton发送\" pref=\"35\" max=\"32767\" attributes=\"1\"/>\n                          <Component id=\"jButton关闭\" alignment=\"0\" pref=\"35\" max=\"32767\" attributes=\"1\"/>\n                      </Group>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                  </Group>\n              </Group>\n            </DimensionLayout>\n          </Layout>\n          <SubComponents>\n            <Component class=\"javax.swing.JButton\" name=\"jButton&#x53d1;&#x9001;\">\n              <Properties>\n                <Property name=\"text\" type=\"java.lang.String\" value=\"&#x53d1;&#x9001;\"/>\n              </Properties>\n              <Events>\n                <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"jButton&#x53d1;&#x9001;ActionPerformed\"/>\n              </Events>\n              <AuxValues>\n                <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n              </AuxValues>\n            </Component>\n            <Component class=\"javax.swing.JButton\" name=\"jButton&#x5173;&#x95ed;\">\n              <Properties>\n                <Property name=\"text\" type=\"java.lang.String\" value=\"&#x5173;&#x95ed;\"/>\n              </Properties>\n            </Component>\n            <Container class=\"javax.swing.JPanel\" name=\"jPanel&#x5de5;&#x5177;&#x9762;&#x677f;\">\n              <Properties>\n                <Property name=\"background\" type=\"java.awt.Color\" editor=\"org.netbeans.beaninfo.editors.ColorEditor\">\n                  <Color blue=\"ff\" green=\"ff\" red=\"cc\" type=\"rgb\"/>\n                </Property>\n              </Properties>\n              <AuxValues>\n                <AuxValue name=\"JavaCodeGenerator_VariableLocal\" type=\"java.lang.Boolean\" value=\"true\"/>\n              </AuxValues>\n\n              <Layout>\n                <DimensionLayout dim=\"0\">\n                  <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                      <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                          <EmptySpace max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"jLabel字体\" min=\"-2\" pref=\"36\" max=\"-2\" attributes=\"0\"/>\n                          <EmptySpace max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"jLabel表情\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <EmptySpace max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"jLabel音乐\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <EmptySpace max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"jLabel图片\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <EmptySpace type=\"unrelated\" max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"jLabel截图\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <EmptySpace pref=\"193\" max=\"32767\" attributes=\"0\"/>\n                          <Component id=\"jLabel聊天记录\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      </Group>\n                  </Group>\n                </DimensionLayout>\n                <DimensionLayout dim=\"1\">\n                  <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                      <Group type=\"102\" attributes=\"0\">\n                          <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                              <Component id=\"jLabel字体\" min=\"-2\" max=\"-2\" attributes=\"1\"/>\n                              <Component id=\"jLabel表情\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"1\"/>\n                              <Component id=\"jLabel音乐\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jLabel图片\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jLabel截图\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jLabel聊天记录\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          </Group>\n                          <EmptySpace max=\"-2\" attributes=\"0\"/>\n                      </Group>\n                  </Group>\n                </DimensionLayout>\n              </Layout>\n              <SubComponents>\n                <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x5b57;&#x4f53;\">\n                  <Properties>\n                    <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                      <Image iconType=\"3\" name=\"/client/img/chat/fun_font_32.png\"/>\n                    </Property>\n                    <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"&#x5b57;&#x4f53;\"/>\n                    <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n                      <Border info=\"org.netbeans.modules.form.compat2.border.EtchedBorderInfo\">\n                        <EtchetBorder>\n                          <Color PropertyName=\"highlight\" blue=\"ff\" green=\"ff\" red=\"cc\" type=\"rgb\"/>\n                          <Color PropertyName=\"shadow\" blue=\"ff\" green=\"ff\" red=\"cc\" type=\"rgb\"/>\n                        </EtchetBorder>\n                      </Border>\n                    </Property>\n                  </Properties>\n                  <AuxValues>\n                    <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n                  </AuxValues>\n                </Component>\n                <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x8868;&#x60c5;\">\n                  <Properties>\n                    <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                      <Image iconType=\"3\" name=\"/client/img/chat/fun_face_32.png\"/>\n                    </Property>\n                    <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"&#x8868;&#x60c5;\"/>\n                  </Properties>\n                  <AuxValues>\n                    <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n                  </AuxValues>\n                </Component>\n                <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x56fe;&#x7247;\">\n                  <Properties>\n                    <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                      <Image iconType=\"3\" name=\"/client/img/chat/fun_picture_32.png\"/>\n                    </Property>\n                    <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"&#x53d1;&#x9001;&#x56fe;&#x7247;\"/>\n                  </Properties>\n                  <AuxValues>\n                    <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n                  </AuxValues>\n                </Component>\n                <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x97f3;&#x4e50;\">\n                  <Properties>\n                    <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                      <Image iconType=\"3\" name=\"/client/img/chat/fun_music_32.png\"/>\n                    </Property>\n                    <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"&#x53d1;&#x9001;&#x97f3;&#x4e50;\"/>\n                  </Properties>\n                  <AuxValues>\n                    <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n                  </AuxValues>\n                </Component>\n                <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x622a;&#x56fe;\">\n                  <Properties>\n                    <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                      <Image iconType=\"3\" name=\"/client/img/chat/fun_snap_32.png\"/>\n                    </Property>\n                    <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"&#x622a;&#x56fe;\"/>\n                  </Properties>\n                  <AuxValues>\n                    <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n                  </AuxValues>\n                </Component>\n                <Component class=\"javax.swing.JLabel\" name=\"jLabel&#x804a;&#x5929;&#x8bb0;&#x5f55;\">\n                  <Properties>\n                    <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n                      <Image iconType=\"3\" name=\"/client/img/chat/fun_message_history_32.png\"/>\n                    </Property>\n                    <Property name=\"text\" type=\"java.lang.String\" value=\"&#x804a;&#x5929;&#x8bb0;&#x5f55;\"/>\n                    <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"&#x6253;&#x5f00;&#x6211;&#x7684;&#x804a;&#x5929;&#x8bb0;&#x5f55;\"/>\n                  </Properties>\n                  <AuxValues>\n                    <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n                  </AuxValues>\n                </Component>\n              </SubComponents>\n            </Container>\n            <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane3\">\n              <AuxValues>\n                <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n              </AuxValues>\n\n              <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n              <SubComponents>\n                <Component class=\"javax.swing.JTextPane\" name=\"jTextPane&#x53d1;&#x9001;&#x6846;\">\n                  <AuxValues>\n                    <AuxValue name=\"JavaCodeGenerator_VariableModifier\" type=\"java.lang.Integer\" value=\"1\"/>\n                  </AuxValues>\n                </Component>\n              </SubComponents>\n            </Container>\n          </SubComponents>\n        </Container>\n      </SubComponents>\n    </Container>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "src/client/frame/ChatFrame.java",
    "content": "﻿/*\n * ChatFrame.java\n *\n * Created on __DATE__, __TIME__\n */\n\npackage client.frame;\n\nimport java.awt.Color;\n\nimport javax.swing.UIManager;\n\nimport client.common.MyLabel;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\n\n/**\n *\n * @author  __USER__\n */\npublic class ChatFrame extends javax.swing.JFrame\n{\n\n\t/** Creates new form ChatFrame */\n\tpublic ChatFrame()\n\t{\n\t\tinitComponents();\n\t}\n\n\t/** This method is called from within the constructor to\n\t * initialize the form.\n\t * WARNING: Do NOT modify this code. The content of this method is\n\t * always regenerated by the Form Editor.\n\t */\n\t//GEN-BEGIN:initComponents\n\t// <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">\n\tprivate void initComponents()\n\t{\n\n\t\tjPanel右侧面板 = new javax.swing.JPanel();\n\t\tjLabelQQ秀_对方 = new javax.swing.JLabel();\n\t\tjLabelQQ秀_自己 = new javax.swing.JLabel();\n\t\tjPanel左侧面板 = new javax.swing.JPanel();\n\t\tjPanel顶部面板 = new javax.swing.JPanel();\n\t\tjLabel头像 = new javax.swing.JLabel();\n\t\tjLabelQQ空间 = new javax.swing.JLabel();\n\t\tjLabel我的好友 = new javax.swing.JLabel();\n\t\tjLabel视频 = new javax.swing.JLabel();\n\t\tjLabel语音 = new javax.swing.JLabel();\n\t\tjLabel发送文件 = new javax.swing.JLabel();\n\t\tjLabel加好友 = new javax.swing.JLabel();\n\t\tjPanel聊天面板 = new javax.swing.JPanel();\n\t\tjScrollPane1 = new javax.swing.JScrollPane();\n\t\tjTextPane接收框 = new javax.swing.JTextPane();\n\t\tjPanel发送面板 = new javax.swing.JPanel();\n\t\tjButton发送 = new javax.swing.JButton();\n\t\tjButton关闭 = new javax.swing.JButton();\n\t\tjavax.swing.JPanel jPanel工具面板 = new javax.swing.JPanel();\n\t\tjLabel字体 = new javax.swing.JLabel();\n\t\tjLabel表情 = new javax.swing.JLabel();\n\t\tjLabel表情.addMouseListener(new MouseAdapter() {\n\t\t\t@Override\n\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t{\n\t\t\t\tselectFace();\n\t\t\t}\n\t\t});\n\t\tjLabel图片 = new javax.swing.JLabel();\n\t\tjLabel图片.addMouseListener(new MouseAdapter() {\n\t\t\t@Override\n\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t{\n\t\t\t\tsendImg();\n\t\t\t}\n\t\t});\n\t\tjLabel音乐 = new javax.swing.JLabel();\n\t\tjLabel截图 = new javax.swing.JLabel();\n\t\tjLabel截图.addMouseListener(new MouseAdapter() {\n\t\t\t@Override\n\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t{\n\t\t\t\tscreenFram();\n\t\t\t}\n\t\t});\n\t\tjLabel聊天记录 = new javax.swing.JLabel();\n\t\tjScrollPane3 = new javax.swing.JScrollPane();\n\t\tjTextPane发送框 = new javax.swing.JTextPane();\n\n\t\tsetDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);\n\t\tsetTitle(\"\\u804a\\u5929\");\n\t\tsetBackground(new java.awt.Color(204, 255, 255));\n\t\taddWindowListener(new java.awt.event.WindowAdapter()\n\t\t{\n\t\t\tpublic void windowClosing(java.awt.event.WindowEvent evt)\n\t\t\t{\n\t\t\t\tformWindowClosing(evt);\n\t\t\t}\n\t\t});\n\n\t\tjPanel右侧面板.setBackground(new java.awt.Color(204, 255, 255));\n\n\t\tjLabelQQ秀_对方.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/qqshow/qqshow_girl_02_180.jpg\"))); // NOI18N\n\n\t\tjLabelQQ秀_自己.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/qqshow/qqshow_boy_01.jpg\"))); // NOI18N\n\n\t\tjavax.swing.GroupLayout jPanel右侧面板Layout = new javax.swing.GroupLayout(\n\t\t\t\tjPanel右侧面板);\n\t\tjPanel右侧面板.setLayout(jPanel右侧面板Layout);\n\t\tjPanel右侧面板Layout.setHorizontalGroup(jPanel右侧面板Layout\n\t\t\t\t.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t.addComponent(jLabelQQ秀_对方).addComponent(jLabelQQ秀_自己));\n\t\tjPanel右侧面板Layout.setVerticalGroup(jPanel右侧面板Layout.createParallelGroup(\n\t\t\t\tjavax.swing.GroupLayout.Alignment.LEADING).addGroup(\n\t\t\t\tjPanel右侧面板Layout\n\t\t\t\t\t\t.createSequentialGroup()\n\t\t\t\t\t\t.addComponent(jLabelQQ秀_对方)\n\t\t\t\t\t\t.addGap(18, 18, 18)\n\t\t\t\t\t\t.addComponent(jLabelQQ秀_自己,\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE, 251,\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t\t.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t\t\tShort.MAX_VALUE)));\n\n\t\tjPanel左侧面板.setBackground(new java.awt.Color(204, 255, 255));\n\n\t\tjPanel顶部面板.setBackground(new java.awt.Color(51, 204, 255));\n\n\t\tjLabel头像.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/QQ_64.png\"))); // NOI18N\n\n\t\tjLabelQQ空间.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_qzone_54.png\"))); // NOI18N\n\n\t\tjLabel我的好友.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_myfeeds_54.png\"))); // NOI18N\n\n\t\tjLabel视频.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_video_54.png\"))); // NOI18N\n\t\tjLabel视频.setToolTipText(\"\\u5f00\\u59cb\\u89c6\\u9891\");\n\n\t\tjLabel语音.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_voice_54.png\"))); // NOI18N\n\t\tjLabel语音.setToolTipText(\"\\u5f00\\u59cb\\u8bed\\u97f3\");\n\n\t\tjLabel发送文件.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_sendfile_54.png\"))); // NOI18N\n\t\tjLabel发送文件.setToolTipText(\"\\u53d1\\u9001\\u6587\\u4ef6\");\n\t\tjLabel发送文件.addMouseListener(new java.awt.event.MouseAdapter()\n\t\t{\n\t\t\tpublic void mouseClicked(java.awt.event.MouseEvent evt)\n\t\t\t{\n\t\t\t\tjLabel发送文件MouseClicked(evt);\n\t\t\t}\n\t\t});\n\n\t\tjLabel加好友.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_add_54.png\"))); // NOI18N\n\n\t\tjavax.swing.GroupLayout jPanel顶部面板Layout = new javax.swing.GroupLayout(\n\t\t\t\tjPanel顶部面板);\n\t\tjPanel顶部面板.setLayout(jPanel顶部面板Layout);\n\t\tjPanel顶部面板Layout\n\t\t\t\t.setHorizontalGroup(jPanel顶部面板Layout\n\t\t\t\t\t\t.createParallelGroup(\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t\t\t.addGroup(\n\t\t\t\t\t\t\t\tjPanel顶部面板Layout\n\t\t\t\t\t\t\t\t\t\t.createSequentialGroup()\n\t\t\t\t\t\t\t\t\t\t.addContainerGap()\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel头像)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.UNRELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel视频)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel语音)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel发送文件)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.UNRELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabelQQ空间)\n\t\t\t\t\t\t\t\t\t\t.addGap(13, 13, 13)\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel我的好友)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED,\n\t\t\t\t\t\t\t\t\t\t\t\t23, Short.MAX_VALUE)\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel加好友)\n\t\t\t\t\t\t\t\t\t\t.addContainerGap()));\n\t\tjPanel顶部面板Layout\n\t\t\t\t.setVerticalGroup(jPanel顶部面板Layout\n\t\t\t\t\t\t.createParallelGroup(\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t\t\t.addGroup(\n\t\t\t\t\t\t\t\tjPanel顶部面板Layout\n\t\t\t\t\t\t\t\t\t\t.createSequentialGroup()\n\t\t\t\t\t\t\t\t\t\t.addContainerGap()\n\t\t\t\t\t\t\t\t\t\t.addGroup(\n\t\t\t\t\t\t\t\t\t\t\t\tjPanel顶部面板Layout\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.createParallelGroup(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.TRAILING)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel头像)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addGroup(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjPanel顶部面板Layout\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.createParallelGroup(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjLabel视频)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjLabel语音)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjLabel发送文件)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjLabelQQ空间)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjLabel我的好友)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjLabel加好友)))\n\t\t\t\t\t\t\t\t\t\t.addContainerGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\tShort.MAX_VALUE)));\n\n\t\tjPanel聊天面板.setLayout(new java.awt.BorderLayout());\n\n\t\tjTextPane接收框.setEditable(false);\n\t\tjScrollPane1.setViewportView(jTextPane接收框);\n\n\t\tjPanel聊天面板.add(jScrollPane1, java.awt.BorderLayout.CENTER);\n\n\t\tjPanel发送面板.setBackground(new java.awt.Color(204, 255, 255));\n\n\t\tjButton发送.setText(\"\\u53d1\\u9001\");\n\t\tjButton发送.addActionListener(new java.awt.event.ActionListener()\n\t\t{\n\t\t\tpublic void actionPerformed(java.awt.event.ActionEvent evt)\n\t\t\t{\n\t\t\t\tjButton发送ActionPerformed(evt);\n\t\t\t}\n\t\t});\n\n\t\tjButton关闭.setText(\"\\u5173\\u95ed\");\n\n\t\tjPanel工具面板.setBackground(new java.awt.Color(204, 255, 255));\n\n\t\tjLabel字体.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_font_32.png\"))); // NOI18N\n\t\tjLabel字体.setToolTipText(\"\\u5b57\\u4f53\");\n\t\tjLabel字体.setBorder(javax.swing.BorderFactory.createEtchedBorder(\n\t\t\t\tnew java.awt.Color(204, 255, 255), new java.awt.Color(204, 255,\n\t\t\t\t\t\t255)));\n\n\t\tjLabel表情.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_face_32.png\"))); // NOI18N\n\t\tjLabel表情.setToolTipText(\"\\u8868\\u60c5\");\n\n\t\tjLabel图片.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_picture_32.png\"))); // NOI18N\n\t\tjLabel图片.setToolTipText(\"\\u53d1\\u9001\\u56fe\\u7247\");\n\n\t\tjLabel音乐.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_music_32.png\"))); // NOI18N\n\t\tjLabel音乐.setToolTipText(\"\\u53d1\\u9001\\u97f3\\u4e50\");\n\n\t\tjLabel截图.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_snap_32.png\"))); // NOI18N\n\t\tjLabel截图.setToolTipText(\"\\u622a\\u56fe\");\n\n\t\tjLabel聊天记录.setIcon(new javax.swing.ImageIcon(getClass().getResource(\n\t\t\t\t\"/client/img/chat/fun_message_history_32.png\"))); // NOI18N\n\t\tjLabel聊天记录.setText(\"\\u804a\\u5929\\u8bb0\\u5f55\");\n\t\tjLabel聊天记录\n\t\t\t\t.setToolTipText(\"\\u6253\\u5f00\\u6211\\u7684\\u804a\\u5929\\u8bb0\\u5f55\");\n\n\t\tjavax.swing.GroupLayout jPanel工具面板Layout = new javax.swing.GroupLayout(\n\t\t\t\tjPanel工具面板);\n\t\tjPanel工具面板.setLayout(jPanel工具面板Layout);\n\t\tjPanel工具面板Layout\n\t\t\t\t.setHorizontalGroup(jPanel工具面板Layout\n\t\t\t\t\t\t.createParallelGroup(\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t\t\t.addGroup(\n\t\t\t\t\t\t\t\tjPanel工具面板Layout\n\t\t\t\t\t\t\t\t\t\t.createSequentialGroup()\n\t\t\t\t\t\t\t\t\t\t.addContainerGap()\n\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\tjLabel字体,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\t36,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel表情)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel音乐)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel图片)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.UNRELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel截图)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED,\n\t\t\t\t\t\t\t\t\t\t\t\t193, Short.MAX_VALUE)\n\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel聊天记录)));\n\t\tjPanel工具面板Layout\n\t\t\t\t.setVerticalGroup(jPanel工具面板Layout\n\t\t\t\t\t\t.createParallelGroup(\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t\t\t.addGroup(\n\t\t\t\t\t\t\t\tjPanel工具面板Layout\n\t\t\t\t\t\t\t\t\t\t.createSequentialGroup()\n\t\t\t\t\t\t\t\t\t\t.addGroup(\n\t\t\t\t\t\t\t\t\t\t\t\tjPanel工具面板Layout\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.createParallelGroup(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel字体)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel表情)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel音乐)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel图片)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(jLabel截图)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjLabel聊天记录))\n\t\t\t\t\t\t\t\t\t\t.addContainerGap()));\n\n\t\tjScrollPane3.setViewportView(jTextPane发送框);\n\n\t\tjavax.swing.GroupLayout jPanel发送面板Layout = new javax.swing.GroupLayout(\n\t\t\t\tjPanel发送面板);\n\t\tjPanel发送面板.setLayout(jPanel发送面板Layout);\n\t\tjPanel发送面板Layout\n\t\t\t\t.setHorizontalGroup(jPanel发送面板Layout\n\t\t\t\t\t\t.createParallelGroup(\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t\t\t.addComponent(jPanel工具面板,\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t\t\tShort.MAX_VALUE)\n\t\t\t\t\t\t.addGroup(\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.TRAILING,\n\t\t\t\t\t\t\t\tjPanel发送面板Layout\n\t\t\t\t\t\t\t\t\t\t.createSequentialGroup()\n\t\t\t\t\t\t\t\t\t\t.addContainerGap(321, Short.MAX_VALUE)\n\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\tjButton关闭,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\t76,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\tjButton发送,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\t77,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t\t\t\t\t\t.addGap(5, 5, 5))\n\t\t\t\t\t\t.addComponent(jScrollPane3,\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE, 486,\n\t\t\t\t\t\t\t\tShort.MAX_VALUE));\n\t\tjPanel发送面板Layout\n\t\t\t\t.setVerticalGroup(jPanel发送面板Layout\n\t\t\t\t\t\t.createParallelGroup(\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t\t\t.addGroup(\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.TRAILING,\n\t\t\t\t\t\t\t\tjPanel发送面板Layout\n\t\t\t\t\t\t\t\t\t\t.createSequentialGroup()\n\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\tjPanel工具面板,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\t36,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\tjScrollPane3,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\t96,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t\t\t\t\t\t.addGap(10, 10, 10)\n\t\t\t\t\t\t\t\t\t\t.addGroup(\n\t\t\t\t\t\t\t\t\t\t\t\tjPanel发送面板Layout\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.createParallelGroup(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjButton发送,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t35,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tShort.MAX_VALUE)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjButton关闭,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t35,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tShort.MAX_VALUE))\n\t\t\t\t\t\t\t\t\t\t.addContainerGap()));\n\n\t\tjavax.swing.GroupLayout jPanel左侧面板Layout = new javax.swing.GroupLayout(\n\t\t\t\tjPanel左侧面板);\n\t\tjPanel左侧面板.setLayout(jPanel左侧面板Layout);\n\t\tjPanel左侧面板Layout.setHorizontalGroup(jPanel左侧面板Layout\n\t\t\t\t.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t.addComponent(jPanel顶部面板, javax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)\n\t\t\t\t.addComponent(jPanel发送面板, javax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)\n\t\t\t\t.addComponent(jPanel聊天面板, javax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t486, Short.MAX_VALUE));\n\t\tjPanel左侧面板Layout\n\t\t\t\t.setVerticalGroup(jPanel左侧面板Layout\n\t\t\t\t\t\t.createParallelGroup(\n\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t\t\t.addGroup(\n\t\t\t\t\t\t\t\tjPanel左侧面板Layout\n\t\t\t\t\t\t\t\t\t\t.createSequentialGroup()\n\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\tjPanel顶部面板,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\t89,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\tjPanel聊天面板,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\t260, Short.MAX_VALUE)\n\t\t\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED)\n\t\t\t\t\t\t\t\t\t\t.addComponent(\n\t\t\t\t\t\t\t\t\t\t\t\tjPanel发送面板,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE)));\n\n\t\tjavax.swing.GroupLayout layout = new javax.swing.GroupLayout(\n\t\t\t\tgetContentPane());\n\t\tgetContentPane().setLayout(layout);\n\t\tlayout.setHorizontalGroup(layout\n\t\t\t\t.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t.addGroup(\n\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.TRAILING,\n\t\t\t\t\t\tlayout.createSequentialGroup()\n\t\t\t\t\t\t\t\t.addComponent(jPanel左侧面板,\n\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t\t\t\t\tShort.MAX_VALUE)\n\t\t\t\t\t\t\t\t.addPreferredGap(\n\t\t\t\t\t\t\t\t\t\tjavax.swing.LayoutStyle.ComponentPlacement.RELATED)\n\t\t\t\t\t\t\t\t.addComponent(jPanel右侧面板,\n\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE,\n\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\t\t\t\t\tjavax.swing.GroupLayout.PREFERRED_SIZE)));\n\t\tlayout.setVerticalGroup(layout\n\t\t\t\t.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n\t\t\t\t.addComponent(jPanel右侧面板, javax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)\n\t\t\t\t.addComponent(jPanel左侧面板,\n\t\t\t\t\t\tjavax.swing.GroupLayout.Alignment.TRAILING,\n\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE,\n\t\t\t\t\t\tjavax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));\n\n\t\tpack();\n\t}// </editor-fold>\n\t//GEN-END:initComponents\n\n\tprivate void formWindowClosing(java.awt.event.WindowEvent evt)\n\t{\n\t\t// TODO add your handling code here:\n\t\tbeforeClose();\n\t}\n\n\tprivate void jLabel发送文件MouseClicked(java.awt.event.MouseEvent evt)\n\t{\n\t\t// TODO add your handling code here:\n\t\tsendFile();\n\t}\n\n\tprivate void jButton发送ActionPerformed(java.awt.event.ActionEvent evt)\n\t{\n\t\t// TODO add your handling code here:\n\t\tsendMessage();\n\t}\n\n\t//GEN-BEGIN:variables\n\t// Variables declaration - do not modify\n\tprivate javax.swing.JButton jButton关闭;\n\tpublic javax.swing.JButton jButton发送;\n\tprivate javax.swing.JLabel jLabelQQ秀_对方;\n\tprivate javax.swing.JLabel jLabelQQ秀_自己;\n\tpublic javax.swing.JLabel jLabelQQ空间;\n\tpublic javax.swing.JLabel jLabel加好友;\n\tpublic javax.swing.JLabel jLabel发送文件;\n\tpublic javax.swing.JLabel jLabel图片;\n\tprivate javax.swing.JLabel jLabel头像;\n\tpublic javax.swing.JLabel jLabel字体;\n\tpublic javax.swing.JLabel jLabel我的好友;\n\tpublic javax.swing.JLabel jLabel截图;\n\tpublic javax.swing.JLabel jLabel聊天记录;\n\tpublic javax.swing.JLabel jLabel表情;\n\tpublic javax.swing.JLabel jLabel视频;\n\tpublic javax.swing.JLabel jLabel语音;\n\tpublic javax.swing.JLabel jLabel音乐;\n\tprivate javax.swing.JPanel jPanel发送面板;\n\tprivate javax.swing.JPanel jPanel右侧面板;\n\tprivate javax.swing.JPanel jPanel左侧面板;\n\tprivate javax.swing.JPanel jPanel聊天面板;\n\tprivate javax.swing.JPanel jPanel顶部面板;\n\tprivate javax.swing.JScrollPane jScrollPane1;\n\tprivate javax.swing.JScrollPane jScrollPane3;\n\tpublic javax.swing.JTextPane jTextPane发送框;\n\tpublic javax.swing.JTextPane jTextPane接收框;\n\n\t// End of variables declaration//GEN-END:variables\n\n\tpublic javax.swing.JTextPane getjTextPane聊天记录()\n\t{\n\t\treturn jTextPane接收框;\n\t}\n\n\tpublic void setjTextPane聊天记录(javax.swing.JTextPane jTextPane聊天记录)\n\t{\n\t\tthis.jTextPane接收框 = jTextPane聊天记录;\n\t}\n\n\t/**\n\t * 发送消息，空的方法，由子类实现\n\t */\n\tpublic void sendMessage()\n\t{\n\t}\n\n\tpublic void beforeClose(){}\n\t/**\n\t * 选择表情\n\t */\n\tpublic void selectFace(){}\n\t/**\n\t * 处理消息中的表情\n\t */\n\tpublic void dealIcon(String str)\n\t{\n\t\t\n\t}\n\t/**\n\t * 发送文件\n\t */\n\tpublic void sendFile()\n\t{\n\t\t\n\t}\n\n\t\n\t/**\n\t * 发送图片\n\t */\n\tpublic void sendImg()\n\t{\n\t\t\n\t}\n\n\n\t\n\tpublic void screenFram()\n\t{\n\t\t\n\t}\n\n}"
  },
  {
    "path": "src/client/frame/FaceFrame.java",
    "content": "﻿package client.frame;\n\nimport java.awt.Color;\nimport java.awt.GridLayout;\nimport java.awt.SystemColor;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\n\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JWindow;\n\nimport client.common.MyLabel;\nimport client.control.Chat;\n\npublic class FaceFrame extends JWindow\n{\n\n\tprivate JPanel contentPane;\n\n\tGridLayout gridLayout1 = new GridLayout();\n\tpublic static JLabel[] ico = new JLabel[90];\n\tChat chat;\n\tint width=720;\n\tint height=288;\n\tpublic FaceFrame(Chat chat)\n\t{\n\t\tsuper(chat);\n\t\tthis.chat = chat;\n\t\ttry\n\t\t{\n\t\t\tjbInit();\n\t\t\tint left=chat.getLocation().x+20;\n\t\t\tint top=chat.getLocation().y+chat.getHeight()-200-height;\n\t\t\tthis.setBounds(left, top, width, height);\n\t\t\tthis.setAlwaysOnTop(true);\n\t\t\tthis.setVisible(true);\n\t\t} catch (Exception exception)\n\t\t{\n\t\t\texception.printStackTrace();\n\t\t}\n\t}\n\n\tprivate void jbInit() throws Exception\n\t{\n\t\tgetContentPane().setLayout(gridLayout1);\n\t\tgridLayout1.setColumns(15);\n\t\tgridLayout1.setHgap(1);\n\t\tgridLayout1.setRows(6);\n\t\tgridLayout1.setVgap(1);\n\t\tString fileName = \" \";\n\t\tfor (int i = 0; i < ico.length; i++)\n\t\t{\n\t\t\tif(i<10)\n        \t{\n        \t\tfileName= \"/client/img/face/f00\"+i+\".png\";//修改图片路径 \n        \t}\n        \telse\n        \t{\n        \t\tfileName= \"/client/img/face/f0\"+i+\".png\";\n\t\t\t}\n\t\t\tico[i]=new   JLabel(new   ImageIcon(FaceFrame.class.getResource(fileName)));\n\t\t\tico[i].setToolTipText(\"点此添加QQ表情哟^_^\");\n\t\t\tnew MyLabel(ico[i],Color.black).addEvent();\n\t\t\tfinal Icon img = ico[i].getIcon();\n\t\t\tfinal int count=i;\n\t\t\tico[i].addMouseListener(new MouseAdapter()\n\t\t\t{\n\t\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t\t{\n\t\t\t\t\tchat.jTextPane发送框.insertIcon(img);\n\t\t\t\t\tchat.faceIdx=count;\n\t\t\t\t\tgetObj().dispose();// 这里最好用单例模式\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.getContentPane().add(ico[i]);\n\t\t}\n\t\tthis.getContentPane().setBackground(SystemColor.text);\n\t}\n\n\tprivate JWindow getObj()\n\t{\n\t\treturn this;\n\t}\n\n}\n"
  },
  {
    "path": "src/client/frame/LoginFrame.java",
    "content": "﻿package client.frame;\n\nimport java.awt.EventQueue;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\nimport javax.swing.border.EmptyBorder;\nimport client.frame.MyPanel;\nimport javax.swing.JLabel;\n//import com.sun.awt.AWTUtilities;\nimport javax.swing.JPasswordField;\nimport javax.swing.JComboBox;\nimport java.awt.Font;\nimport java.awt.Color;\nimport javax.swing.ImageIcon;\nimport javax.swing.JCheckBox;\nimport javax.swing.JTextField;\nimport java.awt.Toolkit;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\n\npublic class LoginFrame extends JFrame\n{\n\n\tprivate JPanel contentPane;\n\tpublic JPasswordField pwd密码;\n\tprivate JLabel lblQQ2013;\n\tpublic JLabel lbl头像;\n\tpublic JCheckBox checkBox记住密码;\n\tpublic JCheckBox checkBox自动登录;\n\tpublic JLabel lbl登录;\n\tpublic JTextField textField用户名;\n\tpublic JLabel lbl注册账号;\n\tpublic JLabel lbl忘记密码;\n\tpublic JLabel lbl最小化;\n\tpublic JLabel lbl退出;\n\tpublic JLabel lbl多账号;\n\tpublic JLabel lbl设置;\n\tpublic JComboBox comboBox状态;\n\t/**\n\t * Launch the application.\n\t */\n\tpublic static void main(String[] args)\n\t{\n\t\tEventQueue.invokeLater(new Runnable()\n\t\t{\n\t\t\tpublic void run()\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tLoginFrame frame = new LoginFrame();\n\t\t\t\t\t//AWTUtilities.setWindowOpaque(frame, false);//设置窗体完全透明\n\t\t\t\t\tframe.setVisible(true);\n\t\t\t\t}\n\t\t\t\tcatch (Exception e)\n\t\t\t\t{\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Create the frame.\n\t */\n\tpublic LoginFrame()\n\t{\n\t\tsetTitle(\"QQ2013\");\n\t\tsetIconImage(Toolkit.getDefaultToolkit().getImage(LoginFrame.class.getResource(\"/client/img/QQ_64.png\")));\n\t\tsetUndecorated(true);//设置窗体没有边框\n\t\tsetDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n\t\tsetBounds(100, 100, 354, 272);\n\t\t\n\t\tcontentPane = new MyPanel(\"../img/QQ2011_Login.png\");\n\t\tcontentPane.setBorder(new EmptyBorder(5, 5, 5, 5));\n\t\tsetContentPane(contentPane);\n\t\tcontentPane.setLayout(null);\n\t\t\n\t\tpwd密码 = new JPasswordField();\n\t\tpwd密码.setText(\"123\");\n\t\tpwd密码.setEchoChar('●');\n\t\tpwd密码.setBounds(104, 163, 154, 26);\n\t\tcontentPane.add(pwd密码);\n\t\t\n\t\tlblQQ2013 = new JLabel(\"QQ2013\");\n\t\tlblQQ2013.setForeground(new Color(0, 0, 51));\n\t\tlblQQ2013.setFont(new Font(\"宋体\", Font.BOLD, 16));\n\t\tlblQQ2013.setBounds(14, 6, 55, 18);\n\t\tcontentPane.add(lblQQ2013);\n\t\t\n\t\tlbl头像 = new JLabel(\"\");\n\t\tlbl头像.setIcon(new ImageIcon(LoginFrame.class.getResource(\"/client/img/headImage/head_boy_01_64.jpg\")));\n\t\tlbl头像.setBounds(18, 127, 64, 64);\n\t\tcontentPane.add(lbl头像);\n\t\t\n\t\tcheckBox记住密码 = new JCheckBox(\"\\u8BB0\\u4F4F\\u5BC6\\u7801\");\n\t\tcheckBox记住密码.setBounds(156, 198, 76, 18);\n\t\tcontentPane.add(checkBox记住密码);\n\t\t\n\t\tcheckBox自动登录 = new JCheckBox(\"\\u81EA\\u52A8\\u767B\\u5F55\");\n\t\tcheckBox自动登录.setBounds(237, 198, 76, 18);\n\t\tcontentPane.add(checkBox自动登录);\n\t\t\n\t\tlbl登录 = new JLabel(\"\");\n\t\tlbl登录.setIcon(new ImageIcon(LoginFrame.class.getResource(\"/client/img/button/button_login_1.png\")));\n\t\tlbl登录.setBounds(262, 237, 69, 22);\n\t\tcontentPane.add(lbl登录);\n\t\t\n\t\ttextField用户名 = new JTextField();\n\t\ttextField用户名.setText(\"\\u9A6C\\u5316\\u817E\");\n\t\ttextField用户名.setBounds(104, 128, 154, 26);\n\t\tcontentPane.add(textField用户名);\n\t\ttextField用户名.setColumns(10);\n\t\t\n\t\tlbl注册账号 = new JLabel(\"\\u6CE8\\u518C\\u8D26\\u53F7\");\n\t\tlbl注册账号.setFont(new Font(\"SansSerif\", Font.PLAIN, 13));\n\t\tlbl注册账号.setForeground(new Color(0, 51, 255));\n\t\tlbl注册账号.setBounds(288, 132, 55, 18);\n\t\tcontentPane.add(lbl注册账号);\n\t\t\n\t\tlbl忘记密码 = new JLabel(\"\\u5FD8\\u8BB0\\u5BC6\\u7801\");\n\t\tlbl忘记密码.setFont(new Font(\"SansSerif\", Font.PLAIN, 13));\n\t\tlbl忘记密码.setForeground(new Color(0, 51, 255));\n\t\tlbl忘记密码.setBounds(288, 167, 55, 18);\n\t\tcontentPane.add(lbl忘记密码);\n\t\t\n\t\tlbl最小化 = new JLabel(\"\");\n\t\tlbl最小化.setIcon(new ImageIcon(LoginFrame.class.getResource(\"/client/img/button/login_minsize_1.png\")));\n\t\tlbl最小化.setBounds(284, 0, 29, 19);\n\t\tcontentPane.add(lbl最小化);\n\t\t\n\t\tlbl退出 = new JLabel(\"\");\n\t\tlbl退出.setIcon(new ImageIcon(LoginFrame.class.getResource(\"/client/img/button/login_exit_1.png\")));\n\t\tlbl退出.setBounds(312, -1, 37, 20);\n\t\tcontentPane.add(lbl退出);\n\t\t\n\t\tlbl多账号 = new JLabel(\"\");\n\t\tlbl多账号.setIcon(new ImageIcon(LoginFrame.class.getResource(\"/client/img/button/login_duozhanghao_1.png\")));\n\t\tlbl多账号.setBounds(14, 237, 69, 21);\n\t\tcontentPane.add(lbl多账号);\n\t\t\n\t\tlbl设置 = new JLabel(\"\");\n\t\tlbl设置.setIcon(new ImageIcon(LoginFrame.class.getResource(\"/client/img/button/login_setting_1.png\")));\n\t\tlbl设置.setBounds(93, 237, 69, 21);\n\t\tcontentPane.add(lbl设置);\n\t\t\n\t\tcomboBox状态 = new JComboBox();\n\t\tcomboBox状态.setBounds(104, 195, 40, 24);\n\t\tcontentPane.add(comboBox状态);\n\t}\n}\n"
  },
  {
    "path": "src/client/frame/MainFrame.java",
    "content": "﻿package client.frame;\n\nimport java.awt.EventQueue;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\nimport java.awt.Toolkit;\nimport java.awt.Color;\nimport javax.swing.GroupLayout;\nimport javax.swing.GroupLayout.Alignment;\nimport javax.swing.JOptionPane;\nimport javax.swing.LayoutStyle.ComponentPlacement;\nimport javax.swing.JLabel;\nimport javax.swing.ImageIcon;\nimport javax.swing.JComboBox;\nimport java.awt.Font;\nimport javax.swing.JTabbedPane;\nimport javax.swing.JButton;\nimport javax.swing.JToolBar;\nimport java.awt.FlowLayout;\nimport java.awt.BorderLayout;\nimport javax.swing.JTree;\nimport javax.swing.JScrollPane;\nimport javax.swing.tree.DefaultTreeModel;\nimport javax.swing.tree.DefaultMutableTreeNode;\nimport javax.swing.tree.MutableTreeNode;\nimport javax.swing.tree.TreeModel;\nimport javax.swing.tree.TreePath;\nimport javax.swing.tree.TreeSelectionModel;\n\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JPopupMenu;\nimport java.awt.Component;\nimport javax.swing.JMenuItem;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ActionEvent;\n\n/**\n * @author LXA\n *\n */\npublic class MainFrame extends JFrame\n{\n\tpublic JLabel lbl设置;\n\tpublic JLabel lbl头像;\n\tpublic JComboBox comboBox状态;\n\tpublic JLabel lbl用户名;\n\tpublic JLabel lbl个性签名;\n\tpublic JTree tree;\n\tprivate JTabbedPane tabbedPane;\n\tprivate JPanel panel好友列表;\n\tprivate JPanel panel群;\n\tprivate JPanel panel最近;\n\tprivate JScrollPane scrollPane好友;\n\tprivate JPanel panel用户信息;\n\tprivate JPanel panel好友面板;\n\tprivate JPanel panel设置面板;\n\tprivate JPopupMenu popupMenu好友列表;\n\tprivate JMenuItem menuItem发送即时消息;\n\tprivate JMenuItem menuItem查看好友信息;\n\tprivate JMenuItem menuItem发送文件;\n\tprivate JMenuItem menuItem删除用户;\n\n\n\t/**\n\t * Create the frame.\n\t */\n\tpublic MainFrame()\n\t{\n\t\tsetIconImage(Toolkit.getDefaultToolkit().getImage(MainFrame.class.getResource(\"/client/img/QQ_64.png\")));\n\t\tsetTitle(\"QQ2013\");\n\t\tsetDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n\t\tsetBounds(100, 100, 330, 600);\n\t\t\n\t\tpanel用户信息 = new JPanel();\n\t\tpanel用户信息.setBackground(new Color(51, 153, 255));\n\t\t\n\t\tpanel好友面板 = new JPanel();\n\t\t\n\t\tpanel设置面板 = new JPanel();\n\t\tpanel设置面板.setBackground(new Color(51, 153, 255));\n\t\tGroupLayout groupLayout = new GroupLayout(getContentPane());\n\t\tgroupLayout.setHorizontalGroup(\n\t\t\tgroupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addComponent(panel用户信息, GroupLayout.DEFAULT_SIZE, 361, Short.MAX_VALUE)\n\t\t\t\t.addComponent(panel设置面板, GroupLayout.DEFAULT_SIZE, 361, Short.MAX_VALUE)\n\t\t\t\t.addComponent(panel好友面板, GroupLayout.DEFAULT_SIZE, 361, Short.MAX_VALUE)\n\t\t);\n\t\tgroupLayout.setVerticalGroup(\n\t\t\tgroupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t.addComponent(panel用户信息, GroupLayout.PREFERRED_SIZE, 96, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(panel好友面板, GroupLayout.DEFAULT_SIZE, 303, Short.MAX_VALUE)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(panel设置面板, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE))\n\t\t);\n\t\tpanel好友面板.setLayout(new BorderLayout(0, 0));\n\t\t\n\t\ttabbedPane = new JTabbedPane(JTabbedPane.TOP);\n\t\tpanel好友面板.add(tabbedPane, BorderLayout.CENTER);\n\t\t\n\t\tpanel好友列表 = new JPanel();\n\t\ttabbedPane.addTab(\"\\u597D\\u53CB\", new ImageIcon(MainFrame.class.getResource(\"/client/img/friend_list.png\")), panel好友列表, null);\n\t\tpanel好友列表.setLayout(new BorderLayout(0, 0));\n\t\t\n\t\tscrollPane好友 = new JScrollPane();\n\t\tpanel好友列表.add(scrollPane好友);\n\t\t\n\t\ttree = new JTree();\n\t\tscrollPane好友.setViewportView(tree);\n\t\t\n\t\tpopupMenu好友列表 = new JPopupMenu();\n\t\taddPopup(tree, popupMenu好友列表);\n\t\t\n\t\tmenuItem发送即时消息 = new JMenuItem(\"\\u53D1\\u9001\\u5373\\u65F6\\u6D88\\u606F\");\n\t\tmenuItem发送即时消息.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e) \n\t\t\t{\n\t\t\t\tstartChat(e);\n\t\t\t}\n\t\t});\n\t\tmenuItem发送即时消息.setIcon(new ImageIcon(MainFrame.class.getResource(\"/client/img/QQ_16.png\")));\n\t\tpopupMenu好友列表.add(menuItem发送即时消息);\n\t\t\n\t\tmenuItem发送文件 = new JMenuItem(\"\\u53D1\\u9001\\u6587\\u4EF6\");\n\t\tmenuItem发送文件.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e) \n\t\t\t{\n\t\t\t\tsendFile(e);\n\t\t\t}\n\t\t});\n\t\tpopupMenu好友列表.add(menuItem发送文件);\n\t\t\n\t\tmenuItem查看好友信息 = new JMenuItem(\"\\u67E5\\u770B\\u597D\\u53CB\\u8D44\\u6599\");\n\t\tmenuItem查看好友信息.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e) \n\t\t\t{\n\t\t\t\tgetFriendInfo(e);\n\t\t\t}\n\t\t});\n\t\tpopupMenu好友列表.add(menuItem查看好友信息);\n\t\t\n\t\tmenuItem删除用户 = new JMenuItem(\"\\u5220\\u9664\\u7528\\u6237\");\n\t\tmenuItem删除用户.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e) \n\t\t\t{\n\t\t\t\tdeleteFriend(e);\n\t\t\t}\n\t\t});\n\t\tpopupMenu好友列表.add(menuItem删除用户);\n\n\t\tpanel群 = new JPanel();\n\t\ttabbedPane.addTab(\"\\u7FA4\\u7EC4\", new ImageIcon(MainFrame.class.getResource(\"/client/img/friend_qun.png\")), panel群, null);\n\t\t\n\t\tJButton btn官方聊天室 = new JButton(\"\\u8FDB\\u5165\\u5B98\\u65B9\\u804A\\u5929\\u5BA4\");\n\t\tbtn官方聊天室.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e)\n\t\t\t{\n\t\t\t\tgotoChatRoom();\n\t\t\t}\n\t\t});\n\t\tbtn官方聊天室.setFont(new Font(\"微软雅黑\", Font.PLAIN, 28));\n\t\t\n\t\tJButton btn新建聊天室 = new JButton(\"\\u65B0\\u5EFA\\u804A\\u5929\\u5BA4\");\n\t\tbtn新建聊天室.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e) \n\t\t\t{\n\t\t\t\tbuildNewChatRoom();\n\t\t\t}\n\t\t});\n\t\tbtn新建聊天室.setFont(new Font(\"微软雅黑\", Font.PLAIN, 28));\n\t\tGroupLayout gl_panel群 = new GroupLayout(panel群);\n\t\tgl_panel群.setHorizontalGroup(\n\t\t\tgl_panel群.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(Alignment.TRAILING, gl_panel群.createSequentialGroup()\n\t\t\t\t\t.addContainerGap()\n\t\t\t\t\t.addGroup(gl_panel群.createParallelGroup(Alignment.TRAILING)\n\t\t\t\t\t\t.addComponent(btn新建聊天室, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 302, Short.MAX_VALUE)\n\t\t\t\t\t\t.addComponent(btn官方聊天室, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 302, Short.MAX_VALUE))\n\t\t\t\t\t.addContainerGap())\n\t\t);\n\t\tgl_panel群.setVerticalGroup(\n\t\t\tgl_panel群.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(gl_panel群.createSequentialGroup()\n\t\t\t\t\t.addContainerGap()\n\t\t\t\t\t.addComponent(btn官方聊天室, GroupLayout.PREFERRED_SIZE, 89, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(btn新建聊天室, GroupLayout.PREFERRED_SIZE, 76, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addContainerGap(132, Short.MAX_VALUE))\n\t\t);\n\t\tpanel群.setLayout(gl_panel群);\n\t\t\n\t\tpanel最近 = new JPanel();\n\t\ttabbedPane.addTab(\"\\u6700\\u8FD1\", new ImageIcon(MainFrame.class.getResource(\"/client/img/friend_history.png\")), panel最近, null);\n\t\tpanel设置面板.setLayout(null);\n\t\t\n\t\tlbl设置 = new JLabel(\"\");\n\t\tlbl设置.setIcon(new ImageIcon(MainFrame.class.getResource(\"/client/img/button/QQ_settings_1.png\")));\n\t\tlbl设置.setBounds(6, 6, 64, 64);\n\t\tpanel设置面板.add(lbl设置);\n\t\tpanel用户信息.setLayout(null);\n\t\t\n\t\tlbl头像 = new JLabel(\"\");\n\t\tlbl头像.setIcon(new ImageIcon(MainFrame.class.getResource(\"/client/img/headImage/head_boy_01_64.jpg\")));\n\t\tlbl头像.setBounds(15, 15, 64, 64);\n\t\tpanel用户信息.add(lbl头像);\n\t\t\n\t\tcomboBox状态 = new JComboBox();\n\t\tcomboBox状态.setBounds(91, 15, 58, 28);\n\t\tpanel用户信息.add(comboBox状态);\n\t\t\n\t\tlbl用户名 = new JLabel(\"\\u9A6C\\u5316\\u817E\");\n\t\tlbl用户名.setFont(new Font(\"黑体\", Font.BOLD, 18));\n\t\tlbl用户名.setBounds(159, 18, 90, 25);\n\t\tpanel用户信息.add(lbl用户名);\n\t\t\n\t\tlbl个性签名 = new JLabel(\"\\u5404\\u4F4D\\u817E\\u8BAF\\u7F51\\u53CB\\u597D\\uFF0CQQ2013\\u5373\\u5C06\\u516C\\u6D4B\\u4E86\");\n\t\tlbl个性签名.setBounds(91, 55, 210, 18);\n\t\tpanel用户信息.add(lbl个性签名);\n\t\tgetContentPane().setLayout(groupLayout);\n\t}\n\t\n\tprivate static void addPopup(Component component, final JPopupMenu popup) {\n\t\tcomponent.addMouseListener(new MouseAdapter() {\n\t\t\tpublic void mousePressed(MouseEvent e) {\n\t\t\t\tif (e.isPopupTrigger()) {\n\t\t\t\t\tshowMenu(e);\n\t\t\t\t}\n\t\t\t}\n\t\t\tpublic void mouseReleased(MouseEvent e) {\n\t\t\t\tif (e.isPopupTrigger()) {\n\t\t\t\t\tshowMenu(e);\n\t\t\t\t}\n\t\t\t}\n\t\t\tprivate void showMenu(MouseEvent e) {\n\t\t\t\tpopup.show(e.getComponent(), e.getX(), e.getY());\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t * 开始聊天\n\t */\n\tpublic void startChat(ActionEvent e)\n\t{\n\t}\n\t/**\n\t * 获取好友资料\n\t * @param e\n\t */\n\tpublic void getFriendInfo(ActionEvent e)\n\t{\n\t\t\n\t}\n\t/**\n\t * 发送文件\n\t * @param e\n\t */\n\tpublic void sendFile(ActionEvent e)\n\t{\n\t\t\n\t}\n\t/**\n\t * 删除好友\n\t * @param e\n\t */\n\tpublic void deleteFriend(ActionEvent e)\n\t{\n\t\t\n\t}\n\t/**\n\t * 进入聊天室\n\t */\n\tpublic void gotoChatRoom()\n\t{}\n\t\n\t/**\n\t * 新建聊天室\n\t */\n\tpublic void buildNewChatRoom()\n\t{\n\t\t\n\t}\n}\n/*TreePath path =tree.getSelectionPath();\nif (path.getPathCount()>1) //选择的不是根节点\n{ \n\tSystem.out.println(path);\n\tDefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();  \n\tDefaultTreeModel treeModel= (DefaultTreeModel) tree.getModel();\n\ttreeModel.removeNodeFromParent(node);\n} */ "
  },
  {
    "path": "src/client/frame/MyPanel.java",
    "content": "﻿package client.frame;\n\nimport java.awt.Graphics;\nimport java.awt.Image;\nimport javax.swing.JPanel;\nimport com.MyTools;\n\npublic class MyPanel extends JPanel\n{\n\tprivate Image image=null;\n\tpublic MyPanel(String imagePath)\n\t{\n\t\tthis.setOpaque(false);\n\t\timage=MyTools.getIcon(imagePath).getImage();\n\t}\n\t@Override\n\tpublic void paintComponent(Graphics g)\n\t{\n\t\tsuper.paintComponent(g);\n\t\tg.drawImage(image, 0, 0, null);\n\t}\n}\n"
  },
  {
    "path": "src/client/frame/PublicMessageFrame.java",
    "content": "package client.frame;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\n\nimport javax.swing.JButton;\nimport javax.swing.JDialog;\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextArea;\nimport javax.swing.Timer;\nimport javax.swing.border.EmptyBorder;\nimport javax.swing.ImageIcon;\n\nimport client.common.MyLabel;\nimport client.control.Chat;\nimport javax.swing.JScrollPane;\n\npublic class PublicMessageFrame extends JDialog\n{\n\tprivate JPanel contentPane;\n\tpublic JTextArea textArea公告;\n\tpublic JLabel lbl关闭;\n\tprivate JLabel lbl最小化;\n\tpublic JButton btn打开 ;\n\tpublic Chat chat=null;\n\tprivate JScrollPane scrollPane;\n\t/**\n\t * Launch the application.\n\t */\n\tpublic static void main(String[] args)\n\t{\n\t\tnew PublicMessageFrame(\"您有未读消息\",\"大家好，这里是腾讯公司！仿盛大发撒发的发生的发\",null);\n\t}\n\t\n\t/**\n\t * @wbp.parser.constructor\n\t */\n\tpublic PublicMessageFrame(String title,String publicMessage)\n\t{\n\t\tinit(title, publicMessage);\n\t}\n\t/**\n\t * Create the frame.\n\t */\n\tpublic PublicMessageFrame(String title,String publicMessage,Chat chat)\n\t{\n\t\tthis.chat=chat;\n\t\tinit(title, publicMessage);\n\t}\n\tpublic void init(String title,String publicMessage)\n\t{\n\t\tsetUndecorated(true);\n\t\tsetDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);\n\t\tsetBounds(100, 100, 352, 267);\n\t\tcontentPane = new MyPanel(\"../img/QQ2011_Login.png\");\n\t\tcontentPane.setBorder(new EmptyBorder(5, 5, 5, 5));\n\t\tsetContentPane(contentPane);\n\t\tcontentPane.setLayout(null);\n\t\t\n\t\tJLabel lbl标题 = new JLabel(title);\n\t\tlbl标题.setFont(new Font(\"宋体\", Font.BOLD, 16));\n\t\tlbl标题.setBounds(15, 5, 237, 21);\n\t\tcontentPane.add(lbl标题);\n\t\t\n\t\tJButton btn关闭 = new JButton(\"\\u5173\\u95ED(C)\");\n\t\tbtn关闭.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e) \n\t\t\t{\n\t\t\t\tdispose();\n\t\t\t}\n\t\t});\n\t\tbtn关闭.setBounds(247, 234, 83, 27);\n\t\tcontentPane.add(btn关闭);\n\t\t\n\t\tscrollPane = new JScrollPane();\n\t\tscrollPane.setBounds(1, 107, 345, 126);\n\t\tcontentPane.add(scrollPane);\n\t\t\n\t\ttextArea公告 = new JTextArea();\n\t\tscrollPane.setViewportView(textArea公告);\n\t\ttextArea公告.setLineWrap(true);\n\t\ttextArea公告.setFont(new Font(\"微软雅黑\", Font.BOLD, 18));\n\t\ttextArea公告.setBackground(new Color(255, 250, 250));\n\t\ttextArea公告.setEditable(false);\n\t\ttextArea公告.setText(publicMessage);\n\t\t\n\t\tlbl关闭 = new JLabel(\"\");\n\t\tlbl关闭.setIcon(new ImageIcon(PublicMessageFrame.class.getResource(\"/client/img/button/login_exit_1.png\")));\n\t\tlbl关闭.setBounds(312, 0, 38, 18);\n\t\tcontentPane.add(lbl关闭);\n\t\t\n\t\tlbl最小化 = new JLabel(\"\");\n\t\tlbl最小化.setIcon(new ImageIcon(PublicMessageFrame.class.getResource(\"/client/img/button/login_minsize_1.png\")));\n\t\tlbl最小化.setBounds(282, 0, 29, 18);\n\t\tcontentPane.add(lbl最小化);\n\t\t\n\t\tbtn打开 = new JButton(\"\\u6253\\u5F00\");\n\t\tbtn打开.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e)\n\t\t\t{\n\t\t\t\tshowChat();\n\t\t\t}\n\t\t});\n\t\tbtn打开.setBounds(165, 234, 83, 27);\n\t\tcontentPane.add(btn打开);\n\t\t\n\t\taddEvent();\n\t\tshowFrame();\n\t}\n\t\n\t/**\n\t * 添加事件\n\t */\n\tpublic void addEvent()\n\t{\n\t\tnew MyLabel(lbl最小化, \"../img/button/login_minsize\", \"png\").addEvent();\n\t\tnew MyLabel(lbl关闭, \"../img/button/login_exit\", \"png\").addEvent();\n\t\tlbl关闭.addMouseListener(new MouseAdapter()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void mouseClicked(MouseEvent e)\n\t\t\t{\n\t\t\t\tdispose();\n\t\t\t}\n\t\t});\n\t}\n\t/**\n\t * 显示窗体\n\t */\n\tpublic void showFrame()\n\t{\n\t\tthis.setAlwaysOnTop(true);\n\t\tif(chat==null)\n\t\t\tbtn打开.setVisible(false);\n\t\tint width=350;\n\t\tint height=266;\n\t\tDimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();\n\t\tsetBounds(screenSize.width-width-3,screenSize.height,width,height);\n\t\tsetVisible(true);\n\t\tTimer timer=new Timer(10, new ActionListener()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void actionPerformed(ActionEvent e)\n\t\t\t{\n\t\t\t\tsetLocation(getLocation().x, getLocation().y-10);\n\t\t\t}\n\t\t});\n\t\ttimer.start();\n\t\twhile(true)\n\t\t{\n\t\t\t// 25表示任务栏的高度，好奇怪，有的电脑注释掉下面的输出语句就会出现弹窗不停止的奇怪现象\n\t\t\tSystem.out.println(\"当前高度：\"+getLocation().y+\"，屏幕高度：\"+screenSize.height);\n\t\t\tif(getLocation().y+height<screenSize.height-25)\n\t\t\t{\n\t\t\t\ttimer.stop();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t * 显示聊天窗体\n\t */\n\tpublic void showChat()\n\t{\n\t\tif(chat!=null)\n\t\t{\n\t\t\tchat.setVisible(true);\n\t\t\tthis.dispose();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/client/frame/QunChatFrame.java",
    "content": "﻿package client.frame;\n\nimport java.awt.BorderLayout;\nimport java.awt.EventQueue;\n\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\nimport javax.swing.border.EmptyBorder;\nimport javax.swing.GroupLayout;\nimport javax.swing.GroupLayout.Alignment;\nimport java.awt.Color;\nimport javax.swing.border.EtchedBorder;\nimport javax.swing.UIManager;\nimport javax.swing.border.CompoundBorder;\nimport javax.swing.border.BevelBorder;\nimport javax.swing.border.LineBorder;\nimport javax.swing.border.TitledBorder;\nimport javax.swing.JTextArea;\nimport javax.swing.JTree;\nimport javax.swing.JScrollPane;\nimport javax.swing.LayoutStyle.ComponentPlacement;\nimport javax.swing.JTextPane;\nimport javax.swing.JButton;\nimport java.awt.Font;\nimport javax.swing.JLabel;\nimport javax.swing.ImageIcon;\n\npublic class QunChatFrame extends JFrame\n{\n\n\tprivate JPanel contentPane;\n\tpublic JTree tree;\n\tpublic JButton btn发送;\n\tpublic JButton btn关闭;\n\tpublic JTextPane textPane发送;\n\tpublic JTextPane textPane接收框;\n\tpublic JTextArea textArea群公告;\n\t/**\n\t * Launch the application.\n\t */\n\tpublic static void main(String[] args)\n\t{\n\t\tEventQueue.invokeLater(new Runnable()\n\t\t{\n\t\t\tpublic void run()\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tQunChatFrame frame = new QunChatFrame();\n\t\t\t\t\tframe.setVisible(true);\n\t\t\t\t}\n\t\t\t\tcatch (Exception e)\n\t\t\t\t{\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Create the frame.\n\t */\n\tpublic QunChatFrame()\n\t{\n\t\tsetTitle(\"MyQQ\\u5B98\\u65B9\\u804A\\u5929\\u5BA4\");\n\t\tsetDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);\n\t\tsetBounds(100, 100, 712, 576);\n\t\tcontentPane = new JPanel();\n\t\tcontentPane.setBackground(new Color(0, 153, 255));\n\t\tcontentPane.setBorder(new EmptyBorder(5, 5, 5, 5));\n\t\tsetContentPane(contentPane);\n\t\t\n\t\tJPanel panel右边 = new JPanel();\n\t\t\n\t\tJPanel panel左边 = new JPanel();\n\t\tpanel左边.setBackground(new Color(204, 255, 204));\n\t\tGroupLayout gl_contentPane = new GroupLayout(contentPane);\n\t\tgl_contentPane.setHorizontalGroup(\n\t\t\tgl_contentPane.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(Alignment.TRAILING, gl_contentPane.createSequentialGroup()\n\t\t\t\t\t.addComponent(panel左边, GroupLayout.DEFAULT_SIZE, 417, Short.MAX_VALUE)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(panel右边, GroupLayout.PREFERRED_SIZE, 203, GroupLayout.PREFERRED_SIZE))\n\t\t);\n\t\tgl_contentPane.setVerticalGroup(\n\t\t\tgl_contentPane.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addComponent(panel右边, GroupLayout.DEFAULT_SIZE, 479, Short.MAX_VALUE)\n\t\t\t\t.addComponent(panel左边, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 493, Short.MAX_VALUE)\n\t\t);\n\t\t\n\t\tJPanel panel顶部 = new JPanel();\n\t\tpanel顶部.setBackground(new Color(0, 153, 255));\n\t\t\n\t\tJPanel panel中间 = new JPanel();\n\t\t\n\t\tJPanel panel底部 = new JPanel();\n\t\tpanel底部.setBackground(new Color(204, 255, 255));\n\t\tGroupLayout gl_panel左边 = new GroupLayout(panel左边);\n\t\tgl_panel左边.setHorizontalGroup(\n\t\t\tgl_panel左边.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addComponent(panel底部, GroupLayout.PREFERRED_SIZE, 476, Short.MAX_VALUE)\n\t\t\t\t.addComponent(panel顶部, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 476, Short.MAX_VALUE)\n\t\t\t\t.addComponent(panel中间, GroupLayout.DEFAULT_SIZE, 476, Short.MAX_VALUE)\n\t\t);\n\t\tgl_panel左边.setVerticalGroup(\n\t\t\tgl_panel左边.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(gl_panel左边.createSequentialGroup()\n\t\t\t\t\t.addComponent(panel顶部, GroupLayout.PREFERRED_SIZE, 83, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(panel中间, GroupLayout.DEFAULT_SIZE, 233, Short.MAX_VALUE)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(panel底部, GroupLayout.PREFERRED_SIZE, 196, GroupLayout.PREFERRED_SIZE))\n\t\t);\n\t\tpanel顶部.setLayout(null);\n\t\t\n\t\tJLabel lbl头像 = new JLabel(\"\");\n\t\tlbl头像.setIcon(new ImageIcon(QunChatFrame.class.getResource(\"/client/img/QQ_64.png\")));\n\t\tlbl头像.setBounds(6, 6, 64, 64);\n\t\tpanel顶部.add(lbl头像);\n\t\t\n\t\tJLabel lbl视频 = new JLabel(\"\");\n\t\tlbl视频.setIcon(new ImageIcon(QunChatFrame.class.getResource(\"/client/img/chat/fun_video_54.png\")));\n\t\tlbl视频.setBounds(82, 16, 54, 54);\n\t\tpanel顶部.add(lbl视频);\n\t\t\n\t\tJLabel lbl语音 = new JLabel(\"\");\n\t\tlbl语音.setIcon(new ImageIcon(QunChatFrame.class.getResource(\"/client/img/chat/fun_voice_54.png\")));\n\t\tlbl语音.setBounds(138, 16, 54, 54);\n\t\tpanel顶部.add(lbl语音);\n\t\t\n\t\tJLabel lbl发送文件 = new JLabel(\"\");\n\t\tlbl发送文件.setIcon(new ImageIcon(QunChatFrame.class.getResource(\"/client/img/chat/fun_sendfile_54.png\")));\n\t\tlbl发送文件.setBounds(193, 16, 54, 54);\n\t\tpanel顶部.add(lbl发送文件);\n\t\tpanel中间.setLayout(new BorderLayout(0, 0));\n\t\t\n\t\ttextPane接收框 = new JTextPane();\n\t\tpanel中间.add(textPane接收框);\n\t\t\n\t\ttextPane发送 = new JTextPane();\n\t\t\n\t\tbtn发送 = new JButton(\"\\u53D1\\u9001\");\n\t\tbtn发送.setFont(new Font(\"Microsoft YaHei UI\", Font.PLAIN, 18));\n\t\t\n\t\tbtn关闭 = new JButton(\"\\u5173\\u95ED\");\n\t\tbtn关闭.setFont(new Font(\"Microsoft YaHei UI\", Font.PLAIN, 18));\n\t\t\n\t\tJLabel lbl文字 = new JLabel(\"\");\n\t\tlbl文字.setIcon(new ImageIcon(QunChatFrame.class.getResource(\"/client/img/chat/fun_font_32.png\")));\n\t\t\n\t\tJLabel lbl表情 = new JLabel(\"\");\n\t\tlbl表情.setIcon(new ImageIcon(QunChatFrame.class.getResource(\"/client/img/chat/fun_face_32.png\")));\n\t\t\n\t\tJLabel lbl音乐 = new JLabel(\"\");\n\t\tlbl音乐.setIcon(new ImageIcon(QunChatFrame.class.getResource(\"/client/img/chat/fun_music_32.png\")));\n\t\t\n\t\tJLabel lbl图片 = new JLabel(\"\");\n\t\tlbl图片.setIcon(new ImageIcon(QunChatFrame.class.getResource(\"/client/img/chat/fun_picture_32.png\")));\n\t\t\n\t\tJLabel lbl截图 = new JLabel(\"\");\n\t\tlbl截图.setIcon(new ImageIcon(QunChatFrame.class.getResource(\"/client/img/chat/fun_snap_32.png\")));\n\t\tGroupLayout gl_panel底部 = new GroupLayout(panel底部);\n\t\tgl_panel底部.setHorizontalGroup(\n\t\t\tgl_panel底部.createParallelGroup(Alignment.TRAILING)\n\t\t\t\t.addGroup(gl_panel底部.createSequentialGroup()\n\t\t\t\t\t.addContainerGap(285, Short.MAX_VALUE)\n\t\t\t\t\t.addComponent(btn关闭, GroupLayout.PREFERRED_SIZE, 83, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(btn发送, GroupLayout.PREFERRED_SIZE, 86, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addGap(15))\n\t\t\t\t.addComponent(textPane发送, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 476, Short.MAX_VALUE)\n\t\t\t\t.addGroup(Alignment.LEADING, gl_panel底部.createSequentialGroup()\n\t\t\t\t\t.addContainerGap()\n\t\t\t\t\t.addComponent(lbl文字)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(lbl表情)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(lbl音乐)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.UNRELATED)\n\t\t\t\t\t.addComponent(lbl图片)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(lbl截图)\n\t\t\t\t\t.addContainerGap(258, Short.MAX_VALUE))\n\t\t);\n\t\tgl_panel底部.setVerticalGroup(\n\t\t\tgl_panel底部.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(Alignment.TRAILING, gl_panel底部.createSequentialGroup()\n\t\t\t\t\t.addContainerGap(24, Short.MAX_VALUE)\n\t\t\t\t\t.addGroup(gl_panel底部.createParallelGroup(Alignment.LEADING)\n\t\t\t\t\t\t.addComponent(lbl文字)\n\t\t\t\t\t\t.addComponent(lbl表情)\n\t\t\t\t\t\t.addComponent(lbl音乐)\n\t\t\t\t\t\t.addComponent(lbl图片)\n\t\t\t\t\t\t.addComponent(lbl截图))\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(textPane发送, GroupLayout.PREFERRED_SIZE, 88, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addGap(18)\n\t\t\t\t\t.addGroup(gl_panel底部.createParallelGroup(Alignment.LEADING, false)\n\t\t\t\t\t\t.addComponent(btn发送, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)\n\t\t\t\t\t\t.addComponent(btn关闭, GroupLayout.PREFERRED_SIZE, 39, GroupLayout.PREFERRED_SIZE))\n\t\t\t\t\t.addContainerGap())\n\t\t);\n\t\tpanel底部.setLayout(gl_panel底部);\n\t\tpanel左边.setLayout(gl_panel左边);\n\t\t\n\t\tJPanel panel公告 = new JPanel();\n\t\tpanel公告.setBackground(new Color(0, 153, 255));\n\t\tpanel公告.setBorder(new TitledBorder(null, \"\\u7FA4\\u516C\\u544A\", TitledBorder.LEADING, TitledBorder.ABOVE_TOP, null, Color.RED));\n\t\t\n\t\tJScrollPane scrollPane = new JScrollPane();\n\t\tpanel公告.setLayout(new BorderLayout(0, 0));\n\t\t\n\t\ttextArea群公告 = new JTextArea();\n\t\ttextArea群公告.setLineWrap(true);\n\t\ttextArea群公告.setForeground(new Color(255, 0, 0));\n\t\ttextArea群公告.setText(\"\\u6682\\u65E0\\u4EFB\\u4F55\\u5B98\\u65B9\\u516C\\u544A\\uFF01\");\n\t\ttextArea群公告.setFont(new Font(\"微软雅黑\", Font.BOLD, 18));\n\t\ttextArea群公告.setBackground(new Color(255, 204, 0));\n\t\ttextArea群公告.setEnabled(false);\n\t\tpanel公告.add(textArea群公告, BorderLayout.CENTER);\n\t\tGroupLayout gl_panel右边 = new GroupLayout(panel右边);\n\t\tgl_panel右边.setHorizontalGroup(\n\t\t\tgl_panel右边.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(gl_panel右边.createSequentialGroup()\n\t\t\t\t\t.addGap(0)\n\t\t\t\t\t.addGroup(gl_panel右边.createParallelGroup(Alignment.LEADING)\n\t\t\t\t\t\t.addComponent(panel公告, GroupLayout.PREFERRED_SIZE, 203, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t\t.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 203, Short.MAX_VALUE))\n\t\t\t\t\t.addGap(0))\n\t\t);\n\t\tgl_panel右边.setVerticalGroup(\n\t\t\tgl_panel右边.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(gl_panel右边.createSequentialGroup()\n\t\t\t\t\t.addComponent(panel公告, GroupLayout.PREFERRED_SIZE, 170, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE))\n\t\t);\n\t\t\n\t\ttree = new JTree();\n\t\ttree.setRootVisible(false);\n\t\tscrollPane.setViewportView(tree);\n\t\tpanel右边.setLayout(gl_panel右边);\n\t\tcontentPane.setLayout(gl_contentPane);\n\t}\n}\n"
  },
  {
    "path": "src/client/frame/RegisterFrame.java",
    "content": "﻿package client.frame;\n\nimport java.awt.Dimension;\nimport java.awt.EventQueue;\nimport java.awt.Image;\nimport java.awt.Toolkit;\nimport java.io.File;\nimport java.io.IOException;\n\nimport javax.imageio.ImageIO;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPasswordField;\nimport javax.swing.JRadioButton;\nimport javax.swing.JTextField;\nimport javax.swing.border.EmptyBorder;\nimport javax.swing.JToggleButton;\nimport javax.swing.JComboBox;\nimport javax.swing.DefaultComboBoxModel;\nimport java.awt.Font;\nimport javax.swing.SwingConstants;\nimport javax.swing.JTextArea;\nimport javax.swing.JScrollPane;\nimport javax.swing.border.CompoundBorder;\n\nimport client.control.Login;\nimport client.control.Register;\n\nimport java.awt.event.ActionListener;\nimport java.awt.event.ActionEvent;\nimport java.awt.Color;\nimport java.awt.event.WindowAdapter;\nimport java.awt.event.WindowEvent;\n\npublic class RegisterFrame extends JFrame {\n\n\tpublic JPanel contentPane;\n\tpublic JTextField txtName;\n\tpublic JPasswordField pwd;\n\tpublic JPasswordField pwdRe;\n\tpublic JTextField txtEmail;\n\tpublic JTextField txtbirthday;\n\tpublic JComboBox comGender;\n\tpublic JTextArea txtSignat;//签名\n\tpublic JComboBox comboBoxHeadImage;//头像\n\tpublic JButton btnRegister;\n\t/**\n\t * Create the frame.\n\t */\n\tpublic RegisterFrame()\n\t{\n\t\taddWindowListener(new WindowAdapter() {\n\t\t\t@Override\n\t\t\tpublic void windowClosing(WindowEvent e) \n\t\t\t{\n\t\t\t\tbeforeClose();\n\t\t\t}\n\t\t});\n\t\tsetIconImage(Toolkit.getDefaultToolkit().getImage(RegisterFrame.class.getResource(\"/client/img/QQ_64.png\")));\n\t\tsetTitle(\"QQ2013\\u6CE8\\u518C\");\n\t\tsetResizable(false);\n\t\tsetDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);\n\t\tthis.setSize(592, 553);\n\t\t\n\t\tcontentPane = new MyPanel(\"../img/registerBGimg.jpg\");\n\t\tcontentPane.setBorder(new EmptyBorder(5, 5, 5, 5));\n\t\tsetContentPane(contentPane);\n\t\tcontentPane.setLayout(null);\n\t\t\n\t\tJLabel lbUserName = new JLabel(\"\\u7528\\u6237\\u540D\");\n\t\tlbUserName.setFont(new Font(\"微软雅黑\", Font.PLAIN, 18));\n\t\tlbUserName.setBounds(38, 45, 54, 24);\n\t\tcontentPane.add(lbUserName);\n\t\t\n\t\tJLabel lbPwd = new JLabel(\"\\u5BC6\\u7801\");\n\t\tlbPwd.setFont(new Font(\"微软雅黑\", Font.PLAIN, 18));\n\t\tlbPwd.setBounds(38, 96, 54, 30);\n\t\tcontentPane.add(lbPwd);\n\t\t\n\t\tJLabel lbPwdre = new JLabel(\"\\u91CD\\u590D\\u5BC6\\u7801\");\n\t\tlbPwdre.setFont(new Font(\"微软雅黑\", Font.PLAIN, 18));\n\t\tlbPwdre.setBounds(22, 138, 79, 35);\n\t\tcontentPane.add(lbPwdre);\n\t\t\n\t\tJLabel lbEmail = new JLabel(\"E-mail\");\n\t\tlbEmail.setFont(new Font(\"微软雅黑\", Font.PLAIN, 18));\n\t\tlbEmail.setBounds(33, 234, 59, 28);\n\t\tcontentPane.add(lbEmail);\n\t\t\n\t\tJLabel lbBirthday = new JLabel(\"\\u751F\\u65E5\");\n\t\tlbBirthday.setFont(new Font(\"微软雅黑\", Font.PLAIN, 18));\n\t\tlbBirthday.setBounds(38, 285, 46, 24);\n\t\tcontentPane.add(lbBirthday);\n\t\t\n\t\tJLabel lbSignature = new JLabel(\"\\u4E2A\\u6027\\u7B7E\\u540D\");\n\t\tlbSignature.setFont(new Font(\"微软雅黑\", Font.PLAIN, 18));\n\t\tlbSignature.setBounds(22, 332, 79, 28);\n\t\tcontentPane.add(lbSignature);\n\t\t\n\t\tbtnRegister = new JButton(\"\\u514D\\u8D39\\u6CE8\\u518C\");\n\t\tbtnRegister.setForeground(new Color(255, 255, 255));\n\t\tbtnRegister.setBackground(new Color(0, 100, 0));\n\t\tbtnRegister.setFont(new Font(\"微软雅黑\", Font.BOLD, 28));\n\t\tbtnRegister.setBounds(57, 431, 161, 60);\n\t\tcontentPane.add(btnRegister);\n\t\t\n\t\tJButton btnCancel = new JButton(\"\\u53D6\\u6D88\");\n\t\tbtnCancel.setForeground(new Color(255, 250, 250));\n\t\tbtnCancel.setBackground(new Color(106, 90, 205));\n\t\tbtnCancel.setFont(new Font(\"微软雅黑\", Font.BOLD, 28));\n\t\tbtnCancel.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e) \n\t\t\t{\n\t\t\t\tcancle();\n\t\t\t}\n\t\t});\n\t\tbtnCancel.setBounds(248, 431, 100, 60);\n\t\tcontentPane.add(btnCancel);\n\t\t\n\t\ttxtName = new JTextField();\n\t\ttxtName.setBounds(111, 40, 217, 35);\n\t\tcontentPane.add(txtName);\n\t\ttxtName.setColumns(10);\n\t\t\n\t\tpwd = new JPasswordField();\n\t\tpwd.setBounds(111, 92, 217, 35);\n\t\tcontentPane.add(pwd);\n\t\t\n\t\tpwdRe = new JPasswordField();\n\t\tpwdRe.setBounds(113, 138, 215, 35);\n\t\tcontentPane.add(pwdRe);\n\t\t\n\t\ttxtEmail = new JTextField();\n\t\ttxtEmail.setColumns(10);\n\t\ttxtEmail.setBounds(111, 231, 217, 35);\n\t\tcontentPane.add(txtEmail);\n\t\t\n\t\tcomGender = new JComboBox();\n\t\tcomGender.setModel(new DefaultComboBoxModel(new String[] {\"男\", \"女\"}));\n\t\tcomGender.setBounds(111, 185, 59, 35);\n\t\tcontentPane.add(comGender);\n\t\t\n\t\tJLabel lbGender = new JLabel(\"\\u6027\\u522B\");\n\t\tlbGender.setFont(new Font(\"微软雅黑\", Font.PLAIN, 18));\n\t\tlbGender.setBounds(38, 190, 46, 24);\n\t\tcontentPane.add(lbGender);\n\t\t\n\t\ttxtSignat = new JTextArea();\n\t\ttxtSignat.setBounds(111, 328, 217, 75);\n\t\tcontentPane.add(txtSignat);\n\t\t\n\t\ttxtbirthday = new JTextField();\n\t\ttxtbirthday.setBounds(111, 281, 217, 35);\n\t\tcontentPane.add(txtbirthday);\n\t\ttxtbirthday.setColumns(10);\n\t\t\n\t\tcomboBoxHeadImage = new JComboBox();\n\t\tcomboBoxHeadImage.setBounds(375, 193, 138, 117);\n\t\tcontentPane.add(comboBoxHeadImage);\n\t\t\n\t\tJLabel lblHead = new JLabel(\"\\u5934\\u50CF\\u9009\\u62E9\\uFF1A\");\n\t\tlblHead.setFont(new Font(\"微软雅黑\", Font.PLAIN, 18));\n\t\tlblHead.setBounds(375, 139, 100, 32);\n\t\tcontentPane.add(lblHead);\n\t}\n\t\n\t/**\n\t * 在窗体关闭之前需要做的事\n\t */\n\tpublic void beforeClose()\n\t{}\n\t/**\n\t * 取消按钮事件\n\t */\n\tpublic void cancle()\n\t{}\n}\n"
  },
  {
    "path": "src/client/frame/ScreenFram.java",
    "content": "﻿package client.frame;\n\nimport java.awt.AWTException;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.GraphicsDevice;\nimport java.awt.GraphicsEnvironment;\nimport java.awt.Rectangle;\nimport java.awt.Robot;\nimport java.awt.Toolkit;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseMotionAdapter;\nimport java.awt.image.BufferedImage;\nimport java.awt.image.RescaleOp;\nimport java.io.File;\nimport java.io.IOException;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\n\nimport javax.imageio.ImageIO;\nimport javax.swing.JFrame;\nimport javax.swing.filechooser.FileSystemView;\n\n/**\n * java截屏 运行后将当前屏幕截取，并最大化显示。 拖拽鼠标，选择自己需要的部分。 按Esc键保存图片到桌面，并退出程序。\n * 点击右上角（没有可见的按钮），退出程序，不保存图片。\n * \n * @author JinCeon\n */\npublic class ScreenFram\n{\n\tpublic static void main()\n\t{\n\t\t// 全屏运行\n\t\tRectD rd = new RectD();\n\t\tGraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()\n\t\t\t\t.getDefaultScreenDevice();\n\t\tgd.setFullScreenWindow(rd);\n\t\tSystem.out.println(\"main方法中的截图名：\"+ rd.name);\n\t\t//return rd.name;\n\t}\n}\n\nclass RectD extends JFrame\n{\n\tprivate static final long serialVersionUID = 1L;\n\tint orgx, orgy, endx, endy;\n\tDimension d = Toolkit.getDefaultToolkit().getScreenSize();\n\tBufferedImage image;\n\tBufferedImage tempImage;\n\tBufferedImage saveImage;\n\tGraphics g;\n\tpublic String name;\n\n\t\n\n\t@Override\n\tpublic void paint(Graphics g)\n\t{\n\t\tRescaleOp ro = new RescaleOp(0.8f, 0, null);\n\t\ttempImage = ro.filter(image, null);\n\t\tg.drawImage(tempImage, 0, 0, this);\n\t}\n\n\tpublic RectD()\n\t{\n\t\tsnapshot();\n\t\tsetVisible(true);\n\t\t\n\t\t\n\t\tsetDefaultCloseOperation(EXIT_ON_CLOSE);\n\t\t\n\t\tthis.addMouseMotionListener(new MouseMotionAdapter()\n\t\t{\n\t\t\tpublic void mouseDragged(MouseEvent e)\n\t\t\t{\n\t\t\t\tendx = e.getX();\n\t\t\t\tendy = e.getY();\n\t\t\t\tg = getGraphics();\n\t\t\t\tg.drawImage(tempImage, 0, 0, RectD.this);\n\t\t\t\tint x = Math.min(orgx, endx);\n\t\t\t\tint y = Math.min(orgy, endy);\n\t\t\t\tint width = Math.abs(endx - orgx) + 1;\n\t\t\t\tint height = Math.abs(endy - orgy) + 1;\n\t\t\t\t// 加上1，防止width或height为0\n\t\t\t\tg.setColor(Color.BLUE);\n\t\t\t\tg.drawRect(x - 1, y - 1, width + 1, height + 1);\n\t\t\t\t// 减1，加1都是为了防止图片将矩形框覆盖掉\n\t\t\t\tsaveImage = image.getSubimage(x, y, width, height);\n\t\t\t\tg.drawImage(saveImage, x, y, RectD.this);\n\t\t\t}\n\t\t});\n\t\t\n\t\t\n\t\t\n\t\tthis.addMouseListener(new MouseAdapter()\n\t\t{\n\t\t\tpublic void mousePressed(MouseEvent e)\n\t\t\t{\n\t\t\t\torgx = e.getX();\n\t\t\t\torgy = e.getY();\n\t\t\t}\n\n\t\t\tpublic void mouseReleased(MouseEvent e)\n\t\t\t{\n\t\t\t\tsaveToFile();\n\t\t\t\tdispose();\n\t\t\t}\n\t\t\t\n\t\t});\n\n\t}\n\n\tpublic void saveToFile()\n\t{\n\t\tSimpleDateFormat sdf = new SimpleDateFormat(\"yyyymmddHHmmss\");\n\t\t name =\"snap\";\n\t\t //sdf.format(new Date());\n//\t\tsetName(sdf.format(new Date()));\n\t\tString path = \"./screenCut/\";\n\t\tString format = \"jpg\";\n\t\tFile f = new File(path, name + \".\" + format);\n\t\ttry\n\t\t{\n\t\t\tImageIO.write(saveImage, format, f);\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\tpublic void snapshot()\n\t{\n\t\ttry\n\t\t{\n\t\t\tRobot robot = new Robot();\n\t\t\tDimension d = Toolkit.getDefaultToolkit().getScreenSize();\n\t\t\timage = robot.createScreenCapture(new Rectangle(0, 0, d.width,\n\t\t\t\t\td.height));\n\t\t}\n\t\tcatch (AWTException e)\n\t\t{\n\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/client/frame/SendFileFrame.java",
    "content": "﻿package client.frame;\n\nimport java.awt.Color;\nimport java.awt.EventQueue;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.IOException;\nimport java.net.ServerSocket;\nimport java.net.Socket;\n\nimport javax.swing.JButton;\nimport javax.swing.JFileChooser;\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JOptionPane;\nimport javax.swing.JPanel;\nimport javax.swing.JProgressBar;\nimport javax.swing.JTextField;\nimport javax.swing.border.EmptyBorder;\n\nimport client.control.RecieveThread;\nimport client.control.SendTread;\n\npublic class SendFileFrame extends JFrame\n{\n\n\tpublic JPanel contentPane;\n\tpublic JLabel lbl;\n\tpublic  JProgressBar progressBar;\n\tpublic JLabel lblProgress;\n\tpublic RecieveThread recieveThread;\n\n\t/**\n\t * Create the frame.\n\t */\n\tpublic SendFileFrame()\n\t{\n\t\t//this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n\t\tsetBounds(100, 100, 510, 196);\n\t\tcontentPane = new JPanel();\n\t\tcontentPane.setBorder(new EmptyBorder(5, 5, 5, 5));\n\t\tsetContentPane(contentPane);\n\t\tcontentPane.setLayout(null);\n\n\t\tlbl = new JLabel(\"进度条\");\n\t\tlbl.setBounds(42, 35, 74, 33);\n\t\tcontentPane.add(lbl);\n\n\t\tprogressBar = new JProgressBar();\n\t\tprogressBar.setForeground(Color.BLUE);\n\t\tprogressBar.setBounds(96, 35, 332, 33);\n\t\tcontentPane.add(progressBar);\n\n\t\tlblProgress = new JLabel(\"\");\n\t\tlblProgress.setBounds(64, 82, 386, 58);\n\t\tcontentPane.add(lblProgress);\n\t}\n\n\t/**\n\t * @param bar\n\t * @param passlen\n\t * @param sumlen\n\t * @param lbl\n\t */\n\tpublic void updateProgressBar(JProgressBar bar, long passlen, long sumlen,\n\t\t\tJLabel lbl, double passTime)\n\t{\n\t\tint percent = (int) (passlen * 100 / sumlen);\n\t\tbar.setValue(percent);\n\t\tif (lbl != null)\n\t\t{\n\t\t\tString msg = \"正在接受文件.....\" + (passlen / 1024) + \"kb\" + \"  /\"\n\t\t\t\t\t+ (sumlen / 1024) + \"kb\" + \"已接收 \"+ percent + \"%\"\n\t\t\t\t\t+ \"\\n 发射点\" + (int) ((passlen / 1024) / (passTime / 1000))\n\t\t\t\t\t+ \"Kb/s\";\n\t\t\tif (passlen == sumlen)\n\t\t\t\tmsg = \"传输完毕！\";\n\t\t\tlblProgress.setText(msg);\n\t\t}\n\t}\n\n\t/**\n\t * @param seletMode\n\t * @return \n\t */\n\tpublic String showDialog(int seletMode)\n\t{\n\t\tJFileChooser chooser = new JFileChooser();\n\t\tchooser.setFileSelectionMode(seletMode);\n\t\tchooser.setMultiSelectionEnabled(true);//璁剧疆澶氶?鏂囦欢\n\t\tint result = chooser.showOpenDialog(this);\n\t\tif (result == JFileChooser.APPROVE_OPTION)\n\t\t{\n\t\t\tString filePath = chooser.getSelectedFile().getAbsolutePath();\n\t\t\treturn filePath;\n\t\t}\n\t\treturn null;\n\t}\n}\n"
  },
  {
    "path": "src/client/socket/CC_TCP.java",
    "content": "﻿package client.socket;\n\nimport java.text.DateFormat;\nimport java.util.Date;\n\nimport client.common.MyTextPane;\nimport client.control.Chat;\n\nimport com.MyTools;\nimport com.MyTools.Flag;\nimport com.socket.TCP;\n\n/**\n * @author 刘显安\n *客户端与客户端之间的TCP连接\n */\npublic class CC_TCP extends TCP\n{\n\tChat chat=null;\n\tpublic CC_TCP(String serverIP, int serverPort,Chat chat) throws Exception\n\t{\n\t\tsuper(serverIP, serverPort);\n\t\tthis.chat=chat;\n\t}\n\n\t@Override\n\tpublic void dealWithMessage(Flag flag, String message)\n\t{\n\t\tswitch (flag)\n\t\t{\n\t\t\tcase MESSAGE:showMessage(message);break;\n\t\t\tcase SENDFILE:doStartSendFile(message);break;\n\t\t\tcase FACE:doFace(message);break;\n\t\t\tdefault:break;\n\t\t}\n\t}\n\n\t@Override\n\tpublic void dealWithExit()\n\t{\n\t}\n\tpublic void showMessage(String message)\n\t{\n\t\tchat.setReceivePaneText(false, message);\n\t}\n\tpublic void doStartSendFile(String message)\n\t{\n\t\tchat.friendGetFilePort=Integer.parseInt(message);\n\t\tSystem.out.println(\"已成功获取好友的接收文件端口:\"+message);\n\t}\n\tpublic void doFace(String message)\n\t{\n\t\tnew MyTextPane(chat.jTextPane接收框).addIcon(MyTools.getFaceByIdx(Integer.parseInt(message)), chat.friendName);\n\t}\n\t\n\t\n\n}\n"
  },
  {
    "path": "src/client/socket/CS_TCP.java",
    "content": "package client.socket;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.util.ArrayList;\n\nimport javax.swing.JFileChooser;\nimport javax.swing.JOptionPane;\n\nimport client.control.Chat;\nimport client.control.Login;\nimport client.control.Main;\nimport client.control.SendTread;\nimport client.frame.PublicMessageFrame;\nimport client.frame.SendFileFrame;\n\nimport com.MyTools;\nimport com.MyTools.Flag;\nimport com.socket.TCP;\n\n/**\n * @author 刘显安\n * 客户端与QQ服务器之间的TCP通讯\n */\npublic class CS_TCP extends TCP\n{\n\tLogin login = null;//登录窗体，从构造方法中传过来\n\tMain main=null;//主窗体\n\tpublic CS_TCP(String serverIP, int serverPort, Login login,Main main) throws Exception\n\t{\n\t\tsuper(serverIP, serverPort);\n\t\tthis.login = login;\n\t\tthis.main=main;\n\t}\n\t/**\n\t * 此构造方法仅供注册用\n\t * @param serverIP\n\t * @param serverPort\n\t * @throws Exception\n\t */\n\tpublic CS_TCP(String serverIP, int serverPort) throws Exception\n\t{\n\t\tsuper(serverIP, serverPort);\n\t}\n\n\n\t@Override\n\tpublic void dealWithMessage(Flag flag, String message)\n\t{\n\t\tSystem.out.println(\"测试\"+flag.toString()+\",\"+message);\n\t\tswitch(flag)\n\t\t{\n\t\t\tcase LOGIN:doLogin(message);break;//如果是登录\n\t\t\tcase REGISTER:doRegister(message);break;//如果是注册\n\t\t\tcase USERINFO:doUsersInfo(message);break;//如果是用户信息\n\t\t\tcase GET_FRIEND_INFO:doGetFriendInfo(message);break;//如果是服务器发来的指定好友信息\n\t\t\tcase FRIENDS_LIST:doFriendList(message);break;//接收服务器发来的刷新好友列表信息\n\t\t\tcase QUN_CHAT:doQunChat(message);break;//处理群消息\n\t\t\tcase PUBLIC_MESSAGE:doPublicMessage(message);break;//处理公告信息\n\t\t\tcase SHOW_WINDOW:doShowWindow(message);break;//处理公告信息\n\t\t\tcase UNDERLINE_MESSAGE:doUnreadMessage(message);break;//接收服务器发来的未读消息\n\t\t\tdefault:break;\n\t\t}\n\t}\n\n\t@Override\n\tpublic void dealWithExit()\n\t{\n\t}\n\n\t/**\n\t * 处理与登录相关的事情\n\t * @param message\n\t */\n\tpublic void doLogin(String message)\n\t{\n\t\t//注意一定要给Flag加toString()\n\t\tif (message.split(MyTools.SPLIT1)[0].equals(Flag.SUCCESS.toString()))// 如果登录成功\n\t\t{\n\t\t\tlogin.dispose();//销毁登录窗体\n\t\t\tmain.setCS_TCP(login.cs_TCP);\n\t\t\tmain.setVisible(true);\n\t\t\tdoUsersInfo(message.split(MyTools.SPLIT1)[1]);\n\t\t}\n\t\telse if (message.split(MyTools.SPLIT1)[0].equals(Flag.FAILED.toString()))// 如果登录失败\n\t\t{\n\t\t\tJOptionPane.showMessageDialog(null,\n\t\t\t\t\tmessage.split(MyTools.SPLIT1)[1]);//显示登录失败的原因\n\t\t}\n\t}\n\t\n\n\tpublic void doRegister(String message)\n\t{\n\t\tif(message.split(MyTools.SPLIT1)[0].equals(Flag.SUCCESS.toString()))\n\t\t\tJOptionPane.showMessageDialog(null,message.split(MyTools.SPLIT1)[1]);\n\t\telse if(message.split(MyTools.SPLIT1)[0].equals(Flag.FAILED.toString()))\n\t\t\tJOptionPane.showMessageDialog(null, message.split(MyTools.SPLIT1)[1],\"失败\",JOptionPane.ERROR_MESSAGE);\n\t}\n\t\n\t/**\n\t * 处理服务器发回来用户信息\n\t * @param message\n\t */\n\tpublic void doUsersInfo(String message)\n\t{\n\t\tString[] temp=message.split(MyTools.SPLIT2);\n\t\tString userName=temp[0];//用户名\n\t\tint userState=Integer.parseInt(temp[1]);\n\t\tString signature=temp[2];//个性签名\n\t\tString headImage=temp[3];//头像\n\t\tif(main!=null)\n\t\t{\n\t\t\tmain.lbl用户名.setText(userName);\n\t\t\tmain.comboBox状态.setSelectedIndex(userState);\n\t\t\tmain.lbl个性签名.setText(signature);\n\t\t\tmain.lbl头像.setIcon(MyTools.getIcon(\"../img/headImage/middle/\"+headImage+\"_64.jpg\"));\n\t\t}\n\t}\n\tpublic void doGetFriendInfo(String message)\n\t{\n\t\tJOptionPane.showMessageDialog(null, message);\n\t}\n\tpublic void doFriendList(String message)\n\t{\n\t\tSystem.out.println(\"客户端已接收到好友列表！\");\n\t\tSystem.out.println(message);\n\t\tString[] groupNames=message.split(MyTools.SPLIT1)[0].split(MyTools.SPLIT2);\n\t\tArrayList<String[]> friendNames=new ArrayList<String[]>();\n\t\tfor(int i=0;i<groupNames.length;i++)\n\t\t{\n\t\t\tString temp=message.split(MyTools.SPLIT1)[i+1];\n\t\t\tif(!temp.equals(\"无\") && !\"\".equals(temp))\n\t\t\t\tfriendNames.add(temp.split(MyTools.SPLIT2));\n\t\t\telse\n\t\t\t\tfriendNames.add(new String[]{});\n\t\t}\n\t\t\n\t\tmain.initjTree(groupNames, friendNames);\n\t}\n\tpublic void doQunChat(String message)\n\t{\n\t\tif(main.qunChat!=null)\n\t\t\tmain.qunChat.receiveMessage(message);\n\t\telse\n\t\t{\n\t\t\tString[] temp=message.split(MyTools.SPLIT1);\n\t\t\tnew PublicMessageFrame(\"MyQQ官方聊天室未读消息\", temp[0]+\"说(\"+temp[1]+\"):\\n\"+temp[2]);\n\t\t}\n\t\t\t\n\t}\n\t/**\n\t * 处理聊天室公告信息\n\t * @param message\n\t */\n\tpublic void doPublicMessage(String message)\n\t{\n\t\tif(main.qunChat!=null)\n\t\t\tmain.qunChat.showPublicMessage(message);\n\t\telse\n\t\t\tnew PublicMessageFrame(\"MyQQ聊天室公告\", message);\n\t}\n\t/**\n\t * 处理弹窗公告信息\n\t */\n\tpublic void doShowWindow(String message)\n\t{\n\t\tnew PublicMessageFrame(\"MyQQ系统公告\", message);\n\t\ttry\n\t\t{\n\t\t\tsun.audio.AudioPlayer.player.start(new sun.audio.AudioStream(new FileInputStream(new File(\"system.wav\"))));\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t/**\n\t * 处理未读消息\n\t * @param message\n\t */\n\tpublic void doUnreadMessage(String message)\n\t{\n\t\t//String[] temp=message.split(MyTools.SPLIT1);\n\t\tnew PublicMessageFrame(\"您有未读离线消息\", message);\n\t\tMyTools.playMsgSound();\n\t}\n}\n"
  },
  {
    "path": "src/client/socket/S_TCP.java",
    "content": "﻿package client.socket;\n\nimport java.applet.Applet;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.net.MalformedURLException;\nimport java.net.ServerSocket;\nimport java.net.Socket;\nimport java.net.URL;\nimport java.text.DateFormat;\nimport java.util.ArrayList;\nimport java.util.Date;\n\nimport javax.swing.JOptionPane;\nimport javax.xml.transform.Templates;\n\nimport client.common.MyTextPane;\nimport client.control.Chat;\nimport client.control.Main;\nimport client.control.RecieveThread;\nimport client.frame.PublicMessageFrame;\nimport client.frame.SendFileFrame;\n\nimport com.MyTools;\nimport com.MyTools.Flag;\nimport com.socket.TCP;\nimport com.socket.TCPServer;\n\npublic class S_TCP extends TCPServer\n{\n\tArrayList<Chat> chats=new ArrayList<Chat>();//存放所有的打开的聊天窗体集合\n\tMain main=null;//传过来的主窗体\n\tpublic S_TCP(int serverPort,Main main)\n\t{\n\t\tsuper(serverPort);\n\t\tthis.main=main;\n\t}\n\t/**\n\t * 处理客户端发来的各种信息\n\t * @param flag 信息标志\n\t * @param message 消息内容\n\t */\n\t@Override\n\tpublic void dealWithMessage(Flag flag,String message,TCP tcp)\n\t{\n\t\tswitch (flag)\n\t\t{\n\t\t\tcase START_CHAT:doStartChat(message,tcp);break;\n\t\t\tcase MESSAGE:showMessage(message,tcp);break;\n\t\t\tcase SENDFILE:doSendFile(message,tcp);break;\n\t\t\tcase SENDIMG: dogetImg(message ,tcp);break;\n\t\t\tcase FACE:doFace(message,tcp);break;//如果是表情\n\t\t\tdefault:break;\n\t\t}\n\t}\n\t\n\t/**\n\t * 接收图片\n\t * @param message\n\t * @param tcp\n\t */\n\tprivate void dogetImg(String message,TCP tcp)\n\t{\n\t\tChat currentChatWindoew =\n\t\tnull;\n\t\tfor(Chat chat:chats)\n\t\t{\n\t\t\tif(chat.friendName.equals(tcp.getClientName()))\n\t\t\t\tcurrentChatWindoew = chat;\n\t\t}\n\t  tcp.getImg(currentChatWindoew ,message);\n\t}\n\t\n\t\n\t/**\n\t * 处理客户端退出的相关事件\n\t * @param tcp TCP连接\n\t */\n\t@Override\n\tpublic void dealWithExit(TCP tcp)\n\t{\n\t\t\n\t}\n\t/**\n\t * 服务端启动后要做的事情，把这部分单独提取出来的目的是为了方便子类继承时重写\n\t */\n\t@Override\n\tpublic void afterServerStart()\n\t{\n\t}\n\tpublic void doStartChat(String message,TCP tcp)\n\t{\n\t\ttcp.setClientName(message);//设置对方的名字\n\t\tif(!message.equals(main.lbl用户名.getText()))\n\t\t{\n\t\t\tChat chat=new Chat(tcp,tcp.getClientName(),main.lbl用户名.getText());\n    \t\tchat.setTitle(\"与\" + tcp.getClientName()+\"(\"+tcp.getClientIP()+\")聊天中\");// 设置窗体标题\n    \t\tchats.add(chat);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tJOptionPane.showMessageDialog(null,\t\"您正在与自己聊天，MyQQ将只会打开一个聊天框！\");\n\t\t}\n\t}\n\tpublic void showMessage(String message,TCP tcp)\n\t{\n\t\tfor(Chat chat:chats)\n\t\t{\n\t\t\tif(chat.friendName.equals(tcp.getClientName()))\n\t\t\t{\n\t\t\t\tif(!chat.isVisible())\n\t\t\t\t{\n\t\t\t\t\tnew PublicMessageFrame(tcp.getClientName()+\"给您发来消息\",message,chat);\n\t\t\t\t\t//对方未打开聊天窗体时就播放声音\n\t\t\t\t\tMyTools.playMsgSound();\n\t\t\t\t}\n\t\t\t\tchat.setReceivePaneText(false, message);\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t * 处理接收文件的相关事件\n\t */\n\tpublic void doSendFile(String message,TCP tcp)\n\t{\n\t\tfor(Chat chat:chats)\n\t\t{\n\t\t\tif(chat.friendName.equals(tcp.getClientName()))\n\t\t\t{\n\t\t\t\tchat.friendGetFilePort=Integer.parseInt(message);\n\t\t\t\tSystem.out.println(\"已成功获取好友的接收文件端口:\"+message);\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t * 处理表情\n\t * @param message\n\t * @param tcp\n\t */\n\tpublic void doFace(String message,TCP tcp)\n\t{\n\t\tfor(Chat chat:chats)\n\t\t{\n\t\t\tif(chat.friendName.equals(tcp.getClientName()))\n\t\t\t{\n\t\t\t\tnew MyTextPane(chat.jTextPane接收框).addIcon(MyTools.getFaceByIdx(Integer.parseInt(message)), chat.friendName);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/client/socket/UDPChat.java",
    "content": "﻿package client.socket;\n\nimport client.control.Chat;\n\nimport com.socket.UDP;\n\n\npublic class UDPChat extends UDP\n{\n\tChat chat = null;// 声明一个聊天的类\n\n\tpublic UDPChat(String friendIP, Chat parent)\n\t{\n\t\tsuper(friendIP);\n\t\tthis.chat = parent;\n\t\tnewThreadGetMessage();\n\t}\n\n\t/**\n\t * 开辟新线程后台获取消息\n\t */\n\tpublic void newThreadGetMessage()\n\t{\n\t\tRunnable runnable = new Runnable()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void run()\n\t\t\t{\n\t\t\t\twhile (true)\n\t\t\t\t{\n\t\t\t\t\tString message = getMessage();// 调用父类UDP的获取消息方法\n\t\t\t\t\tchat.setReceivePaneText(false, message);// 将接收的消息显示在聊天窗体中的聊天框中\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tThread.sleep(30);// 线程休息100毫秒\n\t\t\t\t\t}\n\t\t\t\t\tcatch (InterruptedException e)\n\t\t\t\t\t{\n\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tnew Thread(runnable).start();\n\t}\n\n}\n"
  },
  {
    "path": "src/com/MyTools.java",
    "content": "package com;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Toolkit;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\n\nimport javax.imageio.ImageIO;\nimport javax.swing.ImageIcon;\nimport javax.swing.JFrame;\nimport javax.swing.UIManager;\n\nimport client.control.Main;\n\n/**\n * @author \n * 一些经常调用的方法和枚举，都集中放在这里\n */\npublic class MyTools\n{\n\t//下面三句话定义一些标志，示例如下：\n\t//login#马化腾;1234567\n\t//friends_info#我的好友,柳夏南,王林,吴志强;陌生人,胡锦涛,陈水扁\n\tpublic static final String FLAGEND = \"#\";//定义最当头标志结束的字符\n\tpublic static final String SPLIT1 = \";\";//定义一级分割字符\n\tpublic static final String SPLIT2 = \",\";//定义二级分割字符\n\tpublic static final String SPLIT3 = \"&\";//定义三级分割字符\n\t\n\tpublic static final int QQServerPort = 6776; // QQ服务器端口号\n\tpublic static final String QQServerIP = \"127.0.0.1\"; // 服务器IP地址\n\t// 数据库地址和密码\n\tpublic static final String JDBC_URL = \"jdbc:mysql://127.0.0.1:3306/myqq?useUnicode=true&characterEncoding=utf-8\";\n\tpublic static final String JDBC_USER = \"root\";\n\tpublic static final String JDBC_PWD = \"root\";\n\t// public static final String JDBC_URL = \"jdbc:oracle:thin:@127.0.0.1:1521:XE\";\n\t// public static final String JDBC_USER = \"test\";\n\t// public static final String JDBC_PWD = \"test\";\n\n\t\n\t/**\n\t * @author LXA\n\t *定义一个标志的枚举\n\t */\n\tpublic enum Flag\n\t{\n\t\tLOGIN,\t//“登录”的标志\n\t\tSUCCESS,\t//“成功”的标志\n\t\tFAILED,\t\t//“失败”的标志\n\t\tUSERINFO,\t//“用户信息、好友列表”的标志\n\t\tFRIENDS_LIST,\t//好友列表\n\t\tPORT,\t//端口号的标志\n\t\tSTART_CHAT,\t//聊天的标志\n\t\tMESSAGE,\t//聊天内容的标志\n\t\tGET_FRIEND_INFO, //获取好友资料的标志\n\t\tREGISTER,  //注册\n\t\tSENDFILE, //发送文件的标志\n\t\tGETFILE_OK,\n\t\tQUN_CHAT,   //群聊\n\t\tPUBLIC_MESSAGE,  //公告\n\t\tSHOW_WINDOW,  //弹窗\n\t\tUNDERLINE_MESSAGE,//离线消息\n\t\tSENDIMG,//发送图片\n\t\tFACE//表情\n\t};\n\t\n\t/**\n\t * 将窗体居中显示\n\t * @param frame 需要居中显示的窗体\n\t */\n\tpublic static void setWindowsMiddleShow(JFrame frame)\n\t{\n\t\tDimension screenSize= Toolkit.getDefaultToolkit().getScreenSize();\n\t\tframe.setBounds((screenSize.width-frame.getWidth())/2, (screenSize.height-frame.getHeight())/2, frame.getWidth(), frame.getHeight());\n\t}\n\t/**\n\t * 将窗体居中显示\n\t * @param frame 需要居中显示的窗体\n\t * @param width 窗体的宽度\n\t * @param height 窗体的高度\n\t */\n\tpublic static void setWindowsMiddleShow(JFrame frame,int width,int height)\n\t{\n\t\tDimension screenSize= Toolkit.getDefaultToolkit().getScreenSize();\n\t\tframe.setBounds((screenSize.width-width)/2, (screenSize.height-height)/2, width, height);\n\t}\n\t\n\t/**\n\t * 更换皮肤\n\t */\n\tpublic static void changeSkin()\n\t{\n\t\ttry\n\t\t{\n\t\t\t//UIManager.put(\"nimbusBase\", Color.red);\n\t\t\t//UIManager.put(\"nimbusBlueGrey\", Color.red);//按钮的颜色\n\t\t\tUIManager.put(\"control\", new Color(215, 255, 255));//控件背景色\n\t\t\tUIManager.setLookAndFeel(\"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel\");\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t\n\t/**\n\t * 根据文件路径获取图片\n\t * @param path 路径\n\t * @return 返回获取的图片\n\t */\n\tpublic static ImageIcon getIcon(String path)\n\t{\n\t\ttry\n\t\t{\n\t\t\t//System.out.println(Main.class.getResource(path));\n\t\t\tImageIcon icon=new ImageIcon(ImageIO.read(Main.class.getResource(path)));\n\t\t\t\n\t\t\treturn icon;\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\tSystem.out.println(\"图片：\"+path+\"不存在！\");\n\t\t\treturn null;\n\t\t}\n\t}\n\t\n\t/**\n\t * 将字符串转成Flag类型的枚举\n\t * @param str 需要转的字符串\n\t * @return 返回转换后的Flag枚举\n\t */\n\tpublic static Flag stringToFlagEnum(String str)\n\t{\n\t\treturn Enum.valueOf(Flag.class, str);\n\t}\n\tpublic static String getFaceByIdx(int idx)\n\t{\n\t\tString fileName=\"\";\n\t\tif(idx<10)\n    \t{\n    \t\tfileName= \"../img/face/f00\"+idx+\".png\";//修改图片路径 \n    \t}\n    \telse\n    \t{\n    \t\tfileName= \"../img/face/f0\"+idx+\".png\";\n\t\t}\n\t\treturn fileName;\n\t}\n\t\n\t/**\n\t * 默认会报如下错误：\n\t * 访问限制：由于对必需的库 D:\\GreenSoft\\Java\\jdk1.6.0_10\\jre\\lib\\rt.jar 具有一定限制，因此无法访问类型 AudioStream\n\t * 需要作如下修改：右键项目-->属性-->Java编译器-->错误/警告-->勾选“启用特定于项目的设置”-->建议不要使用和限制使用的API-->将“禁止的引用”改为警告\n\t */\n\tpublic static void playMsgSound()\n\t{\n\t\ttry\n\t\t{\n\t\t\tsun.audio.AudioPlayer.player.start(new sun.audio.AudioStream(new FileInputStream(new File(\"msg.wav\"))));\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\n\tpublic static void playSystemSound()\n\t{\n\t\ttry\n\t\t{\n\t\t\tsun.audio.AudioPlayer.player.start(new sun.audio.AudioStream(new FileInputStream(new File(\"system.wav\"))));\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "src/com/socket/TCP.java",
    "content": "﻿package com.socket;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.net.InetAddress;\nimport java.net.ServerSocket;\nimport java.net.Socket;\nimport java.net.UnknownHostException;\n\nimport javax.imageio.ImageIO;\nimport javax.swing.ImageIcon;\n\nimport client.common.MyTextPane;\nimport client.control.Chat;\n\nimport com.MyTools;\nimport com.MyTools.Flag;\n\npublic class TCP\n{\n\tprivate Socket socket = null;\n\tprivate String clientName=\"\";//用户名\n\tprivate int clientServerPort=0;//客户端端口号\n\tprivate int userState=0;//0表示在线\n\t\n\t/**\n\t * 客户端TCP初始化\n\t * @param serverIP 服务端IP地址\n\t * @param serverPort  服务端端口号\n\t * @throws IOException \n\t * @throws UnknownHostException \n\t */\n\tpublic TCP(String serverIP, int serverPort) throws Exception\n\t{\n\t\tsocket = new Socket(serverIP, serverPort);\n\t\tSystem.out.println(\"客户端TCP成功启动！\");\n\t\tgetMessageNewThread();//对于客户端的TCP，给它启动一个新线程不停的接收消息\n\t}\n\t\n\t/**\n\t * TCP的另一种构造方法\n\t * @param server 传过来的Server端TCP连接\n\t */\n\tpublic TCP(ServerSocket server)\n\t{\n\t\ttry\n\t\t{\n\t\t\tsocket = server.accept();\n\t\t\tSystem.out.println(\"新增一台客户端与服务端连接！\");\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\t//e.printStackTrace();\n\t\t}\n\t}\n\t\n\t/**\n\t * 关闭Socket连接\n\t */\n\tpublic void closeSocket()\n\t{\n\t\ttry\n\t\t{\n\t\t\tif(socket!=null)\n\t\t\t\tsocket.close();\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t/**\n\t * 开辟新线程后台接收消息并处理\n\t * @param tcp 传过来的TCP连接\n\t */\n\tpublic void getMessageNewThread()\n\t{\n\t\tRunnable runnable = new Runnable()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void run()\n\t\t\t{\n\t\t\t\tboolean exit=false;\n\t\t\t\twhile(!exit)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\t//将获取的消息按#分割，msg[0]的表示标志，msg[1]表示内容\n\t\t\t\t\t\tString[] temp=getMessage().split(MyTools.FLAGEND);\n\t\t\t\t\t\tString flagHead=temp[0];//获取消息的标志\n\t\t\t\t\t\tString message=temp[1];//获取消息的真实内容\n\t\t\t\t\t\tFlag flag=MyTools.stringToFlagEnum(flagHead);//获取标志\n\t\t\t\t\t\tdealWithMessage(flag,message);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception e)\n\t\t\t\t\t{\n\t\t\t\t\t\tdealWithExit();\n\t\t\t\t\t\texit=true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tnew Thread(runnable).start();\n\t}\n\t\n\tpublic void dealWithMessage(Flag flag,String message)\n\t{\n\t\t\n\t}\n\tpublic void dealWithExit()\n\t{\n\t\t\n\t}\n\t/**\n\t * 发送消息\n\t * @param text\n\t *            要发送的文本\n\t */\n\tpublic void sendMessage(String text)\n\t{\n\t\ttry\n\t\t{\n\t\t\tsocket.getOutputStream().write(text.getBytes());\n\t\t\tSystem.out.println(\"TCP成功发送：\" + text);\n\t\t\tThread.sleep(100);//每发送完一个消息线程休息一下，防止连续发送消息重叠在一起\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\t/**\n\t * 获取消息\n\t * \n\t * @return 获取的文本\n\t */\n\tpublic String getMessage() throws Exception\n\t{\n    \tbyte[] b = new byte[1024];\n    \tint len = socket.getInputStream().read(b);\n    \tString str = new String(b, 0, len);\n    \tSystem.out.println(\"TCP接收到：\" + str);\n    \treturn str;\n\t}\n\tpublic void sendFile()\n\t{\n\t\t\n\t}\n\t/**\n\t * @param imgPath\n\t *            根据图片路径发送图片\n\t * \n\t */\n\tpublic void sendImg(String imgPath)\n\t{\n\t\ttry\n\t\t{\n\t\t\tFile imgFile = new File(imgPath);\n\t\t\tFileInputStream imgFileIn = new FileInputStream(imgFile);\n\t\t\t// 获取文件名\n\t\t\tString imgName = imgFile.getName();\n\t\t\tbyte[] buff = new byte[1024];\n\t\t\tint len = 0;\n\n\t\t\t// 首先发送文件名\n\t\t\tsendMessage(Flag.SENDIMG+MyTools.FLAGEND+imgName);\n\t\t\tOutputStream out = socket.getOutputStream();\n//\t\t\tout.write(imgName.getBytes());\n\t\t\t// 开始发送图片\n\t\t\tSystem.out.println(\"开始发送图片……\");\n\t\t\tif(socket.isClosed())\n\t\t\t\tSystem.out.println(\"已关闭\");\n\t\t\telse {\n\t\t\t\tSystem.out.println(\"未关闭\");\n\t\t\t}\n\t\t\twhile ((len = imgFileIn.read(buff)) != -1)\n\t\t\t{\n\t\t\t\tSystem.out.println(\"111\");\n\t\t\t\tout.write(buff, 0, len);\n\t\t\t\tSystem.out.println(\"222\");\n\t\t\t}\n\t\t\tout.write(\"#文件发送完毕#\".getBytes());\n\t\t\ttry\n\t\t\t{\n\t\t\t\tThread.sleep(100);\n\t\t\t}\n\t\t\tcatch (InterruptedException e)\n\t\t\t{\n\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\tSystem.out.println(\"图片已发送完成\");\n\n\t\t}\n\t\tcatch (FileNotFoundException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\t/**\n\t * 得到图片\n\t */\n\tpublic void getImg(Chat chat ,String imgName)\n\t{\n\t\tFile imgFile = null;\n\t\ttry\n\t\t{\n\t\t\tInputStream in = socket.getInputStream();\n\t\t\tbyte[] buff = new byte[1024];\n\t\t\tint len = 0;\n\t\t\t// 存放接收文件对象\n\t\t\timgFile = new File(\"./\" + System.currentTimeMillis() + imgName);\n\t\t\tFileOutputStream imgOut = new FileOutputStream(imgFile);\n\n\t\t\tSystem.out.println(\"12342\");\n\t\t\tlen = 1024;//in.read(buff,0,buff.length);\n\t\t\t//imgOut.write(buff, 0, len);\n\t\t\twhile (len ==1024)\n\t\t\t{\n\t\t\t\tSystem.out.println(\"len=\"+len);\n\t\t\t\t\n\t\t\t\tSystem.out.println(\"图片正在接收....\");\n\t\t\t\tlen = in.read(buff,0,buff.length);\n\t\t\t\tString str=new String(buff,0,len);\n\t\t\t\tif(str.equals(\"#文件发送完毕#\"))\n\t\t\t\t\tbreak;\n\t\t\t\timgOut.write(buff, 0, len);\n\t\t\t}\n\t\t\tSystem.out.println(\"图片接收完成\");\n\t\t\tin.close();\n\t\t\timgOut.close();\n\t\t\t\n\t\t\tnew MyTextPane(chat.jTextPane接收框).addIcon(ImageIO\n\t\t\t\t\t.read(new FileInputStream(imgFile)), chat.friendName);\n\t\t\t//chat.jTextPane接收框.insertIcon(new ImageIcon()));\n\t\t\tSystem.out.println(\"图片插入完成\");\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\t// TODO Auto-generated catch block\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t\t\n\t}\n\t\n\t\n\t/**\n\t * 获取客户端的IP地址\n\t * @return\n\t */\n\tpublic String getClientIP()\n\t{\n\t\treturn socket.getInetAddress().getHostAddress().replaceAll(\"/\", \"\");\n\t}\n\t\n\t/**\n\t *  获取本机IP地址\n\t * @return 返回字符串形式的IP地址\n\t */\n\tpublic static String getLocalHostIP()\n\t{\n\t\ttry\n\t\t{\n\t\t\treturn InetAddress.getLocalHost().getHostAddress().replaceAll(\"/\", \"\");\n\t\t}\n\t\tcatch (UnknownHostException e)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\t}\n\t/**\n\t * 获取客户端的用户名\n\t * @return\n\t */\n\tpublic String getClientName()\n\t{\n\t\treturn clientName;\n\t}\n\t/**\n\t * 设置客户端的用户名\n\t * @param name\n\t */\n\tpublic void setClientName(String name)\n\t{\n\t\tthis.clientName=name;\n\t}\n\n\t/**\n\t * 获取客户端的TCP服务端端口号\n\t * @return\n\t */\n\tpublic int getClientServerPort()\n\t{\n\t\treturn clientServerPort;\n\t}\n\n\t/**\n\t * 设置客户端的TCP服务端端口号\n\t * @param clientPort\n\t */\n\tpublic void setClientServerPort(int clientServerPort)\n\t{\n\t\tthis.clientServerPort=clientServerPort;\n\t}\n\t\n\t/**\n\t * 获取服务端的端口号\n\t */\n\tpublic int getServerPort()\n\t{\n\t\treturn socket.getLocalPort();//返回自己的端口，如5000\n\t}\n\tpublic int getClientPort()\n\t{\n\t\treturn socket.getPort();//返回与别人建立连接的端口，如65544\n\t}\n\t/**\n\t * 设置当前登录用户状态\n\t * @param userState\n\t */\n\tpublic void setUserState(int userState)\n\t{\n\t\tthis.userState=userState;\n\t}\n\t/**\n\t * 获取当前登录用户状态\n\t * @return\n\t */\n\tpublic int getUserState()\n\t{\n\t\treturn userState;\n\t}\n}\n"
  },
  {
    "path": "src/com/socket/TCPServer.java",
    "content": "﻿package com.socket;\n\nimport java.io.IOException;\nimport java.net.ServerSocket;\nimport java.util.ArrayList;\n\nimport com.MyTools;\nimport com.MyTools.Flag;\nimport com.socket.TCP;\n\npublic class TCPServer\n{\n\tpublic ServerSocket server = null;// 服务端\n    public ArrayList<TCP> tcpSockets = new ArrayList<TCP>();// 存放与客户端的TCPSocket连接\n\tprivate int serverPort = 0;//服务端的端口\n\tpublic boolean isStart = false;// 是否启动了服务端\n\n\t/**\n\t * 服务端TCP初始化\n\t * @param server 服务端\n\t */\n\tpublic TCPServer(int serverPort)\n\t{\n\t\tthis.serverPort=serverPort;\n\t\tisStart = true;\n\t\tif(startServerTCP())//启动TCP服务端\n\t\t{\n\t\t\tafterServerStart();\t//服务端启动后要做的事情\n\t\t\tgetConnectionNewThread();//开辟新线程不断的接受连接\n\t\t}\n\t}\n\t/**\n\t * 关闭服务器\n\t */\n\tpublic void closeServer()\n\t{\n\t\tisStart=false;\n\t\ttry\n\t\t{\n\t\t\tserver.close();\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t/**\n\t * 启动TCP服务端\n\t */\n\tpublic boolean startServerTCP()\n\t{\n\t\tif(serverPort==MyTools.QQServerPort)//如果启动的是QQ服务器\n\t\t{\n    \t\ttry\n\t\t\t{\n\t\t\t\tserver=new ServerSocket(serverPort);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcatch (IOException e)\n\t\t\t{\n\t\t\t\tSystem.out.println(\"启动QQ服务器失败！端口\"+serverPort+\"已被占用，请检查是否已开启了一个QQ服务器！\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t\n\t\t}\n\t\telse//如果启动的是普通TCP服务端\n\t\t{\n\t\t\twhile(true)\n        \t{\n        \t\ttry\n        \t\t{\n        \t\t\tserver = new ServerSocket(serverPort);\n        \t\t\tbreak;\n        \t\t}\n        \t\tcatch (IOException e)\n        \t\t{\n        \t\t\tserverPort++;\n        \t\t}\n        \t}\n\t\t\treturn true;\n\t\t}\n\t}\n\t/**\n\t * 开辟新线程不断的接受连接\n\t */\n\tpublic void getConnectionNewThread()\n\t{\n\t\tRunnable runnable=new Runnable()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void run()\n\t\t\t{\n\t\t\t\twhile (isStart)\n        \t\t{\n        \t\t\tTCP tcp = new TCP(server);\n        \t\t\ttcpSockets.add(tcp);\n        \t\t\tgetMessageNewThread(tcp);\n        \t\t}\n\t\t\t}\n\t\t};\n\t\tnew Thread(runnable).start();\n\t}\n\t/**\n\t * 开辟新线程后台接收消息并处理\n\t * @param tcp 传过来的TCP连接\n\t */\n\tpublic void getMessageNewThread(final TCP tcp)\n\t{\n\t\tRunnable runnable = new Runnable()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void run()\n\t\t\t{\n\t\t\t\tboolean exit=false;\n\t\t\t\twhile(!exit)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\t//将获取的消息按#分割，msg[0]的表示标志，msg[1]表示内容\n\t\t\t\t\t\tString[] temp=tcp.getMessage().split(MyTools.FLAGEND);\n\t\t\t\t\t\tString flagHead=temp[0];//获取消息的标志\n\t\t\t\t\t\tString message=temp[1];//获取消息的真实内容\n\t\t\t\t\t\tFlag flag=MyTools.stringToFlagEnum(flagHead);//获取标志\n\t\t\t\t\t\tdealWithMessage(flag,message,tcp);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception e)\n\t\t\t\t\t{\n\t\t\t\t\t\t//e.printStackTrace();\n\t\t\t\t\t\tif(tcpSockets.remove(tcp))//从ArrayList中移除已退出的用户\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdealWithExit(tcp);\n\t\t\t\t\t\t}\n\t\t\t\t\t\texit=true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tnew Thread(runnable).start();\n\t}\n\t/**\n\t * 处理客户端发来的各种信息\n\t * @param flag 信息标志\n\t * @param message 消息内容\n\t * @param tcp TCP连接\n\t */\n\tpublic void dealWithMessage(Flag flag,String message,TCP tcp)\n\t{\n\n\t}\n\t/**\n\t * 处理客户端退出的相关事件\n\t * @param tcp TCP连接\n\t */\n\tpublic void dealWithExit(TCP tcp)\n\t{\n\t\t\n\t}\n\t/**\n\t * 服务端启动后要做的事情，把这部分单独提取出来的目的是为了方便子类继承时重写\n\t */\n\tpublic void afterServerStart()\n\t{\n\t\tSystem.out.println(\"服务端TCP已启动！端口号：\"+serverPort);\n\t}\n\tpublic int getServerPort()\n\t{\n\t\treturn serverPort;\n\t}\n\n}\n"
  },
  {
    "path": "src/com/socket/UDP.java",
    "content": "﻿package com.socket;\n\nimport java.io.IOException;\nimport java.net.DatagramPacket;\nimport java.net.DatagramSocket;\nimport java.net.InetAddress;\nimport java.net.SocketException;\nimport java.text.BreakIterator;\n\n\npublic class UDP\n{\n\tpublic DatagramSocket socket = null;// 通过UDP建立的Socket\n\tprivate int myPort = 6000;// 我的端口，从6000开始查找可用的端口号\n\tpublic InetAddress friendIP = null;// 好友的IP地址\n\tpublic int friendPort = 0;// 好友的端口\n\n\tpublic UDP(String friendIP)\n\t{\n\t\tgetMyUsefulPort();\n\t\ttry\n\t\t{\n\t\t\tthis.friendIP = InetAddress.getByName(friendIP);\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t\n\t/**\n\t * 设置好友的端口号\n\t * @param friendPort\n\t */\n\tpublic void setFriendPort(int friendPort)\n\t{\n\t\tthis.friendPort=friendPort;\n\t}\n\t/**\n\t * 获取我的端口号，只有当UDP类被实例化后才能调用此方法，\n\t * 否则得到的端口号可能不是最终有效的端口号\n\t * @return\n\t */\n\tpublic int getMyPort()\n\t{\n\t\treturn this.myPort;\n\t}\n\t/**\n\t * 获取可用的端口号\n\t */\n\tpublic void getMyUsefulPort()\n\t{\n\t\twhile(true)\n\t\t{\n    \t\ttry\n    \t\t{\n    \t\t\t// 实例化一个DatagramSocket\n    \t\t\tsocket = new DatagramSocket(myPort);\n    \t\t\tbreak;\n    \t\t}\n    \t\tcatch (SocketException e)\n    \t\t{\n    \t\t\tmyPort++;\n    \t\t}\n\t\t}\n\t}\n\t/*\n\t * 给好友发送消息\n\t */\n\tpublic void sendMessage(String text)\n\t{\n\t\tbyte[] data = text.getBytes();\n\t\tDatagramPacket packet = new DatagramPacket(data, data.length, friendIP,\n\t\t\t\tfriendPort);\n\t\ttry\n\t\t{\n\t\t\tsocket.send(packet);// 开始发送消息\n\t\t\tSystem.out.println(\"使用UDP成功发送：\"+text);\n\t\t}\n\t\tcatch (IOException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\t/**\n\t * 接收消息\n\t */\n\tpublic String getMessage()\n\t{\n\t\tbyte[] buf = new byte[1024];\n\t\tDatagramPacket dp = new DatagramPacket(buf, buf.length);\n\t\ttry\n\t\t{\n\t\t\tsocket.receive(dp);\n\t\t\tString message = new String(dp.getData(), 0, dp.getLength());\n\t\t\tSystem.out.println(\"使用UDP成功接收到：\"+message);\n\t\t\treturn message;\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t\treturn null;\n\t\t}\n\t}\n\t/**\n\t * 开辟新线程后台获取消息,这个方法姑且丢置在这里，暂时不会用到\n\t */\n\tpublic void newThreadGetMessage()\n\t{\n\t\tRunnable runnable = new Runnable()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic void run()\n\t\t\t{\n\t\t\t\twhile (true)\n\t\t\t\t{\n\t\t\t\t\tgetMessage();// 调用UDP的获取消息方法\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tThread.sleep(100);// 线程休息100毫秒\n\t\t\t\t\t}\n\t\t\t\t\tcatch (InterruptedException e)\n\t\t\t\t\t{\n\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tnew Thread(runnable).start();\n\t}\n\t\n}\n"
  },
  {
    "path": "src/log4j-1.2.dtd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!--\n Licensed to the Apache Software Foundation (ASF) under one or more\n contributor license agreements.  See the NOTICE file distributed with\n this work for additional information regarding copyright ownership.\n The ASF licenses this file to You under the Apache License, Version 2.0\n (the \"License\"); you may not use this file except in compliance with\n the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n<!-- Authors: Chris Taylor, Ceki Gulcu. -->\n\n<!-- Version: 1.2 -->\n\n<!-- A configuration element consists of optional renderer\nelements,appender elements, categories and an optional root\nelement. -->\n\n<!ELEMENT log4j:configuration (renderer*, appender*,plugin*, (category|logger)*,root?,\n                               (categoryFactory|loggerFactory)?)>\n\n<!-- The \"threshold\" attribute takes a level value below which -->\n<!-- all logging statements are disabled. -->\n\n<!-- Setting the \"debug\" enable the printing of internal log4j logging   -->\n<!-- statements.                                                         -->\n\n<!-- By default, debug attribute is \"null\", meaning that we not do touch -->\n<!-- internal log4j logging settings. The \"null\" value for the threshold -->\n<!-- attribute can be misleading. The threshold field of a repository\t -->\n<!-- cannot be set to null. The \"null\" value for the threshold attribute -->\n<!-- simply means don't touch the threshold field, the threshold field   --> \n<!-- keeps its old value.                                                -->\n     \n<!ATTLIST log4j:configuration\n  xmlns:log4j              CDATA #FIXED \"http://jakarta.apache.org/log4j/\" \n  threshold                (all|trace|debug|info|warn|error|fatal|off|null) \"null\"\n  debug                    (true|false|null)  \"null\"\n  reset                    (true|false) \"false\"\n>\n\n<!-- renderer elements allow the user to customize the conversion of  -->\n<!-- message objects to String.                                       -->\n\n<!ELEMENT renderer EMPTY>\n<!ATTLIST renderer\n  renderedClass  CDATA #REQUIRED\n  renderingClass CDATA #REQUIRED\n>\n\n<!-- Appenders must have a name and a class. -->\n<!-- Appenders may contain an error handler, a layout, optional parameters -->\n<!-- and filters. They may also reference (or include) other appenders. -->\n<!ELEMENT appender (errorHandler?, param*,\n      rollingPolicy?, triggeringPolicy?, connectionSource?,\n      layout?, filter*, appender-ref*)>\n<!ATTLIST appender\n  name \t\tCDATA \t#REQUIRED\n  class \tCDATA\t#REQUIRED\n>\n\n<!ELEMENT layout (param*)>\n<!ATTLIST layout\n  class\t\tCDATA\t#REQUIRED\n>\n\n<!ELEMENT filter (param*)>\n<!ATTLIST filter\n  class\t\tCDATA\t#REQUIRED\n>\n\n<!-- ErrorHandlers can be of any class. They can admit any number of -->\n<!-- parameters. -->\n\n<!ELEMENT errorHandler (param*, root-ref?, logger-ref*,  appender-ref?)> \n<!ATTLIST errorHandler\n   class        CDATA   #REQUIRED \n>\n\n<!ELEMENT root-ref EMPTY>\n\n<!ELEMENT logger-ref EMPTY>\n<!ATTLIST logger-ref\n  ref CDATA #REQUIRED\n>\n\n<!ELEMENT param EMPTY>\n<!ATTLIST param\n  name\t\tCDATA   #REQUIRED\n  value\t\tCDATA\t#REQUIRED\n>\n\n\n<!-- The priority class is org.apache.log4j.Level by default -->\n<!ELEMENT priority (param*)>\n<!ATTLIST priority\n  class   CDATA\t#IMPLIED\n  value\t  CDATA #REQUIRED\n>\n\n<!-- The level class is org.apache.log4j.Level by default -->\n<!ELEMENT level (param*)>\n<!ATTLIST level\n  class   CDATA\t#IMPLIED\n  value\t  CDATA #REQUIRED\n>\n\n\n<!-- If no level element is specified, then the configurator MUST not -->\n<!-- touch the level of the named category. -->\n<!ELEMENT category (param*,(priority|level)?,appender-ref*)>\n<!ATTLIST category\n  class         CDATA   #IMPLIED\n  name\t\tCDATA\t#REQUIRED\n  additivity\t(true|false) \"true\"  \n>\n\n<!-- If no level element is specified, then the configurator MUST not -->\n<!-- touch the level of the named logger. -->\n<!ELEMENT logger (level?,appender-ref*)>\n<!ATTLIST logger\n  name\t\tCDATA\t#REQUIRED\n  additivity\t(true|false) \"true\"  \n>\n\n\n<!ELEMENT categoryFactory (param*)>\n<!ATTLIST categoryFactory \n   class        CDATA #REQUIRED>\n\n<!ELEMENT loggerFactory (param*)>\n<!ATTLIST loggerFactory\n   class        CDATA #REQUIRED>\n\n<!ELEMENT appender-ref EMPTY>\n<!ATTLIST appender-ref\n  ref CDATA #REQUIRED\n>\n\n<!-- plugins must have a name and class and can have optional parameters -->\n<!ELEMENT plugin (param*, connectionSource?)>\n<!ATTLIST plugin\n  name \t\tCDATA \t   #REQUIRED\n  class \tCDATA  #REQUIRED\n>\n\n<!ELEMENT connectionSource (dataSource?, param*)>\n<!ATTLIST connectionSource\n  class        CDATA  #REQUIRED\n>\n\n<!ELEMENT dataSource (param*)>\n<!ATTLIST dataSource\n  class        CDATA  #REQUIRED\n>\n\n<!ELEMENT triggeringPolicy ((param|filter)*)>\n<!ATTLIST triggeringPolicy\n  name \t\tCDATA  #IMPLIED\n  class \tCDATA  #REQUIRED\n>\n\n<!ELEMENT rollingPolicy (param*)>\n<!ATTLIST rollingPolicy\n  name \t\tCDATA  #IMPLIED\n  class \tCDATA  #REQUIRED\n>\n\n\n<!-- If no priority element is specified, then the configurator MUST not -->\n<!-- touch the priority of root. -->\n<!-- The root category always exists and cannot be subclassed. -->\n<!ELEMENT root (param*, (priority|level)?, appender-ref*)>\n\n\n<!-- ==================================================================== -->\n<!--                       A logging event                                -->\n<!-- ==================================================================== -->\n<!ELEMENT log4j:eventSet (log4j:event*)>\n<!ATTLIST log4j:eventSet\n  xmlns:log4j             CDATA #FIXED \"http://jakarta.apache.org/log4j/\" \n  version                (1.1|1.2) \"1.2\" \n  includesLocationInfo   (true|false) \"true\"\n>\n\n\n\n<!ELEMENT log4j:event (log4j:message, log4j:NDC?, log4j:throwable?, \n                       log4j:locationInfo?, log4j:properties?) >\n\n<!-- The timestamp format is application dependent. -->\n<!ATTLIST log4j:event\n    logger     CDATA #REQUIRED\n    level      CDATA #REQUIRED\n    thread     CDATA #REQUIRED\n    timestamp  CDATA #REQUIRED\n    time       CDATA #IMPLIED\n>\n\n<!ELEMENT log4j:message (#PCDATA)>\n<!ELEMENT log4j:NDC (#PCDATA)>\n\n<!ELEMENT log4j:throwable (#PCDATA)>\n\n<!ELEMENT log4j:locationInfo EMPTY>\n<!ATTLIST log4j:locationInfo\n  class  CDATA\t#REQUIRED\n  method CDATA\t#REQUIRED\n  file   CDATA\t#REQUIRED\n  line   CDATA\t#REQUIRED\n>\n\n<!ELEMENT log4j:properties (log4j:data*)>\n\n<!ELEMENT log4j:data EMPTY>\n<!ATTLIST log4j:data\n  name   CDATA\t#REQUIRED\n  value  CDATA\t#REQUIRED\n>\n"
  },
  {
    "path": "src/log4j.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE log4j:configuration PUBLIC \"-//APACHE//DTD LOG4J 1.2//EN\" \"log4j-1.2.dtd\">\n<log4j:configuration debug=\"true\" xmlns:log4j=\"http://jakarta.apache.org/log4j/\">\n\n\t<!-- 设置根日志，这个决定不同级别的日志具体输出到哪些地方 -->\n\t<root>\n\t\t<priority value=\"debug\" />\n\t\t<appender-ref ref=\"console\" />\n\t\t<appender-ref ref=\"file\" />\n\t</root>\n\t\n\t<!-- 控制台配置 -->\n\t<appender name=\"console\" class=\"org.apache.log4j.ConsoleAppender\">\n\t\t<param name=\"Target\" value=\"System.out\" />\n\t\t<layout class=\"org.apache.log4j.PatternLayout\">\n\t\t\t<param name=\"ConversionPattern\" value=\"[LXA][%p] %d{yyyy年MM月dd日 HH:mm:ss} %m%n\" />\n\t\t</layout>\n\t</appender>\n\t\n\t<!-- 文件配置 -->\n\t<appender name=\"file\" class=\"org.apache.log4j.DailyRollingFileAppender\">\n\t\t<param name=\"File\" value=\"${catalina.home}/logs/lxa.log\"/>\n\t\t<param name=\"DatePattern\" value=\"'-'yyyy-MM-dd'.txt'\"/>\n\t\t<layout class=\"org.apache.log4j.PatternLayout\">\n\t\t\t<param name=\"ConversionPattern\" value=\"[LXA][%p] %d{yyyy年MM月dd日 HH:mm:ss:SSS} %l:%n%m%n%n\"/>\n\t\t</layout>\n\t</appender>\n\t\n\t<!-- 对特殊类进行级别的特殊设置 -->\n\t<logger name=\"com.lxa\">\n\t\t<level value=\"debug\" />\n\t</logger>\n\t\n\t<!-- \n\t\t格式化日志信息：\n\t\t%d{yyyy-MM-dd} 时间\n\t\t%p 模式，如INFO或者DEBUG\n\t\t%c 类的全名\n\t\t%L 行数\n\t\t%l 具体调用的方法名（包括类全名）\n\t\t%m 输出的信息\n\t\t%n 换行\n\t -->\n\n</log4j:configuration>\n"
  },
  {
    "path": "src/server/QQServer.java",
    "content": "package server;\n\nimport java.sql.Date;\nimport java.sql.SQLException;\nimport java.text.DateFormat;\nimport java.util.ArrayList;\n\nimport javax.swing.JOptionPane;\n\nimport server.dao.MsgDao;\nimport server.dao.UserDao;\nimport server.entity.Msg;\nimport server.entity.Users;\n\nimport com.MyTools;\nimport com.MyTools.Flag;\nimport com.socket.TCP;\nimport com.socket.TCPServer;\n\n/**\n * @author LXA 服务端\n */\npublic class QQServer extends TCPServer\n{ \n\n\tUserDao userDao;\n\tMsgDao msgDao;\n\tpublic QQServer(int serverPort)\n\t{\n\t\tsuper(serverPort);\n\t\tuserDao=new UserDao();\n\t\tmsgDao=new MsgDao();\n\t}\n\t/**\n\t * 主函数\n\t * @param args\n\t */\n//\tpublic static void main(String[] args)\n//\t{\n//\t\tnew QQServer(MyTools.QQServerPort);\n//\t}\n\n\t/**\n\t * 处理客户端发来的各种信息\n\t * @param flag 信息标志\n\t * @param message 消息内容\n\t * @param tcp TCP连接\n\t */\n\t@Override\n\tpublic void dealWithMessage(Flag flag, String message,TCP tcp)\n\t{\n\t\tswitch(flag)\n\t\t{\n\t\t\tcase LOGIN:doLogin(message,tcp);break;//如果是登录\n\t\t\tcase GET_FRIEND_INFO:doGetFriendInfo(message,tcp);break;//处理用户发来的请求好友资料的事件\n\t\t\tcase REGISTER:doRegister(message,tcp);break;\n\t\t\tcase QUN_CHAT:doQunChat(message,tcp);break;\n\t\t\tcase UNDERLINE_MESSAGE:doUnderlineMessage(message,tcp);break;//处理用户发来的离线消息\n\t\t\tdefault:break;\n\t\t}\n\t}\n\t\n\t/**\n\t * 处理客户端退出的相关事件\n\t * @param tcp TCP连接\n\t */\n\t@Override\n\tpublic void dealWithExit(TCP tcp)\n\t{\n\t\trefreshAllUserFriendList();\n\t\tuserDao.updateUserState(tcp.getClientName(), -1+\"\");//将用户的状态更新到数据库中去\n\t\tuserDao.setLastExit(tcp.getClientName());\n\t\tSystem.out.println(\"用户\"+tcp.getClientName()+\"已退出！\");\n\t\tshowOnlineNumber();\n\t}\n\t\n\t/* \n\t * 服务端启动后要做的事情\n\t */\n\t@Override\n\tpublic void afterServerStart()\n\t{\n\t\tSystem.out.println(\"QQ服务器已启动！\");\n\t\tshowOnlineNumber();\n\t}\n\n\t/**\n\t * 处理客户端登录\n\t * @param message\n\t */\n\tpublic void doLogin(String message,TCP tcp)\n\t{\n\t\tSystem.out.println(\"客户端\"+tcp.getClientIP()+\"尝试登录……\");\n\t\tString[] temp=message.split(MyTools.SPLIT1);\n\t\tString name=temp[0];//用户名\n\t\tString password=temp[1];//用户密码\n\t\tint port=Integer.parseInt(temp[2]);//用户端口号\n\t\tint userState=Integer.parseInt(temp[3]);//用户状态\n\t\tSystem.out.println(\"nihao\");\n\t\tif(checkNameAndPwd(name, password))//如果用户名和密码都正确\n\t\t{\n\t\t\tif(checkIsLoginAgain(name))//如果重复登录\n\t\t\t\ttcp.sendMessage(Flag.LOGIN+MyTools.FLAGEND+Flag.FAILED+MyTools.SPLIT1+\"您不能重复登录！\");\n\t\t\telse \n\t\t\t{\n\t\t\t\t\n\t\t\t\ttcp.setClientName(name);//设置登录用户的名字到TCP中保存\n\t\t\t\ttcp.setClientServerPort(port);//保存当前登录用户的端口\n\t\t\t\ttcp.setUserState(userState);//保存当前登录用户的状态\n\t\t\t\tuserDao.updateUserState(name, userState+\"\");//将用户的状态保存到数据库中去\n\t\t\t\tuserDao.setLastLogin(name);\n\t\t\t\tuserDao.setIP(tcp.getClientIP(), name);//将用户的IP存往数据库\n\t\t\t\ttcp.sendMessage(Flag.LOGIN+MyTools.FLAGEND+Flag.SUCCESS+MyTools.SPLIT1+getCurrentUserInfo(tcp));//发送一个消息给用户提示登录成功\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tThread.sleep(50);\n\t\t\t\t}\n\t\t\t\tcatch (InterruptedException e)\n\t\t\t\t{\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t\trefreshAllUserFriendList();//刷新所有用户的好友列表，但不包括当前登录用户\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tThread.sleep(50);\n\t\t\t\t}\n\t\t\t\tcatch (InterruptedException e)\n\t\t\t\t{\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t\tsendUnreadMessage(tcp);//发送用户未读消息\n\t\t\t\tshowOnlineNumber();//显示当前在线人数\n\t\t\t}\n\t\t}\n\t\telse//如果登录失败\n\t\t{\n\t\t\ttcp.sendMessage(Flag.LOGIN+MyTools.FLAGEND+Flag.FAILED+MyTools.SPLIT1+\"用户名或密码错误！\");\n\t\t}\n\t}\n\t\n\t/**\n\t * 处理用户发来的请求好友资料的事件\n\t * @param message\n\t * @param tcp\n\t */\n\tpublic void doGetFriendInfo(String message,TCP tcp)\n\t{\n\t\tUsers users = userDao.queryByName(tcp.getClientName());\n\t\tStringBuffer sb=new StringBuffer();\n\t\tsb.append(\"用户ID：\"+users.getId()+\"\\n\");\n\t\tsb.append(\"用户名：\"+users.getName()+\"\\n\");\n\t\tsb.append(\"性别：\"+users.getGender()+\"\\n\");\n\t\tsb.append(\"电子邮件：\"+users.getEmail()+\"\\n\");\n\t\tsb.append(\"最后一次登录：\"+users.getLastLogin()+\"\\n\");\n\t\tsb.append(\"最后一次退出：\"+users.getLastExit()+\"\\n\");\n\t\tsb.append(\"个性签名：\"+users.getSignature()+\"\\n\");\n\t\tsb.append(\"生日：\"+users.getBirthday()+\"\\n\");\n\t\tString userInfo=new String(sb);\n\t\ttcp.sendMessage(Flag.GET_FRIEND_INFO+MyTools.FLAGEND+userInfo);\n\t}\n\t\n\t/**\n\t * 处理用户发来的注册请求\n\t * @param message\n\t * @param tcp\n\t */\n\tpublic void doRegister(String message,TCP tcp)\n\t{\n\t\tString[] temp=message.split(MyTools.SPLIT1);\n\t\tString name=temp[0];//姓名\n\t\tString password=temp[1];//密码\n\t\tString sex=temp[2];//性别\n\t\tString email=temp[3];//电子邮件\n\t\tDate birthday;//生日\n\t\tString repost=\"恭喜你，注册成功！\";//给用户的回复\n\t\ttry\n\t\t{\n\t\t\tSystem.out.println(\"生日：\"+temp[4]);\n\t\t\tbirthday=Date.valueOf(temp[4]);\n\t\t\tSystem.out.println(birthday);\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\tbirthday=Date.valueOf(\"1992-07-28\");\n\t\t\trepost+=\"\\n但是您的生日日期格式不正确，系统已给您设置成默认的生日：1992-07-28!\";\n\t\t}\n\t\tString signature=temp[5];//个性签名\n\t\tString headImageIdx=temp[6];//头像索引\n\t\tUsers users=new Users(name, password, sex, email, signature, headImageIdx, birthday);\n\t\tif(userDao.checkUserIsExit(name))\n\t\t\ttcp.sendMessage(Flag.REGISTER+MyTools.FLAGEND+Flag.FAILED+MyTools.SPLIT1+\"用户名已存在！\");\n\t\telse \n\t\t{\n\t\t\ttry\n    \t\t{\n    \t\t\tuserDao.add(users);\n    \t\t\ttcp.sendMessage(Flag.REGISTER+MyTools.FLAGEND+Flag.SUCCESS+MyTools.SPLIT1+repost);\n    \t\t}\n    \t\tcatch (SQLException e)\n    \t\t{\n    \t\t\te.printStackTrace();\n    \t\t\ttcp.sendMessage(Flag.REGISTER+MyTools.FLAGEND+Flag.FAILED+MyTools.SPLIT1+\"由于某些原因，注册失败！\");\n    \t\t}\n\t\t}\n\t}\n\t\n\t/**\n\t * 检查登录用户的用户名和密码是否正确\n\t * @param name\n\t * @param password\n\t * @return\n\t */\n\tpublic boolean checkNameAndPwd(String name,String password)\n\t{\n\t\tboolean success=false;\n\t\tif(userDao.checkNameAndPwd(name, password))\n\t\t\tsuccess=true;\n\t\treturn success;\n\t}\n\t/**\n\t * 检查用户是否重复登录\n\t * @param name 用户名\n\t * @return 返回的真假值\n\t */\n\tpublic boolean checkIsLoginAgain(String name)\n\t{\n\t\tboolean res=false;\n\t\tfor(TCP tcp:tcpSockets)\n\t\t\tif(tcp.getClientName().equals(name))\n\t\t\t{\n\t\t\t\tres=true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\treturn res;\n\t}\n\t/**\n\t * 初始化客户端信息\n\t * @param tcp\n\t */\n\tpublic void initClientInfo(TCP tcp)\n\t{\n\t\ttcp.sendMessage(Flag.USERINFO+MyTools.FLAGEND+getCurrentUserInfo(tcp));\n\t}\n\n\t/**\n\t * 刷新所有在线用户的好友列表\n\t */\n\tpublic void refreshAllUserFriendList()\n\t{\n\t\tfor(TCP tcp:tcpSockets)\n\t\t\ttcp.sendMessage(Flag.FRIENDS_LIST+MyTools.FLAGEND+getAllUsersInfo());\n\t}\n\t\n\t/**\n\t * 获取当前用户的信息\n\t * @param t\n\t * @return\n\t */\n\tpublic String getCurrentUserInfo(TCP tcp)\n\t{\n\t\t//示例：用户名;状态;个性签名;头像\n\t\tStringBuffer sb=new StringBuffer();\n\t\tString userName=tcp.getClientName();\n\t\tUsers users=userDao.queryByName(userName);//从数据库中查询用户信息\n\t\tsb.append(userName+MyTools.SPLIT2//用户名\n\t\t\t\t+tcp.getUserState()+MyTools.SPLIT2//状态\n\t\t\t\t+users.getSignature()+MyTools.SPLIT2//签名\n\t\t\t\t+users.getHeadImg());//头像\n\t\tString userInfo=new String(sb);//返回当前登录用户自己的信息\n\t\treturn userInfo;\n\t}\n\t/**\n\t * 将所有用户的信息转换成字符串\n\t * @return\n\t */\n\tpublic String getAllUsersInfo()\n\t{\n\t\t//示例：刘显安,192.168.1.1,8888;吴志强,192.168.1.2,6666\n\t\tStringBuffer sb=new StringBuffer();\n\t\tsb.append(\"所有在线用户\"+MyTools.SPLIT2+\"所有不在线用户\"+MyTools.SPLIT2+\"我的好友\"+MyTools.SPLIT1);\n\t\tfor(TCP tcp:tcpSockets)\n\t\t{\n\t\t\tif(tcp.getUserState()!=4)//因为4表示隐身\n\t\t\t{\n\t\t\t\tSystem.out.println(\"客户端名\"+tcp.getClientName());\n    \t\t\tsb.append(tcp.getClientName()+MyTools.SPLIT3//用户名\n    \t\t\t\t\t+tcp.getClientIP()+MyTools.SPLIT3//IP\n    \t\t\t\t\t+tcp.getClientServerPort()+MyTools.SPLIT3//端口号\n    \t\t\t\t\t+userDao.queryByName(tcp.getClientName()).getHeadImg()+MyTools.SPLIT3//头像\n    \t\t\t\t\t+tcp.getUserState()+MyTools.SPLIT2);//用户状态\n\t\t\t}\n\t\t}\n\t\tString onlineUser=new String(sb);\n\t\tonlineUser=onlineUser.substring(0,onlineUser.length()-1);//去掉最后一个逗号\n\t\tonlineUser+=MyTools.SPLIT1;//加上一个分号\n\t\t\n\t\t\n\t\tsb=new StringBuffer();\n\t\tArrayList<Users> userList=userDao.queryAll();\n\t\tfor(Users users:userList)\n\t\t{\n\t\t\tif(users.getState().equals(\"-1\")||users.getState().equals(\"4\")||users.getState()==null)\n\t\t\t{\n\t\t\t\tsb.append(users.getName()+MyTools.SPLIT3\n\t\t\t\t\t\t+\"下线或隐身\"+MyTools.SPLIT3\n\t\t\t\t\t\t+\"0\"+MyTools.SPLIT3\n\t\t\t\t\t\t+users.getHeadImg()+MyTools.SPLIT3\n\t\t\t\t\t\t+\"-1\"+MyTools.SPLIT2);\n\t\t\t}\n\t\t}\n\t\tString underlineUser=new String(sb);\n\t\tif(!underlineUser.equals(\"\"))\n\t\t\tunderlineUser=underlineUser.substring(0,underlineUser.length()-1);//去掉最后一个逗号\n\t\tunderlineUser+=MyTools.SPLIT1;//加上一个分号\n\t\t\n\t\tString myfriend=\"无\";\n\t\t\n\t\treturn onlineUser+underlineUser+myfriend;\n\t}\n\t\n\t/**\n\t * 显示当前在线人数\n\t */\n\tpublic void showOnlineNumber()\n\t{\n\t\tSystem.out.println(\"当前总在线人数：\"+tcpSockets.size());\n\t}\n\t\n\tpublic void doQunChat(String message,TCP tcp)\n\t{\n\t\tfor(TCP t:tcpSockets)\n\t\t\tt.sendMessage(Flag.QUN_CHAT+MyTools.FLAGEND+message);\n\t}\n\t\n\t/**\n\t * 处理用户发来的离线消息\n\t * @param message\n\t * @param tcp\n\t */\n\tpublic void doUnderlineMessage(String message,TCP tcp)\n\t{\n\t\tint sendFrom=userDao.queryByName(tcp.getClientName()).getId();\n\t\tint sendTo=userDao.queryByName(message.split(MyTools.SPLIT1)[0]).getId();\n\t\tMsg msg=new Msg(message.split(MyTools.SPLIT1)[1],sendFrom,sendTo,\"\", \"\");\n\t\ttry\n\t\t{\n\t\t\tmsgDao.insertMsg(msg);\n\t\t}\n\t\tcatch (SQLException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * 给用户发送未读消息\n\t */\n\tpublic void sendUnreadMessage(TCP tcp)\n\t{\n\t\tString userName=tcp.getClientName();\n\t\tint userID=userDao.queryByName(userName).getId();\n\t\tArrayList<Msg> msgs=(ArrayList<Msg>) msgDao.selectMsgBySendTo(userID);\n\t\tStringBuffer sb=new StringBuffer();\n\t\tsb.append(Flag.UNDERLINE_MESSAGE+MyTools.FLAGEND);\n\t\tif(msgs.size()>0)\n\t\t{\n\t\t\tfor(Msg msg:msgs)\n\t\t\t{\n\t\t\t\tsb.append(userDao.queryById(msg.getSendFrom()).getName()+\"(\"\n\t\t\t\t\t\t+msg.getSendTime()+\"):\\n\"\n\t\t\t\t\t\t+msg.getMsgContent()+\"\\n\");\n\t\t\t}\n\t\t\tString unreadMessage=new String(sb);\n\t\t\ttcp.sendMessage(unreadMessage);\n\t\t\tSystem.out.println(\"给用户发送未读离线消息成功！\");\n\t\t\tmsgDao.deleteMsgBySendTO(userID);\n\t\t\tSystem.out.println(\"删除用户未读消息成功！\");\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * 发送聊天室公告\n\t * @param message\n\t */\n\tpublic void sendPublicMessage(String message)\n\t{\n\t\tfor(TCP t:tcpSockets)\n\t\t\tt.sendMessage(Flag.PUBLIC_MESSAGE+MyTools.FLAGEND+message);\n\t\tJOptionPane.showMessageDialog(null, \"公告发布成功！\",\"恭喜\",JOptionPane.INFORMATION_MESSAGE);\n\t}\n\t/**\n\t * 发送弹窗公告\n\t * @param message\n\t */\n\tpublic void sendShowWindow(String message)\n\t{\n\t\tfor(TCP t:tcpSockets)\n\t\t\tt.sendMessage(Flag.SHOW_WINDOW+MyTools.FLAGEND+message);\n\t\tJOptionPane.showMessageDialog(null, \"弹窗公告发布成功！\",\"恭喜\",JOptionPane.INFORMATION_MESSAGE);\n\t}\n\t\n}\n"
  },
  {
    "path": "src/server/common/JDBC.java",
    "content": "package server.common;\n\nimport java.awt.List;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.sql.Connection;\nimport java.sql.DriverManager;\nimport java.sql.PreparedStatement;\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport java.sql.Statement;\nimport java.util.Properties;\n\nimport com.MyTools;\n\npublic class JDBC\n{\n\tpublic Connection con = null;\n\tpublic PreparedStatement preSta = null;\n\tpublic ResultSet result = null;\n\t\n\t/**\n\t * 无参的构造方法\n\t */\n\tpublic JDBC()\n\t{\n\t\tgetConnection();\n\t}\n\t\n\t/**\n\t * 有参的构造方法\n\t * @param url\n\t * @param user 用户名\n\t * @param password \n\t */\n\tpublic JDBC(String url,String user,String password)\n\t{\n\t\tgetConnection(url,user,password);\n\t}\n\t\n\t/**\n\t * 获取连接\n\t * @param url 连接数据库的URL\n\t * @param user 用户名\n\t * @param password 密码\n\t * @return\n\t */\n\tprivate Connection getConnection(String url,String user,String password)\n\t{\n\t\ttry\n\t\t{\n\t\t\tClass.forName(\"com.mysql.jdbc.Driver\");\n\t\t\tSystem.out.println(\"开始尝试连接数据库！\");\n\t\t\tcon = DriverManager.getConnection(url, user, password);\n\t\t\tSystem.out.println(\"连接成功！\");\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\tSystem.out.println(\"执行数据库操作报错！\");\n\t\t\t e.printStackTrace();\n\t\t}\n\t\treturn con;\n\t}\n\t/**\n\t * 使用默认的参数获取数据库的连接\n\t * @return\n\t */\n\tprivate Connection getConnection()\n\t{\n\t\treturn getConnection(MyTools.JDBC_URL, MyTools.JDBC_USER, MyTools.JDBC_PWD);\n\t}\n\t/**\n\t * 关闭数据库的连接\n\t */\n\tpublic void closeConnection()\n\t{\n\t\ttry\n\t\t{\n\t\t\tif(result!=null)\n\t\t\t\tresult.close();\n\t\t\tif(preSta!=null)\n\t\t\t\tpreSta.close();\n\t\t\tif (con != null)\n\t\t\t\tcon.close();\n\t\t\tSystem.out.println(\"数据库连接已关闭！\");\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t/**\n\t * 执行数据库的更新操作\n\t * @param sql 需要执行的预编译语句\n\t * @param params 预编译语句的参数列表\n\t * @return 受影响的行数\n\t * @throws SQLException \n\t */\n\tpublic int update(String sql,String[] params) throws SQLException\n\t{\n\t\tint count=0;\n\t\tpreSta=con.prepareStatement(sql);\n\t\tif(params!=null)\n\t\t{\n\t\t\tfor(int i=0;i<params.length;i++)\n\t\t\t\tpreSta.setString(i+1, params[i]);\n\t\t}\n\t\tcount=preSta.executeUpdate();\n\t\treturn count;\n\t}\n\t/**\n\t * 执行数据库的查询操作\n\t * @param sql 需要执行的预编译语句\n\t * @param params 预编译语句的参数列表\n\t * @return 返回查询的结果集，类型为ResultSet\n\t * @throws SQLException \n\t */\n\tpublic ResultSet query(String sql,String[] params)\n\t{\n\t\ttry\n\t\t{\n\t\t\tpreSta=con.prepareStatement(sql);\n\t\t\tif(params!=null)\n\t\t\t{\n\t\t\t\tfor(int i=0;i<params.length;i++)\n\t\t\t\t\tpreSta.setString(i+1, params[i]);\n\t\t\t}\n\t\t\tresult=preSta.executeQuery();\n\t\t}\n\t\tcatch (SQLException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\treturn result;\n\t}\n\t/**\n\t * 写入配置文件\n\t * @param url jdbc连接域名\n\t * @param user 用户名\n\t * @param password 密码\n\t */\n\tpublic static void writeProperties(String url,String user,String password)\n\t{\n\t\tProperties pro=new Properties();\n\t\tFileOutputStream fileOut=null;\n\t\ttry\n\t\t{\n\t\t\tfileOut=new FileOutputStream(\"Config.ini\");\n\t\t\tpro.put(\"url\", url);\n\t\t\tpro.put(\"user\", user);\n\t\t\tpro.put(\"password\", password);\n\t\t\tpro.store(fileOut, \"My Config\");\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\t\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif(fileOut!=null)\n\t\t\t\t\tfileOut.close();\n\t\t\t}\n\t\t\tcatch (IOException e)\n\t\t\t{\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t * 读取配置文件\n\t * @return 返回list\n\t */\n\tpublic static List readProperties()\n\t{\n\t\tList list=new List();\n\t\tProperties pro=new Properties();\n\t\tFileInputStream fileIn=null;\n\t\ttry\n\t\t{\n\t\t\tfileIn=new FileInputStream(\"Config.ini\");\n\t\t\tpro.load(fileIn);\n\t\t\tlist.add(pro.getProperty(\"url\"));\n\t\t\tlist.add(pro.getProperty(\"user\"));\n\t\t\tlist.add(pro.getProperty(\"password\"));\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\t\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif(fileIn!=null)\n\t\t\t\t\tfileIn.close();\n\t\t\t}\n\t\t\tcatch (IOException e)\n\t\t\t{\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t\treturn list;\n\t}\n}\n"
  },
  {
    "path": "src/server/common/Page.java",
    "content": "﻿package server.common;\n\npublic class Page {\n\tprivate int totalRecords;   //总记录数\n\tprivate int totalPage;     //总页数\n\tprivate int pageSize;     //每页显示几条记录\n\tpublic static int currentPage;  //当前页\n\tpublic int getTotalRecords() {\n\t\treturn totalRecords;\n\t}\n\tpublic void setTotalRecords(int totalRecords) {\n\t\tthis.totalRecords = totalRecords;\n\t}\n\tpublic int getTotalPage() {\n\t\treturn totalPage;\n\t}\n\tpublic void setTotalPage(int totalPage) {\n\t\tthis.totalPage = totalPage;\n\t}\n\tpublic int getPageSize() {\n\t\treturn pageSize;\n\t}\n\tpublic void setPageSize(int pageSize) {\n\t\tthis.pageSize = pageSize;\n\t}\n\tpublic int getCurrentPage() {\n\t\treturn currentPage;\n\t}\n\tpublic void setCurrentPage(int currentPage) {\n\t\tPage.currentPage = currentPage;\n\t}\n\t\n\t\n\t\n}\n"
  },
  {
    "path": "src/server/common/PageService.java",
    "content": "﻿package server.common;\n\nimport java.util.ArrayList;\nimport java.util.List;\npublic class PageService {\n\tPage page;   //定义一个page的封闭类\n\tList listAll; //把总记录数从页面传过来\n\tpublic PageService(List listAll) {\n\t\tthis.listAll = listAll;\n\t\tinitPage();\n\t}\n/**\n * 初始化分页\n * \n */\n\tprivate void initPage() {\n\t\tpage = new Page();\n\t\tpage.setCurrentPage(0);  //初始化分页的当前第0页\n\t\tpage.setPageSize(5);    //设置每页\n\t\tpage.setTotalRecords(listAll.size());  //获取页面传过来的总记录数\n\t\t\n\t\t/**\n\t\t * 计算总页数，第一种： (总记录数+每页显示记录数-1）/每页显示记录数\n\t\t * \n\t\t * 第二种\n\t\t * if(总记录数%每页显示的记录数！=0)\n\t\t *   总页数=总记录数/每页显示的记录数+1\n\t\t * else\n\t\t *   总页数=总记录数/每页显示的记录数\n\t\t */\n\t\tint totalPage = page.getTotalRecords() / page.getPageSize();\n\t\tif (page.getTotalRecords() % page.getPageSize() != 0) {\n\t\t\ttotalPage++;\n\t\t}        \n\t\tpage.setTotalPage(totalPage);\n\n\t}\n\t\n\t/**\n\t * 当页面是第一页的时候 ，继续点击上一页出现的情况 \n\t * 传一个值 ，如果值 小于等于0，就返回第一页\n\t * 当页面是最后一页的时候 ，继续点击上一页出现的情况 \n\t * 如果 这个值大于总页数，就返回最后一页\n\t * 记录每页从哪一条记录开始 \n\t * @param target\n\t * @return\n\t */\n\tpublic List gotoPage(int target) {\n\t\tif (target <= 0) {\n\t\t\ttarget = 0;\n\t\t} else if (target >= page.getTotalPage() - 1) {\n\t\t\ttarget = page.getTotalPage() - 1;\n\t\t}\n\t\tpage.setCurrentPage(target);\n\t\tList listPerPage = new ArrayList();\n\t\tfor (int i = target * page.getPageSize(); (i < (target + 1)\n\t\t\t\t* page.getPageSize())\n\t\t\t\t&& (i < page.getTotalRecords()); i++) {\n\t\t\tlistPerPage.add(listAll.get(i));\n\t\t}\n\t\treturn listPerPage;\n\t}\n\t/**\n\t * 跳转到首页\n\t * @return\n\t */\n\tpublic List gotoFirst(){\n\t\treturn this.gotoPage(0);\n\t}\n\t/**\n\t * 跳转到下一页\n\t * @return\n\t */\n\tpublic List gotoNext(){\n\t\treturn this.gotoPage(page.getCurrentPage()+1);\n\t}\n\t/**\n\t * 跳转到上一页，只要当前页-1\n\t * @return\n\t */\n\tpublic List gotoPre(){\n\t\treturn this.gotoPage(page.getCurrentPage()-1);\n\t\t\n\t}\n\t/**\n\t * 跳转到最后 一页，获取page的totalPage就是最后一页\n\t * @return\n\t */\n\tpublic List gotoLast(){\n\t\treturn this.gotoPage(page.getTotalPage()-1);\n\t}\n\tpublic int getTotalPage()\n\t{\n\t\treturn page.getTotalPage();\n\t}\n\tpublic int getCurrentPage()\n\t{\n\t\treturn page.getCurrentPage();\n\t}\n\tpublic int getTotalRecord()\n\t{\n\t\treturn page.getTotalRecords();\n\t}\n\tpublic int getPageSize()\n\t{\n\t\treturn page.getPageSize();\n\t}\n}\n"
  },
  {
    "path": "src/server/dao/IMsg.java",
    "content": "﻿package server.dao;\n\nimport java.sql.SQLException;\nimport java.util.List;\n\nimport server.entity.Msg;\n\npublic interface IMsg\n{\n\tpublic boolean insertMsg(Msg msg)throws SQLException;\n\tpublic boolean deleteMsg(int msgId)throws SQLException;\n\tpublic int updateMsg(Msg msg)throws SQLException;\n\tpublic Msg selectAMsg(int msgId);\n\tpublic List<Msg> selectMsgs(String sql);\n}\n"
  },
  {
    "path": "src/server/dao/IUser.java",
    "content": "﻿package server.dao;\n\n\n\nimport java.sql.SQLException;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport server.entity.Users;\n\n/**\n * @author Administrator\n *用户类数据库操作接口\n */\npublic interface IUser {\n\t/**\n\t * @param userid\n\t * @return根据用户编号查询单条用户数据\n\t */\n\tpublic Users queryById(int usersid) ;\n\t/**\n\t * @return查询所有用户信息\n\t */\n\tpublic List<Users> queryAll() ;\n\t\n\t/**\n\t * @param user\n\t * @return返回是否添加成功\n\t */\n\tpublic boolean add(Users user)throws SQLException;\n\t/**\n\t * @param user\n\t * @return返回是否修改成功\n\t */\n\tpublic boolean update(Users user)throws SQLException;\n\t/**\n\t * @param userid\n\t * @return返回是否删除成功\n\t */\n\tpublic boolean delete(int usersid)throws SQLException;\n\t/**\n\t * 检测用户名是否已存在\n\t * @param name\n\t * @return\n\t */\n\tpublic boolean checkUserIsExit(String name);\n\t/**\n\t * 检测用户名或密码是否正确\n\t * @param name\n\t * @param password\n\t * @return\n\t */\n\tpublic boolean checkNameAndPwd(String name,String password);\n\t/**\n\t * 更新用户状态\n\t * @param name\n\t * @param state\n\t * @return\n\t */\n\tpublic boolean updateUserState(String name,String state);\n\t/**\n\t * @param userid\n\t * @return根据用户编号查询单条用户数据\n\t */\n\tpublic Users queryByName(String name);\n}\n"
  },
  {
    "path": "src/server/dao/MsgDao.java",
    "content": "package server.dao;\n\n\nimport java.sql.Date;\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\n\nimport java.text.DateFormat;\n\nimport java.util.List;\n\nimport javax.naming.spi.DirStateFactory.Result;\n\nimport server.common.JDBC;\nimport server.entity.Msg;\n\npublic class MsgDao implements IMsg\n{\n\tJDBC jdbc = new JDBC();\n\n\tpublic boolean insertMsg(Msg msg) throws SQLException\n\t{\n\t\tString sql  = \"insert into msg(msg_content,msg_sendfrom,msg_sendto,msg_sendtime,msg_remark,msg_type) values (?,?,?,CURRENT_TIMESTAMP,?,?)\";\n\t\tString[] strArr = new String[]{msg.getMsgContent(), String.valueOf(msg.getSendFrom()),\n\t\t\t\tString.valueOf(msg.getSendTo()), msg.getRemark(), msg.getMsgTye(),\n\t\t\t\t\t\t};\n\t\tif(jdbc.update(sql, strArr) > 0)\n\t\t\treturn true;\n\t\treturn false;\n\t}\n\t\n\t@Override\n\tpublic boolean deleteMsg(int msgId) throws SQLException\n\t{\n\t\tString sql = \"delete from msg where msg_id = ?\";\n\t\treturn jdbc.update(sql, new String[]{ String.valueOf(msgId) })>0;\n\t}\n\t\n\t@Override\n\tpublic int updateMsg(Msg msg) throws SQLException\n\t{\n\t\t// 定义日期时间格式\n\t\tSimpleDateFormat sdf = new SimpleDateFormat(\"yyyy-MM-dd\");\n\t\tString sql = \"update msg set MSG_CONTENT = ? , MSG_SENDFROM = ? ,MSG_SENDTO =?\"\n\t\t\t\t+\",MSG_REMARK = ?  ,MSG_TYPE = ? where msg_id = ?\";\n\t\tString[] strArr = new String[]\n\t\t{ msg.getMsgContent(), String.valueOf(msg.getSendFrom()),\n\n\t\tString.valueOf(msg.getSendTo()), msg.getRemark(), msg.getMsgTye(),\n\t\t\t\tString.valueOf(msg.getMsgId()) };\n\n\t\t// System.out.println(new java.util.Date());\n\t\treturn jdbc.update(sql, strArr);\n\t}\n\t@Override\n\tpublic Msg selectAMsg(int msgId)\n\t{\n\t\tResultSet rs = null;\n\t\tString sql = \"select * from MSG where MSG_ID = ?\";\n\n\t\trs = jdbc.query(sql, new String[]\n\t\t{ String.valueOf(msgId) });\n\t\ttry\n\t\t{\n\t\t\tif (rs.next())\n\t\t\t{\n\t\t\t\tString msgContent = rs.getString(\"MSG_CONTENT\");\n\t\t\t\tint sendFrom = rs.getInt(\"MSG_SENDFROM\");\n\t\t\t\tint sendTo = rs.getInt(\"MSG_SENDTO\");\n\t\t\t\tString sendTime = rs.getString(\"MSG_SENDTIME\");\n\t\t\t\tString remark = rs.getString(\"MSG_REMARK\");\n\t\t\t\tString msgType = rs.getString(\"MSG_TYPE\");\n\n\t\t\t\tMsg msg = new Msg(msgContent, sendFrom, sendTo, sendTime,\n\t\t\t\t\t\tremark, msgType);\n\t\t\t\treturn msg;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn null;\n\n\t\t}\n\t\tcatch (SQLException e)\n\t\t{\n\n\t\t\te.printStackTrace();\n\t\t\treturn null;\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tjdbc.closeConnection();\n\t\t}\n\t}\n\n\t@Override\n\tpublic ArrayList<Msg> selectMsgs(String sql)\n\t{\n\t\tArrayList<Msg> list = new ArrayList<Msg>();\n\n\t\tResultSet rs = null;\n\n\t\trs = jdbc.query(sql, null);\n\t\ttry\n\t\t{\n\t\t\twhile (rs.next())\n\t\t\t{\n\t\t\t\tint msg_id = rs.getInt(1);\n\t\t\t\tString msgContent = rs.getString(2);\n\t\t\t\tint sendFrom = rs.getInt(3);\n\t\t\t\tint sendTo = rs.getInt(4);\n\t\t\t\tString sendTime = rs.getString(5);\n\t\t\t\tString remark = rs.getString(6);\n\t\t\t\tString msgType = rs.getString(7);\n\n\t\t\t\tMsg msg = new Msg(msg_id, msgContent, sendFrom, sendTo,\n\t\t\t\t\t\tsendTime, remark, msgType);\n\t\t\t\tlist.add(msg);\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\t\tcatch (SQLException e)\n\t\t{\n\n\t\t\te.printStackTrace();\n\t\t\treturn null;\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tjdbc.closeConnection();\n\t\t}\n\t}\n\t/*public ArrayList<Msg> QueryMessageBySendTO(int sendTo)\n\t{\n\t\treturn selectMsgs(\"select * from MSG where MSG_SENDTO = \"+sendTo);\n\t}*/\n\n\tpublic boolean deleteMsgBySendTO(int sendto) \n\t{\n\t\ttry\n\t\t{\n\t\t\tString sql = \"delete from msg where msg_sendto = ?\";\n\t\t\treturn jdbc.update(sql, new String[]{ sendto+\"\"})>0;\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t\treturn false;\n\t\t}\n\t}\n\t/**\n\t * WZQ写的\n\t * @param sendto\n\t * @return\n\t */\n\tpublic List<Msg> selectMsgBySendTo(int sendto)\n\t{\n\t\tResultSet rs = null;\n\t\tString sql = \"select * from MSG where MSG_SENDTO = ?\";\n\t\tList<Msg> list=new ArrayList<Msg>();\n\t\trs = jdbc.query(sql, new String[]\n\t\t{ String.valueOf(sendto) });\n\t\ttry\n\t\t{\n\t\t\twhile (rs.next())\n\t\t\t{\n\t\t\t\tString msgContent = rs.getString(\"MSG_CONTENT\");\n\t\t\t\tint sendFrom = rs.getInt(\"MSG_SENDFROM\");\n\t\t\t\tint sendTo = rs.getInt(\"MSG_SENDTO\");\n\t\t\t\tString sendTime = rs.getString(\"MSG_SENDTIME\");\n\t\t\t\tString remark = rs.getString(\"MSG_REMARK\");\n\t\t\t\tString msgType = rs.getString(\"MSG_TYPE\");\n\t\t\t\tMsg msg = new Msg(msgContent, sendFrom, sendTo, sendTime,\n\t\t\t\t\t\tremark, msgType);\n\t\t\t\tlist.add(msg);\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\t\tcatch (SQLException e)\n\t\t{\n\n\t\t\te.printStackTrace();\n\t\t\treturn null;\n\t\t}\n\t\tfinally\n\t\t{\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "src/server/dao/UserDao.java",
    "content": "package server.dao;\n\nimport java.sql.Date;\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport server.common.JDBC;\nimport server.entity.Users;\n\npublic class UserDao implements IUser {\n\tJDBC con = new JDBC();\n\n\t@Override\n\tpublic boolean add(Users user) throws SQLException \n\t{\n\t\tDate birth = user.getBirthday();\n\t\tString sql=\"insert into users(u_name,u_pwd,u_gender,u_email,u_remarke,u_signature,u_head_Img,u_type,u_birthday) values (?,?,?,?,?,?,?,?,?)\";\n\t\tString[] params={user.getName(),user.getPwd(),user.getGender(),user.getEmail(),user.getRemarke(),user.getSignature(),user.getHeadImg(),user.getType(),user.getBirthday().toString()};\n\t\treturn con.update(sql,params)>0;\n\t}\n\n\t@Override\n\tpublic boolean delete(int usersid) throws SQLException\n\t{\n\t\tString sql=\"delete from users where U_ID =?\";\n\t\tif(con.update(sql, new String[]{String.valueOf(usersid)})>0)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\telse \n\t\t{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic boolean update(Users user)\n\t{\n\t\tint result = 0;\n\t\tSimpleDateFormat sdf = new SimpleDateFormat(\"yyyy-MM-dd\");\n\t\tsdf.format(user.getBirthday().getTime());\n\t\ttry\n\t\t{\n\t\t\tresult = con.update(\"update users set u_name = ?, u_pwd = ?, u_gender = ?, \" +\n\t\t\t\t\t\"u_email = ?,\" +\n\t\t\t\t\t\" u_remarke = ?, u_signature = ?, u_head_img = ?, u_type = ?,\" +\n\t\t\t\t\t\" u_birthday = to_date('\"+user.getBirthday()+\"','yyyy-mm-dd') where u_id = ?\", new String[]{user.getName(),\n\t\t\t\t\tuser.getPwd(),user.getGender(),user.getEmail()\n\t\t\t\t\t,user.getRemarke(),\n\t\t\t\t\tuser.getSignature(),user.getHeadImg(),user.getType(),\n\t\t\t\t\tString.valueOf(user.getId())});\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\treturn result>0;\n\t}\n\n\t@Override\n\tpublic ArrayList<Users> queryAll()\n\t{\n\t\tUsers user = null;\n\t\tArrayList<Users> list = new ArrayList<Users>();\n\t\tResultSet rs = con.query(\"select * from users order by u_id\", null);\n\t\ttry \n\t\t{\n\t\t\t// 开始遍历获取数据\n\t\t\twhile (rs.next())\n\t\t\t{\n\t\t\t\tuser = new Users();// 如果找到数据，创建用户对象\n\t\t\t\tuser.setId(rs.getInt(\"u_id\"));\n\t\t\t\tuser.setName(rs.getString(\"u_name\"));\n\t\t\t\tuser.setPwd(rs.getString(\"u_pwd\"));\n\t\t\t\tuser.setGender(rs.getString(\"u_gender\"));\n\t\t\t\tuser.setEmail(rs.getString(\"u_email\"));\n\t\t\t\tuser.setLastLogin(rs.getString(\"u_last_login\"));\n\t\t\t\tuser.setLastExit(rs.getString(\"u_last_exit\"));\n\t\t\t\tuser.setRemarke(rs.getString(\"u_remarke\"));\n\t\t\t\tuser.setSignature(rs.getString(\"u_signature\"));\n\t\t\t\tuser.setHeadImg(rs.getString(\"u_head_Img\"));\n\t\t\t\tuser.setBirthday(rs.getDate(\"u_birthday\"));\n\t\t\t\tuser.setType(rs.getString(\"u_type\"));\n\t\t\t\tuser.setState(rs.getString(\"u_state\"));\n\t\t\t\tuser.setIp(rs.getString(\"u_ip\"));\n\t\t\t\tlist.add(user);\n\t\t\t}\n\t\t}\n\t\tcatch (SQLException e) \n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\tfinally \n\t\t{\n\t\t\t//con.closeConnection();// 关闭所有数据库对象\n\t\t}\n\t\treturn list;\n\t}\n\n\n\tpublic Users queryById(int usersid)\n\t{\n\t\tUsers user = null;\n\t\tResultSet rs = con.query(\"select * from users where u_id=? \",\n\t\t\t\tnew String[] { String.valueOf(usersid) });\n\t\ttry {\n\t\t\t// 开始遍历获取数据\n\t\t\twhile (rs.next()) {\n\t\t\t\tuser = new Users();// 如果找到数据，创建用户对象\n\t\t\t\tuser.setId(rs.getInt(\"u_id\"));\n\t\t\t\tuser.setName(rs.getString(\"u_name\"));\n\t\t\t\tuser.setPwd(rs.getString(\"u_pwd\"));\n\t\t\t\tuser.setGender(rs.getString(\"u_gender\"));\n\t\t\t\tuser.setEmail(rs.getString(\"u_email\"));\n\t\t\t\tuser.setLastLogin(rs.getString(\"u_last_login\"));\n\t\t\t\tuser.setLastExit(rs.getString(\"u_last_exit\"));\n\t\t\t\tuser.setRemarke(rs.getString(\"u_remarke\"));\n\t\t\t\tuser.setSignature(rs.getString(\"u_signature\"));\n\t\t\t\tuser.setHeadImg(rs.getString(\"u_head_Img\"));\n\t\t\t\tuser.setBirthday(rs.getDate(\"u_birthday\"));\n\t\t\t\tuser.setType(rs.getString(\"u_type\"));\n\t\t\t}\n\t\t} \n\t\tcatch (SQLException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t} \n\t\tfinally\n\t\t{\n\t\t\t//con.closeConnection();// 关闭所有数据库对象\n\t\t}\n\t\treturn user;\n\t}\n\tpublic Users queryByName(String userName)\n\t{\n\t\tUsers user = null;\n\t\tResultSet rs = con.query(\"select * from users where u_name=?\",\n\t\t\t\tnew String[]{userName});\n\t\ttry \n\t\t{\n\t\t\t// 开始遍历获取数据\n\t\t\twhile (rs.next()) {\n\t\t\t\tuser = new Users();// 如果找到数据，创建用户对象\n\t\t\t\tuser.setId(rs.getInt(\"u_id\"));\n\t\t\t\tuser.setName(rs.getString(\"u_name\"));\n\t\t\t\tuser.setPwd(rs.getString(\"u_pwd\"));\n\t\t\t\tuser.setGender(rs.getString(\"u_gender\"));\n\t\t\t\tuser.setEmail(rs.getString(\"u_email\"));\n\t\t\t\tuser.setLastLogin(rs.getString(\"u_last_login\"));\n\t\t\t\tuser.setLastExit(rs.getString(\"u_last_exit\"));\n\t\t\t\tuser.setRemarke(rs.getString(\"u_remarke\"));\n\t\t\t\tuser.setSignature(rs.getString(\"u_signature\"));\n\t\t\t\tuser.setHeadImg(rs.getString(\"u_head_Img\"));\n\t\t\t\tuser.setBirthday(rs.getDate(\"u_birthday\"));\n\t\t\t\tuser.setType(rs.getString(\"u_type\"));\n\t\t\t}\n\t\t}\n\t\tcatch (SQLException e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\tfinally \n\t\t{\n\t\t\t//con.closeConnection();// 关闭所有数据库对象\n\t\t}\n\t\treturn user;\n\t}\n\n\t/* \n\t * 检测用户是否已存在\n\t */\n\t@Override\n\tpublic boolean checkUserIsExit(String name)\n\t{\n\t\ttry\n\t\t{\n\t\t\tResultSet rs = con.query(\"select * from users where u_name=? \",\n\t\t\t\t\tnew String[] { name});\n\t\t\tif(rs.next())\n\t\t\t\treturn true;\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t\treturn false;\n\t\t}\n\n\t}\n\n\t@Override\n\tpublic boolean checkNameAndPwd(String name, String password)\n\t{\n\t\ttry\n\t\t{\n\t\t\tResultSet rs = con.query(\"select * from users where u_name=? and u_pwd=? \",\n\t\t\t\t\tnew String[] { name,password});\n\t\t\tif(rs.next())\n\t\t\t\treturn true;\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/* \n\t * 更新用户状态\n\t */\n\t@Override\n\tpublic boolean updateUserState(String name, String state)\n\t{\n\t\tint result = 0;\n\t\ttry\n\t\t{\n\t\t\tresult = con.update(\"update users set u_state = ? where u_name = ?\",new String[]{state,name});\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t\treturn result>0;\n\t}\n\t\n\tpublic void setLastLogin(String name)\n\t{\n\t\tString sql=\"update users set u_last_login=CURRENT_TIMESTAMP where u_name=?\";\n\t\ttry {\n\t\t\tcon.update(sql, new String[]{name});\n\t\t} catch (Exception e) {\n\t\t\t// TODO Auto-generated catch block\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\tpublic void setLastExit(String name)\n\t{\n\t\tString sql=\"update users set u_last_exit=CURRENT_TIMESTAMP where u_name=?\";\n\t\ttry {\n\t\t\tcon.update(sql, new String[]{name});\n\t\t} catch (Exception e) {\n\t\t\t// TODO Auto-generated catch block\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\tpublic void setUserState(String name,int i)\n\t{\n\t\tString sql=\"update users set u_state=? where u_name=?\";\n\t\ttry \n\t\t{\n\t\t\tcon.update(sql, new String[]{String.valueOf(i),name});\n\t\t}\n\t\tcatch (Exception e) \n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\tpublic void setIP(String IP,String name)\n\t{\n\t\tString sql=\"update users set u_ip=? where u_name=?\";\n\t\ttry \n\t\t{\n\t\t\tcon.update(sql, new String[]{IP,name});\n\t\t} \n\t\tcatch (Exception e) \n\t\t{\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "src/server/entity/Msg.java",
    "content": "﻿package server.entity;\n\nimport java.sql.Date;\n\npublic class Msg\n{\n\tprivate int msgId;\n\tprivate String msgContent;\n\tprivate int sendFrom;//信息发送者\n\tprivate int sendTo;//信息接收者\n\tprivate String sendTime;//信息发送时间\n\tprivate String remark;\n\tprivate String msgTye;//信息类型：离线消息和群公告\n\t\n\t@Override\n\tpublic String toString()\n\t{\n\t\t// TODO Auto-generated method stub\n\t\treturn \"消息的全部信息是：\\n\"+\"msgId:\"+msgId+\"  msgContent:\"+msgContent+\n\t\t\t\t\"  sendFrom:\"+sendFrom+\"  sendTo:\"+sendTo+\" sendTime :\"+sendTime+\n\t\t\t\t\"   remark:\"+remark+\"  msgTye:\"+msgTye;\n\t}\n\t\n\t\n\t/**\n\t * @param msgContent\n\t * @param sendFrom\n\t * @param sendTo\n\t * @param remark\n\t * @param msgTye\n\t * \n\t * 除msgId 和 sendTime 参数之外  的构造参数\n\t */\n\tpublic Msg(String msgContent, int sendFrom, int sendTo, String remark,\n\t\t\tString msgTye)\n\t{\n\t\tsuper();\n\t\tthis.msgContent = msgContent;\n\t\tthis.sendFrom = sendFrom;\n\t\tthis.sendTo = sendTo;\n\t\tthis.remark = remark;\n\t\tthis.msgTye = msgTye;\n\t}\n\n\t\n\t\n\t\n\n\t/**\n\t * @param msgId\n\t * @param msgContent\n\t * @param sendFrom\n\t * @param sendTo\n\t * @param remark\n\t * @param msgTye\n\t * \n\t *  含有除  sendTime参数的  构造函数\n\t */\n\tpublic Msg(int msgId, String msgContent, int sendFrom, int sendTo,\n\t\t\tString remark, String msgTye)\n\t{\n\t\tsuper();\n\t\tthis.msgId = msgId;\n\t\tthis.msgContent = msgContent;\n\t\tthis.sendFrom = sendFrom;\n\t\tthis.sendTo = sendTo;\n\t\tthis.remark = remark;\n\t\tthis.msgTye = msgTye;\n\t}\n\n\n\t\n\t/**\n\t * @param msgId\n\t * @param msgContent\n\t * @param sendFrom\n\t * @param sendTo\n\t * @param sendTime\n\t * @param remark\n\t * @param msgTye\n\t * 含有全部构造参数\n\t */\n\tpublic Msg(int msgId, String msgContent, int sendFrom, int sendTo,\n\t\t\tString sendTime, String remark, String msgTye)\n\t{\n\t\tsuper();\n\t\tthis.msgId = msgId;\n\t\tthis.msgContent = msgContent;\n\t\tthis.sendFrom = sendFrom;\n\t\tthis.sendTo = sendTo;\n\t\tthis.sendTime = sendTime;\n\t\tthis.remark = remark;\n\t\tthis.msgTye = msgTye;\n\t}\n\t\n\t/**\n\t * @param msgContent\n\t * @param sendFrom\n\t * @param sendTo\n\t * @param sendTime\n\t * @param remark\n\t * @param msgTye\n\t *   含有除msgId之外所有参数的构造方法\n\t */\n\tpublic Msg(String msgContent, int sendFrom, int sendTo, String sendTime,\n\t\t\tString remark, String msgTye)\n\t{\n\t\tsuper();\n\t\tthis.msgContent = msgContent;\n\t\tthis.sendFrom = sendFrom;\n\t\tthis.sendTo = sendTo;\n\t\tthis.sendTime = sendTime;\n\t\tthis.remark = remark;\n\t\tthis.msgTye = msgTye;\n\t}\n\tpublic Msg()\n\t{\n\t\t// TODO Auto-generated constructor stub\n\t}\n\n\tpublic int getMsgId()\n\t{\n\t\treturn msgId;\n\t}\n\tpublic void setMsgId(int msgId)\n\t{\n\t\tthis.msgId = msgId;\n\t}\n\tpublic String getMsgContent()\n\t{\n\t\treturn msgContent;\n\t}\n\tpublic void setMsgContent(String msgContent)\n\t{\n\t\tthis.msgContent = msgContent;\n\t}\n\tpublic int getSendFrom()\n\t{\n\t\treturn sendFrom;\n\t}\n\tpublic void setSendFrom(int sendFrom)\n\t{\n\t\tthis.sendFrom = sendFrom;\n\t}\n\tpublic int getSendTo()\n\t{\n\t\treturn sendTo;\n\t}\n\tpublic void setSendTo(int sendTo)\n\t{\n\t\tthis.sendTo = sendTo;\n\t}\n\tpublic String getSendTime()\n\t{\n\t\treturn sendTime;\n\t}\n\tpublic void setSendTime(String sendTime)\n\t{\n\t\tthis.sendTime = sendTime;\n\t}\n\tpublic String getRemark()\n\t{\n\t\treturn remark;\n\t}\n\tpublic void setRemark(String remark)\n\t{\n\t\tthis.remark = remark;\n\t}\n\tpublic String getMsgTye()\n\t{\n\t\treturn msgTye;\n\t}\n\tpublic void setMsgTye(String msgTye)\n\t{\n\t\tthis.msgTye = msgTye;\n\t}\n\t\n}\n"
  },
  {
    "path": "src/server/entity/Users.java",
    "content": "﻿package server.entity;\n\n\n\n\nimport java.sql.Date;\n\n/**\n * @author Administrator\n * 用户表的实体类\n */\npublic class Users\n{\n\tprivate int id;//主键\n\tprivate String name;//姓名\n\tprivate String pwd;//密码\n\tprivate String ip;//IP地址\n\tprivate String state;//状态，-1或空表示不在线，0表示在线，1表示Q我，2表示离开，3表示忙碌，4表示隐身\n\tprivate String gender;//性别\n\tprivate String email;//邮箱\n\tprivate String lastLogin;//最后一次登录\n\tprivate String lastExit;//最后一次退出\n\tprivate String remarke;//备用\n\tprivate String signature;//个性签名\n\tprivate String headImg;//头像\n\tprivate String type;//类型\n\tprivate Date birthday;//生日\n\t\n\n\tpublic Users() \n\t{\n\t\tsuper();\n\t}\n\t/**\n\t * @param id\t      \t用户ID\n\t * @param name\t\t\t用户名\n\t * @param pwd\t\t\t用户密码\n\t * @param gender\t\t用户性别\n\t * @param email\t\t\t用户e-mail\n\t * @param lastLogin\t\t用户最后一次登录时间\n\t * @param lastExit\t\t用户最后一次下线时间\n\t * @param remarke\t\t备注\n\t * @param signature\t\t用户签名\n\t * @param headImg\t\t用户头像\n\t * @param birthday\t\t用户生日\n\t * @param type\t\t\t用户类型（管理员/普通用户）\n\t */\n\tpublic Users(int id, String name, String pwd, String gender, String email, String remarke,\n\n\t\t\tString signature, String headImg, Date birthday,String type,String ip,String state) {\n\t\tsuper();\n\t\tthis.id = id;\n\t\tthis.name = name;\n\t\tthis.pwd = pwd;\n\t\tthis.gender = gender;\n\t\tthis.email = email;\n\t\tthis.remarke = remarke;\n\t\tthis.signature = signature;\n\t\tthis.headImg = headImg;\n\t\tthis.birthday = birthday;\n\t\tthis.type = type;\n\t\tthis.ip = ip;\n\t\tthis.state = state;\n\t}\n\t/**\n\t * 无用户ID的构造方法\n\t * @param name\n\t * @param pwd\n\t * @param gender\n\t * @param email\n\t * @param lastLogin\n\t * @param lastExit\n\t * @param nickName\n\t * @param remarke\n\t * @param signature\n\t * @param headImg\n\t * @param birthday\n\t */\n\t\n\tpublic Users(String name, String pwd, String gender, String email,\n\t\t\tString signature, String headImg, Date birthday) {\n\t\tsuper();\n\t\tthis.name = name;\n\t\tthis.pwd = pwd;\n\t\tthis.gender = gender;\n\t\tthis.email = email;\n\t\tthis.signature = signature;\n\t\tthis.headImg = headImg;\n\t\tthis.birthday = birthday;\n\t\tthis.state=-1+\"\";//将用户默认状态设为-1表示不在线\n\t}\n\t\n\tpublic Users(int id, String name, String pwd, String gender, String email,\n\t\t\tDate birthday) {\n\t\tsuper();\n\t\tthis.id = id;\n\t\tthis.name = name;\n\t\tthis.pwd = pwd;\n\t\tthis.gender = gender;\n\t\tthis.email = email;\n\t\tthis.birthday = birthday;\n\t}\n\t/**\n\t * @return the state\n\t */\n\tpublic String getState() {\n\t\treturn state;\n\t}\n\t/**\n\t * @param state the state to set\n\t */\n\tpublic void setState(String state) {\n\t\tthis.state = state;\n\t}\n\t/**\n\t * @return the ip\n\t */\n\tpublic String getIp() {\n\t\treturn ip;\n\t}\n\t/**\n\t * @param ip the ip to set\n\t */\n\tpublic void setIp(String ip) {\n\t\tthis.ip = ip;\n\t}\n\t/**\n\t * @return the type\n\t */\n\tpublic String getType() {\n\t\treturn type;\n\t}\n\t/**\n\t * @param type the type to set\n\t */\n\tpublic void setType(String type) {\n\t\tthis.type = type;\n\t}\n\t/**\n\t * @return the birthday\n\t */\n\tpublic Date getBirthday() {\n\t\treturn birthday;\n\t}\n\t/**\n\t * @param birthday the birthday to set\n\t */\n\tpublic void setBirthday(Date birthday) {\n\t\tthis.birthday = birthday;\n\t}\n\t/**\n\t * @return the id\n\t */\n\tpublic int getId() {\n\t\treturn id;\n\t}\n\t/**\n\t * @param id the id to set\n\t */\n\tpublic void setId(int id) {\n\t\tthis.id = id;\n\t}\n\t/**\n\t * @return the name\n\t */\n\tpublic String getName() {\n\t\treturn name;\n\t}\n\t/**\n\t * @param name the name to set\n\t */\n\tpublic void setName(String name) {\n\t\tthis.name = name;\n\t}\n\t/**\n\t * @return the pwd\n\t */\n\tpublic String getPwd() {\n\t\treturn pwd;\n\t}\n\t/**\n\t * @param pwd the pwd to set\n\t */\n\tpublic void setPwd(String pwd) {\n\t\tthis.pwd = pwd;\n\t}\n\t/**\n\t * @return the gender\n\t */\n\tpublic String getGender() {\n\t\treturn gender;\n\t}\n\t/**\n\t * @param gender the gender to set\n\t */\n\tpublic void setGender(String gender) {\n\t\tthis.gender = gender;\n\t}\n\t/**\n\t * @return the email\n\t */\n\tpublic String getEmail() {\n\t\treturn email;\n\t}\n\t/**\n\t * @param email the email to set\n\t */\n\tpublic void setEmail(String email) {\n\t\tthis.email = email;\n\t}\n\t/**\n\t * @return the lastLogin\n\t */\n\tpublic String getLastLogin() {\n\t\treturn lastLogin;\n\t}\n\t/**\n\t * @param lastLogin the lastLogin to set\n\t */\n\tpublic void setLastLogin(String lastLogin) {\n\t\tthis.lastLogin = lastLogin;\n\t}\n\t/**\n\t * @return the lastExit\n\t */\n\tpublic String getLastExit() {\n\t\treturn lastExit;\n\t}\n\t/**\n\t * @param lastExit the lastExit to set\n\t */\n\tpublic void setLastExit(String lastExit) {\n\t\tthis.lastExit = lastExit;\n\t}\n\t/**\n\t * @return the \n\t */\n\tpublic String getRemarke() {\n\t\treturn remarke;\n\t}\n\t/**\n\t * @param remarke \n\t */\n\tpublic void setRemarke(String remarke) {\n\t\tthis.remarke = remarke;\n\t}\n\t/**\n\t * @return the signature\n\t */\n\tpublic String getSignature() {\n\t\treturn signature;\n\t}\n\t/**\n\t * @param signature the signature to set\n\t */\n\tpublic void setSignature(String signature) {\n\t\tthis.signature = signature;\n\t}\n\t/**\n\t * @return the headImg\n\t */\n\tpublic String getHeadImg() {\n\t\treturn headImg;\n\t}\n\t/**\n\t * @param headImg the headImg to set\n\t */\n\tpublic void setHeadImg(String headImg) {\n\t\tthis.headImg = headImg;\n\t}\n\t\n\t\n\n}\n"
  },
  {
    "path": "src/server/frame/MainWindow.java",
    "content": "﻿package server.frame;\n\nimport java.awt.Dimension;\nimport java.awt.EventQueue;\nimport java.awt.Toolkit;\nimport java.awt.event.WindowAdapter;\nimport java.awt.event.WindowEvent;\n\nimport javax.swing.JFrame;\nimport javax.swing.JOptionPane;\nimport javax.swing.JPanel;\nimport javax.swing.UIManager;\nimport javax.swing.border.EmptyBorder;\nimport javax.swing.JTabbedPane;\nimport javax.swing.GroupLayout;\nimport javax.swing.GroupLayout.Alignment;\n\nimport client.control.Main;\n\nimport com.MyTools;\nimport javax.swing.ImageIcon;\n\npublic class MainWindow extends JFrame {\n\n\tprivate JPanel contentPane;\n\tprivate final JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.LEFT);\n\tUserMana userMana;\n\tMsgMana msgMana;\n\tServerMana serverMana;\n\t\n\t/**\n\t * 主方法\n\t */\n\tpublic static void main(String[] args) \n\t{\n\t\tMyTools.changeSkin();\n\t\tnew MainWindow().setVisible(true);\n\t}\n\n\t/**\n\t * Create the frame.\n\t */\n\tpublic MainWindow() \n\t{\n\t\tsetTitle(\"MyQQ\\u670D\\u52A1\\u5668\\u540E\\u53F0\\u7BA1\\u7406\");\n\t\tDimension size=Toolkit.getDefaultToolkit().getScreenSize();\n\t\t\n\t\tsetBounds((size.width-753)/2, (size.height-500)/2, 753, 530);\n\t\tcontentPane = new JPanel();\n\t\tcontentPane.setBorder(new EmptyBorder(5, 5, 5, 5));\n\t\tsetContentPane(contentPane);\n\t\t\n\t\tserverMana=new ServerMana();\n\t\ttabbedPane.addTab(\"服务管理\", new ImageIcon(MainWindow.class.getResource(\"/client/img/manager_server.png\")), serverMana, null);\n\t\t\n\t\tuserMana=new UserMana();\n\t\ttabbedPane.addTab(\"用户管理\", new ImageIcon(MainWindow.class.getResource(\"/client/img/manager_users.png\")), userMana, null);\n\t\t\n\t\tmsgMana=new MsgMana();\n\t\ttabbedPane.addTab(\"消息管理\", new ImageIcon(MainWindow.class.getResource(\"/client/img/manager_message.png\")), msgMana, null);\n\t\tGroupLayout gl_contentPane = new GroupLayout(contentPane);\n\t\tgl_contentPane.setHorizontalGroup(\n\t\t\tgl_contentPane.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addComponent(tabbedPane, GroupLayout.DEFAULT_SIZE, 735, Short.MAX_VALUE)\n\t\t);\n\t\tgl_contentPane.setVerticalGroup(\n\t\t\tgl_contentPane.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(gl_contentPane.createSequentialGroup()\n\t\t\t\t\t.addComponent(tabbedPane, GroupLayout.PREFERRED_SIZE, 492, Short.MAX_VALUE)\n\t\t\t\t\t.addContainerGap())\n\t\t);\n\t\tcontentPane.setLayout(gl_contentPane);\n\t\t\n\t\tsetDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);\n\t\taddWindowListener(new WindowAdapter(){\n            public void windowClosing(WindowEvent e){\n              int n=JOptionPane.showConfirmDialog(null,\"确认退出吗?\",\"确认对话框\",\n                                       JOptionPane.YES_NO_OPTION );\n              if(n==JOptionPane.YES_OPTION)  \n                 System.exit(0);\n            }});\n\t    validate();  \n\t}\n}\n"
  },
  {
    "path": "src/server/frame/MsgActionListener.java",
    "content": "﻿package server.frame;\n\nimport java.awt.HeadlessException;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.sql.SQLException;\nimport java.util.List;\n\nimport javax.swing.JOptionPane;\n\n\nimport server.common.PageService;\nimport server.dao.MsgDao;\nimport server.entity.Msg;\n\n\npublic class MsgActionListener implements ActionListener\n{\n\n\tstatic PageService pageService;\n\tMsgDao msgDao;\n\tMsgMana msgMana;\n\n\tpublic MsgActionListener(MsgMana msgMana)\n\t{\n\t\tmsgDao = new MsgDao();\n\t\tString sql = \"select * from msg\";\n\t\tList<Msg> list = msgDao.selectMsgs(sql);\n\t\tpageService = new PageService(list);\n\t\tthis.msgMana = msgMana;\n\t}\n\n\tpublic void actionPerformed(ActionEvent e)\n\t{\n\t\tString strBtn = e.getActionCommand();\n\t\tif (\"删除\".equals(strBtn))\n\t\t{\n\t\t\tint row = msgMana.table.getSelectedRow();\n\t\t\tif (row != -1)\n\t\t\t{\n\t\t\t\tint msgId = Integer.parseInt(msgMana.table.getValueAt(row, 0).toString());\n\t\t\t\ttry {\n\t\t\t\t\tif (msgDao.deleteMsg(msgId))\n\t\t\t\t\t{\n\t\t\t\t\t\t\n\t\t\t\t\t\tJOptionPane.showMessageDialog(null, \"删除成功！\");\n\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tJOptionPane.showMessageDialog(null, \"删除失败！\");\n\t\t\t\t\t}\n\t\t\t\t} catch (HeadlessException e1) {\n\t\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\t\te1.printStackTrace();\n\t\t\t\t} catch (SQLException e1) {\n\t\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\t\te1.printStackTrace();\n\t\t\t\t}\n\t\t\t\tpageService = new PageService(msgMana.refresh());\n\t\t\t}\n\t\t}\n\t\telse if (\"刷新\".equals(strBtn))\n\t\t{\n\t\t\tmsgMana.refresh();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tList<Msg> listPerPage = null;\n\t\t\tif (\"首页\".equals(strBtn))\n\t\t\t{\n\t\t\t\tlistPerPage = pageService.gotoFirst();\n\t\t\t}\n\t\t\telse if (\"下一页\".equals(strBtn))\n\t\t\t{\n\t\t\t\tlistPerPage = pageService.gotoNext();\n\t\t\t}\n\t\t\telse if (\"上一页\".equals(strBtn))\n\t\t\t{\n\t\t\t\tlistPerPage = pageService.gotoPre();\n\t\t\t}\n\t\t\telse if (\"尾页\".equals(strBtn))\n\t\t\t{\n\t\t\t\tlistPerPage = pageService.gotoLast();\n\t\t\t}\n\n\t\t\tint rowCount = msgMana.model.getRowCount();// 获取表格中共有几行\n\n\t\t\tfor (int i = 0; i < rowCount; i++)\n\t\t\t{\n\t\t\t\tmsgMana.model.removeRow(0);\n\n\t\t\t}\n\t\t\tmsgMana.lblCurrent.setText(\"当前在第\"\n\t\t\t\t\t+ (pageService.getCurrentPage() + 1) + \"页\");\n\t\t\tfor (int i = 0; i < listPerPage.size(); i++)\n\t\t\t{\n\t\t\t\tMsg msg = (Msg) listPerPage.get(i);\n\t\t\t\tObject[] rowData = { msg.getMsgId(),\n\t\t\t\t\t\tmsg.getMsgContent(), msg.getSendFrom(), msg.getSendTo(),\n\t\t\t\t\t\tmsg.getSendTime(), msg.getRemark(), msg.getMsgTye()};\n\t\t\t\tmsgMana.model.addRow(rowData);\n\t\t\t}\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "src/server/frame/MsgMana.java",
    "content": "﻿package server.frame;\n\n\nimport java.util.List;\nimport java.util.Vector;\n\nimport javax.swing.GroupLayout;\nimport javax.swing.GroupLayout.Alignment;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JOptionPane;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\n\nimport javax.swing.JTable;\nimport javax.swing.table.DefaultTableModel;\n\n\nimport server.common.PageService;\nimport server.dao.MsgDao;\n\nimport server.entity.Msg;\nimport javax.swing.LayoutStyle.ComponentPlacement;\n\npublic class MsgMana extends JPanel {\n\tpublic JTable table;\n\tpublic DefaultTableModel model;\n\tprivate Vector<String> columnNames = new Vector<String>();\n\tprivate JLabel lblNum;\n\tpublic JLabel lblCurrent;\n\tpublic MsgActionListener msgActionListener;\n\tpublic MsgMana()\n\t{\n\n\t\tJScrollPane scrollPane = new JScrollPane();\n\t\tcolumnNames.add(\"消息ID\");\n\t\tcolumnNames.add(\"消息内容\");\n\t\tcolumnNames.add(\"消息发送者ID\");\n\t\tcolumnNames.add(\"消息接收者ID\");\n\t\tcolumnNames.add(\"消息发送时间\");\n\t\tcolumnNames.add(\"消息备注\");\n\t\tcolumnNames.add(\"消息类型\");\n\t\tmodel = new DefaultTableModel(columnNames, 0);\n\n\t\ttable = new JTable(model)\n\t\t{\n\t\t\tBoolean[] canEdit = new Boolean[] { false, true, true, true, true,\n\t\t\t\t\ttrue, true };\n\n\t\t\t@Override\n\t\t\tpublic boolean isCellEditable(int row, int column)\n\t\t\t{\n\t\t\t\t// TODO Auto-generated method stub\n\t\t\t\treturn canEdit[column];\n\t\t\t}\n\t\t};\n\n\t\tscrollPane.setViewportView(table);\n\n\t\tlblNum = new JLabel(\"\\u51710\\u9875 /\");\n\n\t\tlblCurrent = new JLabel(\"\\u5F53\\u524D\\u5728\\u7B2C1\\u9875\");\n\n\t\tJButton btnFirst = new JButton(\"\\u9996\\u9875\");\n\n\t\tJButton btnPre = new JButton(\"\\u4E0A\\u4E00\\u9875\");\n\n\t\tJButton btnNext = new JButton(\"\\u4E0B\\u4E00\\u9875\");\n\n\t\tJButton btnLast = new JButton(\"\\u5C3E\\u9875\");\n\n\t\tJButton btnDelete = new JButton(\"\\u5220\\u9664\");\n\n\t\tJButton btnReresh = new JButton(\"\\u5237\\u65B0\");\n\n\t\t\n\t\t// 为每个按钮注册监听器\n\t\tmsgActionListener = new MsgActionListener(this);\n\t\tbtnFirst.addActionListener(msgActionListener);\n\t\tbtnPre.addActionListener(msgActionListener);\n\t\tbtnNext.addActionListener(msgActionListener);\n\t\tbtnLast.addActionListener(msgActionListener);\n\t\tbtnDelete.addActionListener(msgActionListener);\n\t\tbtnReresh.addActionListener(msgActionListener);\n\t\tGroupLayout groupLayout = new GroupLayout(this);\n\t\tgroupLayout.setHorizontalGroup(\n\t\t\tgroupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t.addGap(40)\n\t\t\t\t\t.addComponent(btnFirst, GroupLayout.PREFERRED_SIZE, 69, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addGap(4)\n\t\t\t\t\t.addComponent(btnPre)\n\t\t\t\t\t.addGap(10)\n\t\t\t\t\t.addComponent(btnNext, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addGap(25)\n\t\t\t\t\t.addComponent(btnLast, GroupLayout.PREFERRED_SIZE, 62, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addGap(82)\n\t\t\t\t\t.addComponent(btnDelete, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addGap(33)\n\t\t\t\t\t.addComponent(btnReresh, GroupLayout.PREFERRED_SIZE, 69, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addContainerGap(65, Short.MAX_VALUE))\n\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t.addGap(264)\n\t\t\t\t\t.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t\t\t.addComponent(lblNum, GroupLayout.PREFERRED_SIZE, 51, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t\t\t.addGap(46)\n\t\t\t\t\t\t\t.addComponent(lblCurrent, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE)))\n\t\t\t\t\t.addContainerGap(295, Short.MAX_VALUE))\n\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t.addContainerGap()\n\t\t\t\t\t.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 670, Short.MAX_VALUE))\n\t\t);\n\t\tgroupLayout.setVerticalGroup(\n\t\t\tgroupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t.addContainerGap()\n\t\t\t\t\t.addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 299, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addGap(29)\n\t\t\t\t\t.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t\t\t.addComponent(lblNum)\n\t\t\t\t\t\t.addComponent(lblCurrent))\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.UNRELATED)\n\t\t\t\t\t.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t\t\t.addGap(1)\n\t\t\t\t\t\t\t.addComponent(btnFirst))\n\t\t\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t\t\t.addGap(1)\n\t\t\t\t\t\t\t.addComponent(btnPre))\n\t\t\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t\t\t.addGap(1)\n\t\t\t\t\t\t\t.addComponent(btnNext))\n\t\t\t\t\t\t.addComponent(btnLast)\n\t\t\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t\t\t.addGap(1)\n\t\t\t\t\t\t\t.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)\n\t\t\t\t\t\t\t\t.addComponent(btnReresh)\n\t\t\t\t\t\t\t\t.addComponent(btnDelete))))\n\t\t\t\t\t.addGap(22))\n\t\t);\n\t\tsetLayout(groupLayout);\n\n\t\t// 将数据添加到表格中\n\n\t\trefresh();\n\t}\n\n\tpublic List refresh()\n\t{// 先移出表格监听器\n\t\t// 得到总行数\n\t\tint sumRow = model.getRowCount();\n\t\t// 清空表格\n\t\tfor (int i = 0; i < sumRow; i++)\n\t\t{\n\t\t\tmodel.removeRow(0);\n\t\t}\n\n\t\tMsgDao msgDao = new MsgDao();\n\t\tString sql = \"select * from msg\";\n\t\tList<Msg> list = msgDao.selectMsgs(sql);\n\t\tPageService service = new PageService(list);\n\t\tList listTemp = service.gotoFirst();\n\t\tlblNum.setText(\"共\" + service.getTotalPage() + \"页/\");\n\t\tlblCurrent.setText(\"当前在第\" + (service.getCurrentPage() + 1) + \"页\");\n\t\tfor (int i = 0; i < listTemp.size(); i++)\n\t\t{\n\t\t\tMsg msg = (Msg) listTemp.get(i);\n\t\t\tObject[] rowData = new Object[] { msg.getMsgId(),\n\t\t\t\t\tmsg.getMsgContent(), msg.getSendFrom(), msg.getSendTo(),\n\t\t\t\t\tmsg.getSendTime(), msg.getRemark(), msg.getMsgTye() };\n\t\t\tmodel.addRow(rowData);\n\t\t}\n\t\treturn list;\n\t}\n}\n"
  },
  {
    "path": "src/server/frame/ServerActionListen.java",
    "content": "﻿package server.frame;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport javax.swing.JOptionPane;\n\nimport com.MyTools;\n\nimport server.QQServer;\n\npublic class ServerActionListen implements ActionListener{\n\n\tQQServer qqServer=null;\n\tServerMana serverMana=null;\n\tpublic ServerActionListen(ServerMana serverMana)\n\t{\n\t\tthis.serverMana=serverMana;\n\t}\n\tpublic void actionPerformed(ActionEvent e) \n\t{\n\t\tString cmd=e.getActionCommand();\n\t\tif(cmd.equals(\"启动MyQQ服务器\"))\n\t\t{\n\t\t\t\n\t\t\tqqServer=new QQServer(MyTools.QQServerPort);\n\t\t\tserverMana.allTime=0;\n\t\t\tserverMana.startTime=System.currentTimeMillis();\n\t\t\tserverMana.isRun=true;\n\t\t\tserverMana.lblState.setText(\"服务器正在运行中...\");\n\t\t\tthis.serverMana.btnStart.setActionCommand(\"停止MyQQ服务器\");\n\t\t\t\n\t\t}\n\t\telse if(cmd.equals(\"停止MyQQ服务器\"))\n\t\t{\n\t\t\tif(qqServer!=null)\n\t\t\t{\n\t\t\t\tqqServer.closeServer();\n\t\t\t\tserverMana.isRun=false;\n\t\t\t\tserverMana.lblState.setText(\"服务器已关闭。\");\n\t\t\t\tJOptionPane.showMessageDialog(null,\"本次服务器总共运行\"+serverMana.allTime+\"秒\");\n\t\t\t\tthis.serverMana.btnStart.setActionCommand(\"启动MyQQ服务器\");\n\t\t\t}\n\t\t}\n\t}\n\t\n}\n"
  },
  {
    "path": "src/server/frame/ServerMana.java",
    "content": "﻿package server.frame;\n\nimport javax.swing.JOptionPane;\nimport javax.swing.JPanel;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\n\nimport server.QQServer;\n\nimport client.frame.MyPanel;\n\nimport com.MyTools;\n\nimport java.util.Calendar;\nimport java.awt.Font;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ActionEvent;\nimport javax.swing.border.BevelBorder;\nimport javax.swing.border.EmptyBorder;\nimport javax.swing.border.EtchedBorder;\nimport javax.swing.border.TitledBorder;\nimport javax.swing.GroupLayout;\nimport javax.swing.GroupLayout.Alignment;\nimport javax.swing.JTextArea;\nimport javax.swing.LayoutStyle.ComponentPlacement;\n\n\npublic class ServerMana extends JPanel implements Runnable\n{\n\tQQServer qqServer=null;//QQ服务器\n\t\n\t\n\tJButton btnStart;\n\tJLabel lblTime;\n\tCalendar calendar=Calendar.getInstance();\n\tprivate JLabel currentTime;\n\tprivate JLabel label_1;\n\tprivate JLabel lblRun;\n\tprivate JLabel lblStateShow;\n\tpublic JLabel lblState;\n\tpublic int allTime=0;\n\tpublic long startTime=0;\n\tpublic long endTime=0;\n\tpublic boolean isRun=false;\n\tpublic JTextArea textArea公告;\n\tprivate JPanel panel;\n\tprivate JTextArea textArea弹窗;\n\tprivate JButton btn弹窗;\n\t\n\tpublic ServerMana() \n\t{\n\t\tsetLayout(null);\n\t\t\n\t\tbtnStart = new JButton(\"\\u542F\\u52A8MyQQ\\u670D\\u52A1\\u5668\");\n\t\tbtnStart.addActionListener(new ActionListener() \n\t\t{\n\t\t\tpublic void actionPerformed(ActionEvent e) \n\t\t\t{\n\t\t\t\tstartOrCloseServer();\n\t\t\t}\n\t\t});\n\t\tbtnStart.setFont(new Font(\"微软雅黑\", Font.BOLD, 28));\n\t\tbtnStart.setBounds(29, 30, 301, 76);\n\t\tadd(btnStart);\n\t\t\n\t\tJLabel label = new JLabel(\"\\u5F53\\u524D\\u670D\\u52A1\\u5668\\u65F6\\u95F4\\uFF1A\");\n\t\tlabel.setBounds(29, 169, 106, 15);\n\t\tadd(label);\n\t\t\n\t\tcurrentTime = new JLabel(\"\");\n\t\tcurrentTime.setBounds(153, 169, 192, 15);\n\t\tadd(currentTime);\n\t\t\n\t\tlabel_1 = new JLabel(\"\\u670D\\u52A1\\u5668\\u8FD0\\u884C\\u65F6\\u95F4\\uFF1A\");\n\t\tlabel_1.setBounds(29, 203, 106, 15);\n\t\tadd(label_1);\n\t\t\n\t\tlblRun = new JLabel(\"\");\n\t\tlblRun.setBounds(153, 203, 135, 15);\n\t\tadd(lblRun);\n\t\t\n\t\tlblStateShow = new JLabel(\"\\u5F53\\u524D\\u670D\\u52A1\\u5668\\u72B6\\u6001\\uFF1A\");\n\t\tlblStateShow.setBounds(28, 132, 107, 15);\n\t\tadd(lblStateShow);\n\t\t\n\t\tlblState = new JLabel(\"服务器未运行\");\n\t\tlblState.setBounds(153, 132, 135, 15);\n\t\tadd(lblState);\n\t\t\n\t\tJPanel panel公告 = new JPanel();\n\t\tpanel公告.setBorder(new TitledBorder(null, \"\\u53D1\\u5E03\\u804A\\u5929\\u5BA4\\u516C\\u544A\", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(59, 59, 59)));\n\t\tpanel公告.setBounds(29, 231, 289, 240);\n\t\tadd(panel公告);\n\t\t\n\t\ttextArea公告 = new JTextArea();\n\t\t\n\t\tJButton btn发布公告 = new JButton(\"\\u53D1\\u5E03\\u804A\\u5929\\u5BA4\\u516C\\u544A\");\n\t\tbtn发布公告.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e) \n\t\t\t{\n\t\t\t\tsendPublicMessage();\n\t\t\t}\n\t\t});\n\t\tGroupLayout gl_panel公告 = new GroupLayout(panel公告);\n\t\tgl_panel公告.setHorizontalGroup(\n\t\t\tgl_panel公告.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addComponent(textArea公告, GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE)\n\t\t\t\t.addGroup(Alignment.TRAILING, gl_panel公告.createSequentialGroup()\n\t\t\t\t\t.addContainerGap(63, Short.MAX_VALUE)\n\t\t\t\t\t.addComponent(btn发布公告, GroupLayout.PREFERRED_SIZE, 142, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addGap(56))\n\t\t);\n\t\tgl_panel公告.setVerticalGroup(\n\t\t\tgl_panel公告.createParallelGroup(Alignment.TRAILING)\n\t\t\t\t.addGroup(gl_panel公告.createSequentialGroup()\n\t\t\t\t\t.addComponent(textArea公告, GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(btn发布公告, GroupLayout.PREFERRED_SIZE, 47, GroupLayout.PREFERRED_SIZE))\n\t\t);\n\t\tpanel公告.setLayout(gl_panel公告);\n\t\t\n\t\tpanel = new JPanel();\n\t\tpanel.setBorder(new TitledBorder(null, \"\\u53D1\\u5E03\\u5F39\\u7A97\\u516C\\u544A\", TitledBorder.LEADING, TitledBorder.TOP, null, null));\n\t\tpanel.setBounds(330, 231, 256, 240);\n\t\tadd(panel);\n\t\tpanel.setLayout(null);\n\t\t\n\t\ttextArea弹窗 = new JTextArea();\n\t\ttextArea弹窗.setBounds(16, 33, 222, 139);\n\t\tpanel.add(textArea弹窗);\n\t\t\n\t\tbtn弹窗 = new JButton(\"\\u53D1\\u5E03\\u5F39\\u7A97\\u516C\\u544A\");\n\t\tbtn弹窗.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e)\n\t\t\t{\n\t\t\t\tshowWindow();\n\t\t\t}\n\t\t});\n\t\tbtn弹窗.setBounds(71, 177, 127, 46);\n\t\tpanel.add(btn弹窗);\n\t\tThread thread=new Thread(this);\n\t\tthread.start();\n\t\t\n\t}\n\t//设置窗体的背景图片\n\t/*@Override\n\tpublic void paintComponent(Graphics g)\n\t{\n\t\tsuper.paintComponent(g);//这句话有时候必须写，有时候可以不写\n\t\tg.drawImage(MyTools.getIcon(\"../img/registerBGimg2.jpg\").getImage(), 0, 0, null);\n\t}*/\n\n\n\tpublic void run()\n\t{\n\t\twhile(true)\n\t\t{\n\t\t\tshowTime();\n\t\t\tif(isRun)\n\t\t\t{\n\t\t\t\tendTime=System.currentTimeMillis();\n\t\t\t\tshowRunTime();\n\t\t\t}\n\t\t\telse \n\t\t\t{\n\t\t\t\tshowRunTime();\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tThread.sleep(1000);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t}\n\tpublic void showTime()\n\t{\n\t\tCalendar calendar=Calendar.getInstance();\n\t\tString time=calendar.get(Calendar.YEAR)+\"年\"\n\t\t\t\t+(calendar.get(Calendar.MONTH)+1)+\"月\"\n\t\t\t\t+calendar.get(Calendar.DATE)+\"日\"\n\t\t\t\t+\" \"\n\t\t\t\t+calendar.get(Calendar.HOUR_OF_DAY)+\":\"\n\t\t\t\t+calendar.get(Calendar.MINUTE)+\":\"\n\t\t\t\t+calendar.get(Calendar.SECOND);\n\t\tcurrentTime.setText(time);\n\t}\n\tpublic void showRunTime()\n\t{\n\t\tallTime=(int)(endTime-startTime)/1000;\n\t\tlblRun.setText(String.valueOf(allTime));\n\t}\n\tpublic void startOrCloseServer()\n\t{\n\t\tif(btnStart.getText().equals(\"启动MyQQ服务器\"))\n\t\t{\n\t\t\tqqServer=new QQServer(MyTools.QQServerPort);\n\t\t\tallTime=0;\n\t\t\tstartTime=System.currentTimeMillis();\n\t\t\tisRun=true;\n\t\t\tlblState.setText(\"服务器正在运行中...\");\n\t\t\tbtnStart.setText(\"停止MyQQ服务器\");\n\t\t}\n\t\telse if(btnStart.getText().equals(\"停止MyQQ服务器\"))\n\t\t{\n\t\t\tif(qqServer!=null)\n\t\t\t{\n\t\t\t\tqqServer.closeServer();\n\t\t\t\tisRun=false;\n\t\t\t\tlblState.setText(\"服务器已关闭。\");\n\t\t\t\tJOptionPane.showMessageDialog(null,\"本次服务器总共运行\"+allTime+\"秒\");\n\t\t\t\tbtnStart.setText(\"启动MyQQ服务器\");\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t * 发布聊天室公告\n\t */\n\tpublic void sendPublicMessage()\n\t{\n\t\tif(btnStart.getText().equals(\"停止MyQQ服务器\"))\n\t\t{\n    \t\tif(textArea公告.getText().equals(\"\"))\n    \t\t\tJOptionPane.showMessageDialog(null, \"公告内容不能为空！\");\n    \t\telse\n    \t\t\tqqServer.sendPublicMessage(textArea公告.getText());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tJOptionPane.showMessageDialog(null, \"您还未启动MyQQ服务器，不能发布公告！\");\n\t\t}\n\t}\n\t/**\n\t * 弹窗\n\t */\n\tpublic void showWindow()\n\t{\n\t\tif(btnStart.getText().equals(\"停止MyQQ服务器\"))\n\t\t{\n    \t\tif(textArea弹窗.getText().equals(\"\"))\n    \t\t\tJOptionPane.showMessageDialog(null, \"弹窗内容不能为空！\");\n    \t\telse\n    \t\t\tqqServer.sendShowWindow(textArea弹窗.getText());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tJOptionPane.showMessageDialog(null, \"您还未启动MyQQ服务器，不能发布弹窗公告！\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/server/frame/UserActionListen.java",
    "content": "﻿package server.frame;\n\nimport java.awt.HeadlessException;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.sql.SQLException;\nimport java.util.List;\n\nimport javax.swing.JOptionPane;\n\nimport server.common.PageService;\nimport server.dao.UserDao;\nimport server.entity.Users;\n\npublic class UserActionListen implements ActionListener\n{\n\tstatic PageService pageService;\n\tUserDao userDao;\n\tUserMana userMana;\n\n\tpublic UserActionListen(UserMana userMana)\n\t{\n\t\tuserDao = new UserDao();\n\t\tList<Users> list = userDao.queryAll();\n\t\tpageService = new PageService(list);\n\t\tthis.userMana = userMana;\n\t}\n\n\tpublic void actionPerformed(ActionEvent e)\n\t{\n\t\tString strBtn = e.getActionCommand();\n\t\tif(\"删除\".equals(strBtn))\n\t\t{\n\t\t\tint row=userMana.table.getSelectedRow();\n\t\t\tif(row!=-1)\n\t\t\t{\n\t\t\t\tint userId=Integer.parseInt(userMana.table.getValueAt(row, 0).toString());\n\t\t\t\ttry {\n\t\t\t\t\tif(userDao.delete(userId))\n\t\t\t\t\t{\n\t\t\t\t\t\tJOptionPane.showMessageDialog(null, \"删除成功！\");\n\t\t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t\telse \n\t\t\t\t\t{\n\t\t\t\t\t\tJOptionPane.showMessageDialog(null, \"删除失败！\");\n\t\t\t\t\t}\n\t\t\t\t} catch (HeadlessException e1) {\n\t\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\t\te1.printStackTrace();\n\t\t\t\t} catch (SQLException e1) {\n\t\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\t\te1.printStackTrace();\n\t\t\t\t}\n\t\t\t\t//userMana.refresh();\n\t\t\t\tpageService = new PageService(userMana.refresh());\n\t\t\t}\n\t\t}\n\t\telse if(\"刷新\".equals(strBtn))\n\t\t{\n\t\t\t//userMana.refresh();\n\t\t\tpageService = new PageService(userMana.refresh());\n\t\t}\n\t\telse if(\"查找一\".equals(strBtn))\n\t\t{\n\t\t\tuserMana.model.removeTableModelListener(userMana.userTableCahnged);\n\t\t\tUsers user=null;\n\t\t\tint rowCount = userMana.model.getRowCount();\n\t\t\tUserDao userDao=new UserDao();\n\t\t\tif(userMana.txtId.equals(null)||userMana.txtId.equals(\"\"))\n\t\t\t{\n\t\t\t\tJOptionPane.showMessageDialog(null, \"请输入用户ID\");\n\t\t\t}\n\t\t\telse \n\t\t\t{\n\t\t\t\tint userId=Integer.parseInt(userMana.txtId.getText());\n\t\t\t\tuser=userDao.queryById(userId);\n\t\t\t\tif(user==null)\n\t\t\t\t{\n\t\t\t\t\tJOptionPane.showMessageDialog(null, \"用户不存在！\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (int i = 0; i <rowCount; i++)\n\t\t\t\t{\n\t\t\t\t\tuserMana.model.removeRow(0);\n\t\t\t\t}\n\t\t\t\tObject[] rowData =\n\t\t\t\t\t{ user.getId(), user.getName(), user.getPwd(),user.getIp(),user.getState(),user.getGender(), user.getEmail(),\n\t\t\t\t\t\t\tuser.getLastLogin(),user.getLastExit(), user.getBirthday()};\n\t\t\t\tuserMana.model.addRow(rowData);\n\t\t\t}\n\t\t\tuserMana.model.addTableModelListener(userMana.userTableCahnged);\n\t\t}\n\t\telse if(\"查找二\".equals(strBtn))\n\t\t{\n\t\t\tuserMana.model.removeTableModelListener(userMana.userTableCahnged);\n\t\t\tUsers user=null;\n\t\t\tint rowCount = userMana.model.getRowCount();\n\t\t\tUserDao userDao=new UserDao();\n\t\t\tif(userMana.txtName.equals(null)||userMana.txtName.equals(\"\"))\n\t\t\t{\n\t\t\t\tJOptionPane.showMessageDialog(null, \"请输入用户名\");\n\t\t\t}\n\t\t\telse \n\t\t\t{\n\t\t\t\tString userName=userMana.txtName.getText();\n\t\t\t\ttry {\n\t\t\t\t\tuser=userDao.queryByName(userName);\n\t\t\t\t} catch (Exception e1) {\n\t\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\t\te1.printStackTrace();\n\t\t\t\t}\n\t\t\t\tif(user==null)\n\t\t\t\t{\n\t\t\t\t\tJOptionPane.showMessageDialog(null, \"用户不存在！\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (int i = 0; i <rowCount; i++)\n\t\t\t\t{\n\t\t\t\t\tuserMana.model.removeRow(0);\n\t\t\t\t}\n\t\t\t\tObject[] rowData =\n\t\t\t\t\t{ user.getId(), user.getName(), user.getPwd(),user.getIp(),user.getState(),user.getGender(), user.getEmail(),\n\t\t\t\t\t\t\tuser.getLastLogin(),user.getLastExit(), user.getBirthday()};\n\t\t\t\tuserMana.model.addRow(rowData);\n\t\t\t}\n\t\t\tuserMana.model.addTableModelListener(userMana.userTableCahnged);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tuserMana.model.removeTableModelListener(userMana.userTableCahnged);\n\t\t\tList<Users> listPerPage = null;\n\t\t\tif (\"首页\".equals(strBtn))\n\t\t\t{\n\t\t\t\tlistPerPage = pageService.gotoFirst();\n\t\t\t}\n\t\t\telse if (\"下一页\".equals(strBtn))\n\t\t\t{\n\t\t\t\tlistPerPage = pageService.gotoNext();\n\t\t\t}\n\t\t\telse if (\"上一页\".equals(strBtn))\n\t\t\t{\n\t\t\t\tlistPerPage = pageService.gotoPre();\n\t\t\t}\n\t\t\telse if (\"尾页\".equals(strBtn))\n\t\t\t{\n\t\t\t\tlistPerPage = pageService.gotoLast();\n\t\t\t}\n\t\n\t\t\tint rowCount = userMana.model.getRowCount();// 获取表格中共有几行\n\t\n\t\t\tfor (int i = 0; i < rowCount; i++)\n\t\t\t{\n\t\t\t\tuserMana.model.removeRow(0);\n\t\t\t\t\n\t\t\t}\n\t\t\tuserMana.lblCurrent.setText(\"当前在第\" + (pageService.getCurrentPage()+1) + \"页\");\n\t\t\tfor (int i = 0; i < listPerPage.size(); i++)\n\t\t\t{\n\t\t\t\tUsers user = (Users) listPerPage.get(i);\n\t\t\t\tObject[] rowData =\n\t\t\t\t{ user.getId(), user.getName(), user.getPwd(),user.getIp(),user.getState(),user.getGender(), user.getEmail(),\n\t\t\t\t\t\tuser.getLastLogin(),user.getLastExit(), user.getBirthday()};\n\t\t\t\tuserMana.model.addRow(rowData);\n\t\t\t}\n\t\t\tuserMana.model.addTableModelListener(userMana.userTableCahnged);\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "src/server/frame/UserMana.java",
    "content": "﻿package server.frame;\n\nimport java.awt.BorderLayout;\nimport java.awt.FlowLayout;\nimport java.util.List;\nimport java.util.Vector;\n\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTable;\nimport javax.swing.table.DefaultTableModel;\n\nimport server.common.PageService;\nimport server.dao.UserDao;\n\nimport server.entity.Users;\nimport javax.swing.GroupLayout;\nimport javax.swing.GroupLayout.Alignment;\nimport javax.swing.JPopupMenu;\nimport java.awt.Component;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JMenuItem;\nimport javax.swing.JTextField;\nimport javax.swing.LayoutStyle.ComponentPlacement;\n\npublic class UserMana extends JPanel {\n\tJScrollPane scrollpane = new JScrollPane();\n\tVector<String> columnNames = new Vector<String>();\n\tpublic DefaultTableModel model;\n\tpublic JTable table;\n\tpublic JLabel lblNum;\n\tpublic JLabel lblCurrent;\n\t\n\tpublic UserTableCahnged userTableCahnged;\n\n\tJButton btnFirst = new JButton(\"首页\");\n\tJButton btnNext = new JButton(\"下一页\");\n\tJButton btnPre = new JButton(\"上一页\");\n\tJButton btnLast = new JButton(\"尾页\");\n\tJButton btnDelete = new JButton(\"\\u5220\\u9664\");\n\tprivate final JButton btnUpdate = new JButton(\"\\u5237\\u65B0\");\n\tpublic JTextField txtId;\n\tpublic JTextField txtName;\n\tpublic UserMana()\n\t{\n\t\tcolumnNames.add(\"用户ID\");\n\t\tcolumnNames.add(\"用户名\");\n\t\tcolumnNames.add(\"密码\");\n\t\tcolumnNames.add(\"IP\");\n\t\tcolumnNames.add(\"状态\");\n\t\tcolumnNames.add(\"性别\");\n\t\tcolumnNames.add(\"Email\");\n\t\tcolumnNames.add(\"最近上线时间\");\n\t\tcolumnNames.add(\"最后下线时间\");\n\t\tcolumnNames.add(\"生日\");\n\t\tmodel = new DefaultTableModel(columnNames, 0);\n\t\ttable = new JTable(model)\n\t\t{\n\t\t\tboolean[] canEdit = new boolean[] { false, true, true, false, true,\n\t\t\t\t\ttrue, true, false, false, true };\n\n\t\t\tpublic boolean isCellEditable(int rowIndex, int columnIndex)\n\t\t\t{\n\t\t\t\treturn canEdit[columnIndex];\n\t\t\t}\n\n\t\t};\n\t\ttable.getAutoscrolls();\n\t\tscrollpane.setViewportView(table);\n\t\t\n\t\tUserActionListen userActionListen=new UserActionListen(this);\n\t\tuserTableCahnged=new UserTableCahnged(table);\n\t\t\n\t\tmodel.addTableModelListener(userTableCahnged);\n\t\tbtnFirst.addActionListener(userActionListen);\n\t\tbtnPre.addActionListener(userActionListen);\n\t\tbtnNext.addActionListener(userActionListen);\n\t\tbtnLast.addActionListener(userActionListen);\n\t\tlblNum=new JLabel();\n\t\tlblCurrent=new JLabel();\n\t\tbtnDelete.addActionListener(userActionListen);\n\t\tbtnUpdate.addActionListener(userActionListen);\n\t\t\n\t\tJLabel lblid = new JLabel(\"\\u6309\\u7528\\u6237ID\\u67E5\\u627E\\uFF1A\");\n\t\t\n\t\ttxtId = new JTextField();\n\t\ttxtId.setColumns(10);\n\t\t\n\t\tJLabel label = new JLabel(\"\\u6309\\u7528\\u6237\\u540D\\u67E5\\u627E\\uFF1A\");\n\t\t\n\t\ttxtName = new JTextField();\n\t\ttxtName.setColumns(10);\n\t\t\n\t\tJButton btnSearch1 = new JButton(\"\\u67E5\\u627E\\u4E00\");\t\n\t\tJButton btnSeach2 = new JButton(\"\\u67E5\\u627E\\u4E8C\");\n\t\tbtnSearch1.addActionListener(userActionListen);\n\t\tbtnSeach2.addActionListener(userActionListen);\n\t\t\n\t\tGroupLayout groupLayout = new GroupLayout(this);\n\t\tgroupLayout.setHorizontalGroup(\n\t\t\tgroupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t.addGap(24)\n\t\t\t\t\t.addComponent(lblid)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(txtId, GroupLayout.PREFERRED_SIZE, 74, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED, 100, Short.MAX_VALUE)\n\t\t\t\t\t.addComponent(label)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED)\n\t\t\t\t\t.addComponent(txtName, GroupLayout.PREFERRED_SIZE, 74, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addGap(200))\n\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t.addContainerGap()\n\t\t\t\t\t.addComponent(scrollpane, GroupLayout.DEFAULT_SIZE, 638, Short.MAX_VALUE))\n\t\t\t\t.addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()\n\t\t\t\t\t.addContainerGap(240, Short.MAX_VALUE)\n\t\t\t\t\t.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t\t\t.addGap(37)\n\t\t\t\t\t\t\t.addComponent(lblCurrent, GroupLayout.PREFERRED_SIZE, 80, GroupLayout.PREFERRED_SIZE))\n\t\t\t\t\t\t.addComponent(lblNum, GroupLayout.PREFERRED_SIZE, 43, GroupLayout.PREFERRED_SIZE))\n\t\t\t\t\t.addGap(291))\n\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t.addGap(53)\n\t\t\t\t\t.addComponent(btnFirst)\n\t\t\t\t\t.addGap(5)\n\t\t\t\t\t.addComponent(btnPre)\n\t\t\t\t\t.addGap(5)\n\t\t\t\t\t.addComponent(btnNext)\n\t\t\t\t\t.addGap(5)\n\t\t\t\t\t.addComponent(btnLast)\n\t\t\t\t\t.addGap(85)\n\t\t\t\t\t.addComponent(btnDelete)\n\t\t\t\t\t.addGap(18)\n\t\t\t\t\t.addComponent(btnUpdate)\n\t\t\t\t\t.addContainerGap(99, Short.MAX_VALUE))\n\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t.addGap(165)\n\t\t\t\t\t.addComponent(btnSearch1)\n\t\t\t\t\t.addPreferredGap(ComponentPlacement.RELATED, 187, Short.MAX_VALUE)\n\t\t\t\t\t.addComponent(btnSeach2, GroupLayout.PREFERRED_SIZE, 71, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addGap(154))\n\t\t);\n\t\tgroupLayout.setVerticalGroup(\n\t\t\tgroupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t.addGroup(groupLayout.createSequentialGroup()\n\t\t\t\t\t.addGap(35)\n\t\t\t\t\t.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)\n\t\t\t\t\t\t.addComponent(lblid)\n\t\t\t\t\t\t.addComponent(txtId, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t\t.addComponent(label)\n\t\t\t\t\t\t.addComponent(txtName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))\n\t\t\t\t\t.addGap(18)\n\t\t\t\t\t.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)\n\t\t\t\t\t\t.addComponent(btnSearch1)\n\t\t\t\t\t\t.addComponent(btnSeach2))\n\t\t\t\t\t.addGap(16)\n\t\t\t\t\t.addComponent(scrollpane, GroupLayout.PREFERRED_SIZE, 223, GroupLayout.PREFERRED_SIZE)\n\t\t\t\t\t.addGap(31)\n\t\t\t\t\t.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t\t\t.addComponent(lblCurrent)\n\t\t\t\t\t\t.addComponent(lblNum))\n\t\t\t\t\t.addGap(18)\n\t\t\t\t\t.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)\n\t\t\t\t\t\t.addComponent(btnFirst)\n\t\t\t\t\t\t.addComponent(btnPre)\n\t\t\t\t\t\t.addComponent(btnNext)\n\t\t\t\t\t\t.addComponent(btnLast)\n\t\t\t\t\t\t.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)\n\t\t\t\t\t\t\t.addComponent(btnUpdate)\n\t\t\t\t\t\t\t.addComponent(btnDelete)))\n\t\t\t\t\t.addGap(73))\n\t\t);\n\t\tsetLayout(groupLayout);\n\t\trefresh();\n\t}\n\tpublic List refresh()\n\t{\n\t\tmodel.removeTableModelListener(userTableCahnged);\n\t\tint rowCount = model.getRowCount(); // 将表格清空\n\t\tfor (int i = 0; i < rowCount; i++)\n\t\t\tmodel.removeRow(0);\n\t\tUserDao userDao=new UserDao();\n\t\tList<Users> list=userDao.queryAll();\n\t\tPageService pageService=new PageService(list);\n\t\tList<Users> listTemp=pageService.gotoFirst();\n\t\tlblNum.setText(\"共\"+pageService.getTotalPage()+\"页/\");\n\t\tlblCurrent.setText(\"当前在第\"+(pageService.getCurrentPage()+1)+\"页\");\n\t\tfor (Users user : listTemp)\n\t\t{\n\t\t\tObject[] rowData =\n\t\t\t{ user.getId(), user.getName(), user.getPwd(),user.getIp(),user.getState(),user.getGender(), user.getEmail(),\n\t\t\t\t\tuser.getLastLogin(),user.getLastExit(), user.getBirthday()};\n\t\t\tmodel.addRow(rowData);\n\t\t}\t\n\t\tmodel.addTableModelListener(userTableCahnged);\n\t\treturn list;\n\t}\n}\n"
  },
  {
    "path": "src/server/frame/UserTableCahnged.java",
    "content": "﻿package server.frame;\n\nimport java.awt.HeadlessException;\nimport java.sql.Date;\nimport java.sql.SQLException;\n\nimport javax.swing.JOptionPane;\nimport javax.swing.JTable;\nimport javax.swing.event.TableModelEvent;\nimport javax.swing.event.TableModelListener;\n\n\nimport server.dao.UserDao;\nimport server.entity.Users;\n\npublic class UserTableCahnged implements TableModelListener {\n\tJTable table;\n\tpublic UserTableCahnged(JTable table)\n\t{\n\t\tthis.table=table;\n\t}\n\tpublic void tableChanged(TableModelEvent e) {\n\t\tint row=e.getFirstRow();\n\t\tint userId=Integer.parseInt(table.getValueAt(row, 0).toString());\n\t\tString userName=table.getValueAt(row, 1).toString();\n\t\tString pwdString=table.getValueAt(row, 2).toString();\n\t\t//String IP=table.getValueAt(row, 3).toString();\n\t\t//String state=table.getValueAt(row, 4).toString();\n\t\tString userGender=table.getValueAt(row, 5).toString();\n\t\tString userEmail=table.getValueAt(row, 6).toString();\n\t\t//String userSignature=table.getValueAt(row, 5).toString();\n\t\tDate userBirthday=Date.valueOf(table.getValueAt(row, 9).toString());\n\t\tUsers user=new Users(userId,userName,pwdString, userGender, userEmail,userBirthday);\n\t\tUserDao userDao=new UserDao();\n\t\ttry {\n\t\t\tif(userDao.update(user))\n\t\t\t{\n\t\t\t\tJOptionPane.showMessageDialog(null, \"修改成功！\");\n\t\t\t}\n\t\t\telse {\n\t\t\t\tJOptionPane.showMessageDialog(null, \"修改失败！\");\n\t\t\t}\n\t\t} catch (HeadlessException e1) {\n\t\t\t// TODO Auto-generated catch block\n\t\t\te1.printStackTrace();\n\t\t}\n\t\t\n\t}\n\n}\n"
  }
]