MonsterChatRoom(怪聊聊天系统)
本系统采用ServerSocket+Swing+SQL Server2008编写
主要分为三个模块:登录模块,用户信息展示模块,聊天模块
登录模块
如上图所见:后台采用账户名为唯一标识,通过其获取数据库中的数据;登录主界面,实现了三个相关的界面,和记住密码,保存在数据库中,方便下次登录;密码找回,如果账号存在,下面的信息填写中与数据库注册信息核对两条以上,那么密码框向用户开启可编辑状态,重新找回密码成功!
- 主界面的部分代码 :
package com.hz.view;
import java.awt.*;
import java.awt.event.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import com.hz.bean.Account;
import com.hz.bean.User;
import com.hz.client.Client;
import com.hz.db.DbHelp;
import com.hz.thread.*;
import com.hz.util.AccountDatabaseUtil;
import com.hz.util.UserDatabaseUtil;
/**
* 登录界面
*
* @author ztw
*
* 2016-12-4
*/
public class UserLoginView extends JFrame {
// 获取当前屏幕的宽和高
private final int width = Toolkit.getDefaultToolkit().getScreenSize().width;
private final int height = Toolkit.getDefaultToolkit().getScreenSize().height;
// 设置窗口的宽和高
private final int windowWidth = 430;
private final int windowHeight = 330;
private JPanel upJPanel, belowJPanel; //centerJPanel;
private JButton loginButton;
private ImageIcon icon;
private JPasswordField passField;
private JLabel rightLabel, rightLabel2, leftDownLabel, rightDownLabel,
smImgLabel,centerLabel;
private JCheckBox remember;// 记住密码
private JCheckBox automaticLogin;// 自动登录
private JComboBox<String> accountComboBox;
// private List<String> accountNameList;
private List<Account> accountNameList;
private String accountContent;// 获取账户框的值
private String passContent;// 获取密码框的值
// 菜单弹出事件
private JPopupMenu popupMenu;
// 用户封装类
private User user;
private UserDatabaseUtil util;
public UserLoginView() throws HeadlessException {
Window();
upWindowJPanel();
headJPanel();
accountComboBox();
passField();
rightLabel();
windowJCheckBox();
belowWindowJPanel();
this.add(upJPanel);
this.add(centerLabel);
this.add(accountComboBox);
this.add(passField);
this.add(rightLabel);
this.add(rightLabel2);
this.add(remember);
this.add(automaticLogin);
this.add(belowJPanel);
}
/**
* 顶级窗口设置方法
*/
public void Window() {
this.setTitle("MonsterChat");
// 设置窗口图标
Image img = Toolkit.getDefaultToolkit().getImage("image\\sprout01.png");
this.setIconImage(img);
this.setBackground(Color.BLUE);
// 设置窗体位置和大小
this.setBounds((width - windowWidth) / 2, (height - windowHeight) / 2,
windowWidth, windowHeight);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);// 设置窗体不可改变大小
Container container = getContentPane();
container.setLayout(null);
this.setBackground(Color.red);
this.setUndecorated(true);// 去掉窗口的装饰
// 采用指定的窗口装饰
this.getRootPane().setWindowDecorationStyle(JRootPane.WIDTH);
this.setVisible(true);
}
/**
* 上面面板方法
*/
public void upWindowJPanel() {
upJPanel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
icon = new ImageIcon("image\\tree.gif");
Dimension dim = getSize();
g.drawImage(icon.getImage(), 0, 0, dim.width, dim.height, null);
}
};
upJPanel.setBounds(0, 0, windowWidth, 155);
}
/**
* 头像按钮方法
*/
public void headJPanel() {
//面板绘图
// centerJPanel = new JPanel() {
// @Override
// protected void paintComponent(Graphics g) {
//
// icon = new ImageIcon(account.getAccount_icon());
// System.out.println(icon);
// Dimension dim = getSize();
// g.drawImage(icon.getImage(), 0, 0, dim.width, dim.height, null);
// }
// };
account = (Account) accountDatabaseUtil.getByID(accountName);
if(account != null){
icon = new ImageIcon(account.getAccount_icon());
}
centerLabel = new JLabel(icon);
centerLabel.setBounds(40, 168, 80, 80);
centerLabel.setLayout(null);
// 实例化弹出菜单
popupMenu = new JPopupMenu();
// 增加菜单项到菜单上
popupMenu.add(new JMenuItem("我在线上",
new ImageIcon("image\\online01.png")));
popupMenu
.add(new JMenuItem("Q我吧", new ImageIcon("image\\smile01.png")));
popupMenu.addSeparator();
popupMenu.add(new JMenuItem("离开", new ImageIcon("image\\clock01.png")));
popupMenu.add(new JMenuItem("忙碌", new ImageIcon("image\\wait01.png")));
popupMenu.add(new JMenuItem("请勿打扰", new ImageIcon(
"image\\disturb01.png")));
popupMenu.addSeparator();
popupMenu
.add(new JMenuItem("隐身", new ImageIcon("image\\conceal01.png")));
smImgLabel = new JLabel(new ImageIcon("image\\cancel01.png"));
smImgLabel.setBounds(67, 67, 12, 12);
smImgLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}
@Override
public void mousePressed(MouseEvent e) {
smImgLabel.setBounds(68, 68, 12, 12);
}
@Override
public void mouseReleased(MouseEvent e) {
smImgLabel.setBounds(67, 67, 12, 12);
}
@Override
public void mouseEntered(MouseEvent e) {
smImgLabel.setIcon(new ImageIcon("image\\cancel02.png"));
}
@Override
public void mouseExited(MouseEvent e) {
smImgLabel.setIcon(new ImageIcon("image\\cancel01.png"));
}
});
centerLabel.add(smImgLabel);
}
private AccountDatabaseUtil accountDatabaseUtil = new AccountDatabaseUtil();
private Account account;
/**
* 记录登录账户
*/
private void recordInformation() {
accountNameList = new ArrayList<Account>();
try {
rs = accountDatabaseUtil.getAll();
while (rs.next()) {
account = new Account(rs.getString(2));
accountNameList.add(account);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
List<String> list;
String accountName;
private String accountContentIndex;
/**
* 账户框方法
*/
public void accountComboBox() {
recordInformation();
list = new ArrayList<String>();
for (Account account : accountNameList) {
accountName = account + "";// 把对象类型Account转换成字符串类型数据
list.add(accountName);
}
Object[] obj = list.toArray();
if (obj.length >= 3) {
String[] proList = { (String) obj[obj.length - 1],
(String) obj[obj.length - 2], (String) obj[obj.length - 3] };
accountComboBox = new JComboBox<String>(proList);
} else if (obj.length < 3 && obj.length >= 1) {
String[] proList = { (String) obj[obj.length - 1],(String) obj[obj.length - 2] };
accountComboBox = new JComboBox<String>(proList);
}else if(obj.length==2){
String[] proList = { (String) obj[obj.length - 1] };
accountComboBox = new JComboBox<String>(proList);
}else{
String[] proList = {"MM私聊欢迎您!"};
accountComboBox = new JComboBox<String>(proList);
}
accountComboBox.setBounds(135, 168, 185, 28);
accountComboBox.setEditable(true);// 响应键盘输入事件
accountComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
accountContent = accountComboBox.getSelectedItem().toString();
}
});
accountComboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
accountContent = accountComboBox.getSelectedItem().toString();
}
});
// 获取可编辑框的值
accountContent = (String) accountComboBox.getSelectedItem();
}
/**
* 密码框方法
*/
String content;
public void passField() {
// 根据Id获取密码
account = (Account) accountDatabaseUtil.getByID(accountName);
//当账户信息不等于NULL时,获取密码
if(account != null){
passField = new JPasswordField(account.getAccount_password());
}else{
passField = new JPasswordField();
}
passField.setBounds(135, 196, 185, 28);
passField.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
char[] chars = passField.getPassword();// 获得密码框的密码
passContent = new String(chars);
}
});
char[] chars = passField.getPassword();// 获得密码框的密码
passContent = new String(chars);
}
/**
* 右标签方法
*/
public void rightLabel() {
rightLabel = new JLabel("注册账号");
rightLabel.setBounds(330, 175, 55, 15);
rightLabel.setForeground(new Color(0, 129, 255));
rightLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
breakRegisterWindom();
}
@Override
public void mouseEntered(MouseEvent e) {
rightLabel.setForeground(new Color(130, 194, 255));
}
@Override
public void mouseExited(MouseEvent e) {
rightLabel.setForeground(new Color(0, 129, 255));
}
});
rightLabel2 = new JLabel("找回密码");
rightLabel2.setBounds(330, 202, 55, 15);
rightLabel2.setForeground(new Color(0, 129, 255));
rightLabel2.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
breakRetrievePassword();
}
@Override
public void mouseEntered(MouseEvent e) {
rightLabel2.setForeground(new Color(130, 194, 255));
}
@Override
public void mouseExited(MouseEvent e) {
rightLabel2.setForeground(new Color(0, 129, 255));
}
});
}
/**
* 找回密码界面跳转
*/
private void breakRetrievePassword() {
new retrievePasswordThread().start();
}
/**
* 注册界面跳转
*/
public void breakRegisterWindom() {
new registerThread().start();
}
/**
* 窗口复选框方法
*/
private boolean flag = false;
public void windowJCheckBox() {
remember = new JCheckBox("记住密码");
remember.setBounds(132, 233, 80, 15);
remember.setForeground(Color.gray);
// 根据数据库的值判断是否选中
account = (Account) accountDatabaseUtil.getByID(accountName);
if (account != null && account.getAccount_remember().equals("true")) {
flag = true;
}
remember.setSelected(flag);
automaticLogin = new JCheckBox("自动登录");
automaticLogin.setBounds(248, 233, 80, 15);
automaticLogin.setForeground(Color.gray);
}
/**
* 下面面板、按钮方法
*/
private ResultSet rs;// 结果集
public void belowWindowJPanel() {
belowJPanel = new JPanel();
belowJPanel.setBounds(0, 255, windowWidth, 75);
belowJPanel.setLayout(null);
loginButton = new JButton(new ImageIcon("image\\safety.png"));
loginButton.setBounds(135, 5, 185, 30);
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
util = new UserDatabaseUtil();// 调用数据库工具类
user = util.selectName(accountContent);
accountDatabaseUtil = new AccountDatabaseUtil();// 记录账户密码
// 判断账户密码是否为空,并提示
if (((accountContent != null && !accountContent.equals("")))
&& (passContent != null && !passContent.equals(""))) {
savePasswordInfo(user);//是否保存密码信息
} else if ((accountContent == null || accountContent.equals(""))
&& (accountContentIndex == null || accountContentIndex
.equals(""))) {
JOptionPane.showMessageDialog(null, "账户名不能为空!",
"温馨提示",
JOptionPane.PLAIN_MESSAGE,
new ImageIcon("image\\sprout01.png"));
} else if (passContent == null || passContent.equals("")) {
JOptionPane.showMessageDialog(UserLoginView.this, "密码不能为空!",
"温馨提示",
JOptionPane.PLAIN_MESSAGE,
new ImageIcon("image\\sprout01.png"));
}
}
});
leftDownLabel = new JLabel(new ImageIcon("image\\user01.png"));
leftDownLabel.setBounds(10, 15, 25, 25);
leftDownLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
new loginRecordThread().start();
}
@Override
public void mouseEntered(MouseEvent e) {
leftDownLabel.setIcon(new ImageIcon("image\\user02.png"));
}
@Override
public void mouseExited(MouseEvent e) {
leftDownLabel.setIcon(new ImageIcon("image\\user01.png"));
}
});
rightDownLabel = new JLabel(new ImageIcon("image\\qrCode01.png"));
rightDownLabel.setBounds(390, 15, 25, 25);
rightDownLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
rightDownLabel.setIcon(new ImageIcon("image\\qrCode02.png"));
}
@Override
public void mouseExited(MouseEvent e) {
rightDownLabel.setIcon(new ImageIcon("image\\qrCode01.png"));
}
});
belowJPanel.add(leftDownLabel);
belowJPanel.add(loginButton);
belowJPanel.add(rightDownLabel);
}
/**
* 判断是否保存密码信息
* @param user
*/
private void savePasswordInfo(User user) {
if (user != null) {
String user_name = user.getUser_name().trim();
String user_password = user.getUser_password().trim();
String user_icon = user.getUser_icon();
// 判断记住密码否选中
if (remember.isSelected()) {
account = new Account(user_name, user_password,
"true",user_icon,"true");
} else {
account = new Account(user_name, "", "false",user_icon,"false");
}
if ((accountContent.equals(user_name))
&& (passContent.equals(user_password))) {
accountDatabaseUtil.doAdd(account);
breakWindom();// 界面跳转
} else {
JOptionPane.showMessageDialog(UserLoginView.this, "密码错误!",
"温馨提示", JOptionPane.PLAIN_MESSAGE,
new ImageIcon("image\\sprout01.png"));
}
} else {
JOptionPane.showMessageDialog(UserLoginView.this, "用户名不存在!",
"温馨提示",JOptionPane.PLAIN_MESSAGE,
new ImageIcon("image\\sprout01.png"));
}
}
/**
* 主界面跳转
*/
public void breakWindom() {
this.dispose();
// 启动线程
Client client = new Client(user);
client.start();
new ListMainView(user, client);
}
}
信息展示模块
如上图所述;
- 主界面部分代码
package com.hz.view;
import java.awt.*;
import java.awt.event.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.*;
import com.hz.bean.User;
import com.hz.client.Client;
import com.hz.entertainment.Lattice.Maze;
import com.hz.thread.ChatRoomThread;
import com.hz.thread.PrivyThread;
import com.hz.util.DateFormatUtil;
import com.hz.util.FriendsDatabaseUtil;
/**
* 列表主界面
*
* @author ztw
*
* 2016-12-4
*/
public class ListMainView extends JFrame {
// 获取屏幕的宽和高
private final int width = Toolkit.getDefaultToolkit().getScreenSize().width;
private final int height = Toolkit.getDefaultToolkit().getScreenSize().height;
// 设置窗口的宽和高
private final int windowWidth = 278;
private final int windowHeight = 600;
private JPanel headPanel, mainPanel, belowPanel;
private JButton headButton, game;
private JLabel Namelabel, signature, addFriends;
private JTree tree;
private Box box = Box.createVerticalBox();
private User user;
private Set<User> users = new HashSet<>();
private List<User> list;
private Font f2 = new Font("Georgia", Font.PLAIN, 16);
private Font f1 = new Font("方正舒体", Font.PLAIN, 24);
public ListMainView() throws HeadlessException {
initWindow();
headPanelWindow();
MainWindow();
}
private Client client;
public ListMainView(User user, Client client) throws HeadlessException {
this.user = user;
this.client = client;
initWindow();
headPanelWindow();
MainWindow();
}
public void MainWindow() {
mainPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
mainPanel.setBackground(Color.white);
box.add(Box.createVerticalStrut(86));
box.add(mainPanel);
belowPanel = new JPanel();
game = new JButton("---娱乐一分钟,幸福快乐生活一辈子!---");
game.setForeground(Color.GREEN);
box.add(game);
game.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new latticeMaze(user).start();
}
});
DefaultMutableTreeNode node = new DefaultMutableTreeNode("联系人列表");
// 子目录
DefaultMutableTreeNode node_1 = new DefaultMutableTreeNode("都识的好友呵");
node.add(node_1);
/*
* 遍历好友列表
*/
FriendsDatabaseUtil util = new FriendsDatabaseUtil();
list = (List<User>) util.getByID("" + user.getUser_id());
for (User user : list) {
DefaultMutableTreeNode node_1_1 = new DefaultMutableTreeNode(user);
node_1.add(node_1_1);
}
tree = new JTree(node);
mainPanel.add(tree);
this.add(box);
box.add(Box.createVerticalStrut(5));
listenerTree();
}
class latticeMaze extends Thread {
private User user;
public latticeMaze(User user) {
this.user = user;
}
@Override
public void run() {
Maze maze = new Maze(user);
maze.start();
}
}
/**
* 对树子叶监听
*/
public void listenerTree() {
tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
TreePath path = tree.getPathForLocation(e.getX(), e.getY());
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
.getLastPathComponent();
Object object = node.getUserObject();
if (e.getClickCount() == 2 && node.isLeaf()
&& object instanceof User) {
User toUser = (User) object;
breakWindom(toUser);
}
}
});
}
/**
* 页面跳转
*
* @param name
*/
public void breakWindom(User toUser) {
// this.dispose();关闭当前窗口
new PrivyThread(toUser, user, client).start();
}
/**
* 框架初始化
*/
public void initWindow() {
this.setTitle("登录");
// 设置窗体位置和大小
this.setBounds((int) ((width - windowWidth) * 1.0 / 1.1),
((height - windowHeight) / 9), windowWidth, windowHeight);
this.setLayout(new BorderLayout(3, 1));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setUndecorated(true);// 去掉窗口的装饰
this.getRootPane().setWindowDecorationStyle(JRootPane.WIDTH);
this.setResizable(false);// 设置窗体不可改变大小
// 设置窗口图标
Image img = Toolkit.getDefaultToolkit().getImage("image\\sprout01.png");
this.setIconImage(img);
this.setVisible(true);
}
private JLabel sm1, sm2;
/**
* 顶部面板
*/
public void headPanelWindow() {
headPanel = new JPanel(null) {
@Override
protected void paintComponent(Graphics g) {
ImageIcon icon = new ImageIcon("image\\main\\cloud02.png");
Dimension dim = getSize();
g.drawImage(icon.getImage(), -100, 0, dim.width, dim.height,
null);
}
};
headPanel.setBounds(0, 0, width, 86);
this.add(headPanel);
headButton = new JButton(new ImageIcon(user.getUser_icon()));
headButton.setBounds(10, 16, 60, 60);
listenerMonsterChat();
headPanel.add(headButton);
Namelabel = new JLabel(user.getUser_nickname(), new ImageIcon(
"image\\cancel01.png"), 4);
Namelabel.setBounds(80, 16, 60, 15);
headPanel.add(Namelabel);
signature = new JLabel(user.getLog_autograph());
signature.setBounds(80, 40, 140, 15);
signature.setForeground(new Color(173, 173, 173));
headPanel.add(signature);
sm1 = new JLabel("MCR: " + user.getUser_money());
sm1.setForeground(Color.yellow);
sm1.setBounds(80, 60, 100, 20);
sm1.setFont(f2);
sm2 = new JLabel("币");
sm2.setFont(f1);
sm2.setForeground(Color.yellow);
sm2.setBounds(180, 60, 25, 20);
addFriends = new JLabel(new ImageIcon("image\\main\\user01.png"));
addFriends.setBounds(235, 55, 25, 25);
addFriends.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
new ChatRoomThread(user).start();
}
@Override
public void mouseEntered(MouseEvent e) {
addFriends.setIcon(new ImageIcon("image\\main\\user02.png"));
}
@Override
public void mouseExited(MouseEvent e) {
addFriends.setIcon(new ImageIcon("image\\main\\user01.png"));
}
});
headPanel.add(addFriends);
headPanel.add(sm1);
headPanel.add(sm2);
// 关闭窗口时事件
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
JOptionPane.showMessageDialog(ListMainView.this, "确定要退出程序?",
"温馨提示", JOptionPane.PLAIN_MESSAGE,
new ImageIcon("image\\sprout01.png"));
System.exit(0);// 退出程序
}
});
}
/**
* 头像点击监听
*/
private void listenerMonsterChat() {
headButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new UserUpdate(user).start();
}
});
headButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
new UserInfo(user).start();
}
@Override
public void mouseExited(MouseEvent e) {
new UserInfo(user).stop();
infoShow.dispose();
}
});
}
private UserInfoShow infoShow;
class UserInfo extends Thread {
User user = null;
public UserInfo(User user) {
this.user = user;
}
@Override
public void run() {
infoShow = new UserInfoShow(user);
}
}
class UserUpdate extends Thread {
User user = null;
public UserUpdate(User user) {
this.user = user;
}
@Override
public void run() {
new UserUpdateInformation(user.getUser_nickname(),
user.getUser_sex(), user.getUser_icon(),
user.getUser_email(), user.getUser_money(),
user.getRegister_date(), user.getLog_autograph(), user);
}
}
}
主聊天程序
私聊
如上图:好友之间可以进行私人聊天,当然,这里的离线消息,也是可以接收到的
,同时界面的历史记录用户也是可以获取到的,后台都有记录群聊房间
(这里采用了网上一兄弟的界面绘制) 如上图:不管是否好友的关系,只要注册了用户,就可以和所有用户进行通信,(这里开启了一个单独的子服务端口)服务器也可以进行监听所有消息,可以对所有用户发送消息
本项目,采用SQL Server2008数据库做后台,共四张简单表结构组成
主要针对用户的基本信息结构设计
如上图:整个项目的目录结构
因为代码量比较大,所以没有全部贴出,有需要的可以去我的资源中下载整个项目源码包括(项目源码,后台数据库,PPT简介)!
因为是个人原创耗时一个礼拜,所以请赏5个金币吧!感谢了!
下载地址:http://download.csdn.net/detail/qq_33624284/9708767