ServerSocket+Swing+SQL Server2008聊天系统(好友私聊,聊天室群聊)

来源:互联网 发布:跳舞毯哪款最好 知乎 编辑:程序博客网 时间:2024/05/15 23:50

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

1 0
原创粉丝点击