【Java】涉及到GUI、JAVASE、网络编程、多线程、数据库的聊天系统,非常适合大学Java课程的练手

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 【Java】涉及到GUI、JAVASE、网络编程、多线程、数据库的聊天系统,非常适合大学Java课程的练手

前言

本篇文章适合刚刚学完JavaSE、GUI、多线程、网络变成的JAVA新手,出自于java课程的课程设计。本课设全方位的涉及到了以上的知识点,对于大二刚刚接触JAVA的同学而言,是一个非常好的练手项目。


一、核心知识

本篇的核心知识有GUI、网络编程(包括UDP、TCP网络编程),Maven的使用,Java连接数据库、Java的基础知识、MySQL的使用等等。
本篇课设模仿了一个网络通讯工具,实现了登录、注册、修改密码、注销、两人聊天,群聊、添加好友等功能。
其中最核心的在于利用线程池的方式来管理服务器的连接,举个例子:群聊是如何实现的?即用户A向服务端发送消息,服务端接收到消息后,会将该消息转发给连接服务端的所有用户端,从而达到了群聊的效果。
本篇课设中通过多线程的方法,可以登录多个账号,其中私聊使用了TCP的方式、群聊使用了UDP的方式,而且本篇课设还涉及到了GUI的大量使用。

二、效果

1.注册

分别用到了select、insert语句,先在数据库中查询用户名是否存在,若存在则弹出用户名已存在,若不存在则执行insert语句,插入到数据库中。
注册
注册成功

2、登录

用select语句联表查询用户名和密码,如果有用户说明密码正确,如果返回值为空,说明密码或者用户名错误。
登录
登录成功

3、修改密码

使用select语句先检查用户名和原密码是否存在,如果正确,则使用update语句更新密码
在这里插入图片描述

4、注销

使用delete语句,将该用户列删除,并退出主界面,以实现注销的效果。
在这里插入图片描述

5、主界面

主界面初始化主界面有管理员,以及群聊的按钮。主要功能有聊天,添加好友,添加信息的查看,注销的功能
在这里插入图片描述

6、添加好友

insert语句的使用,但是插入之前需要判断一下,对方是否同意,如果对方同意在相互的表里插入相互的信息,如果不同意,则不插入。符合数据的一致性
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7、私聊

运用了TCP网络编程固定知识。超过一定的时间段,会显示发送的时间
在这里插入图片描述

在这里插入图片描述

8、群聊

使用群聊之前需要手动打开ServerChat2,使用了UDP网络编程的知识。
在这里插入图片描述

源代码

1、实体类

Examine.java

package pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


public class Examine {
    int id;
    String friendName;
    int friendPort;
    String user;
    char status;

    public Examine() {
    }

    public Examine(int id, String friendName, int friendPort, String user, char status) {
        this.id = id;
        this.friendName = friendName;
        this.friendPort = friendPort;
        this.user = user;
        this.status = status;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFriendName() {
        return friendName;
    }

    public void setFriendName(String friendName) {
        this.friendName = friendName;
    }

    public int getFriendPort() {
        return friendPort;
    }

    public void setFriendPort(int friendPort) {
        this.friendPort = friendPort;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public char getStatus() {
        return status;
    }

    public void setStatus(char status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Examine{" +
                "id=" + id +
                ", friendName='" + friendName + '\'' +
                ", friendPort=" + friendPort +
                ", user='" + user + '\'' +
                ", status=" + status +
                '}';
    }
}

People.java

package pojo;

public class People {
//    int id;
    String user;
    String pwd;
    int port;

    public People() {
    }

    public People(int id, String user, String pwd,int port) {
//        this.id = id;
        this.user = user;
        this.pwd = pwd;
        this.port = port;
    }

//    public int getId() {
//        return id;
//    }

//    public void setId(int id) {
//        this.id = id;
//    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    @Override
    public String toString() {
        return "People{" +
//                "id=" + id +
                ", user='" + user + '\'' +
                ",  + pwd + '\'' +
                ", port=" + port +
                '}';
    }
}

2、功能类

AddUser.java

package QQChat;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class AddUser implements Runnable{
    String userName;
    int port;

    public AddUser(String userName, int port) {
        this.userName = userName;
        this.port = port;
    }


    public void init() {
        final JFrame jFrame = new JFrame("添加朋友");
        jFrame.setSize(430, 116);
        jFrame.setLocation(700, 200);
        /*2、来个面板*/
        JPanel jPanel = new JPanel();
        jPanel.setSize(jFrame.getWidth(), jFrame.getHeight());
        /*3、添加文本框,密码框*/
        final JTextField jTextField = new JTextField(15);

        /*4、来个标签,三个一个背景,一个用户名,一个密码*/
        JLabel label1 = new JLabel("用户名:");

        label1.setForeground(new Color(0xD2C11B));
        ImageIcon icon = new ImageIcon("D:\\Maven\\JavaWeb\\feng.javaweb.cookie\\ComeToChat\\src\\main\\img\\bj3.png");
        JLabel imgLabel = new JLabel(icon);
        imgLabel.setSize(430, 116);
        label1.setBounds(20, 23, 45, 32);

        /*6、加一个注册按钮*/
        JButton registerButton = new JButton("添加");
        /*7、加一个修改密码的按钮*/
        jTextField.setBounds(85, 25, 120, 24);
        registerButton.setBounds(280, 25, 80, 24);

//        jFrame.setUndecorated(true);//删除标题栏
        jFrame.add(registerButton);
        jFrame.add(label1);
        jFrame.add(imgLabel);
        jFrame.add(jTextField);

        jFrame.add(jPanel);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭
        jFrame.setResizable(false);
        jFrame.setVisible(true);
        registerButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                String user = jTextField.getText();
                /*1、需要查询用户名是否重复*/
                /*2、插入*/
                String driver = "com.mysql.cj.jdbc.Driver";
                String url = "jdbc:mysql://localhost:3306/smm?useSSL=true&useUnicode=true&characterEncoding=utf8";
                String username = "root";
                String pass = "202";
                Connection connection = null;
                Statement statement = null;
                ResultSet resultSet = null;
                String userSql = "select * from smm.people where people.user='" + user +"';";//查看user是否重复了
                String user2Sql = "select * from user_view where user='" + user +"' and  friend ='"+userName+"';";//查看user是否重复了
                System.out.println(user2Sql);
                String intoSql = "insert into smm.examine(friendName,friendPort,user) values('"+userName+"','"+port+"','"+user+"')";
                System.out.println(intoSql);
                System.out.println(userSql);
                try {
                    Class.forName(driver);
                    connection = DriverManager.getConnection(url, username, password);
                    statement = connection.createStatement();
                    if ( jTextField.getText().isEmpty()) {
                        JOptionPane.showMessageDialog(null, "输入不可为空");

                    } else {
                        resultSet = statement.executeQuery(userSql);
                        if (resultSet.next()) {
                            ResultSet resultSet1 = null;
                            resultSet1 = statement.executeQuery(user2Sql);
                            if(resultSet1.next()||user.equals(userName))
                            {
                                JOptionPane.showMessageDialog(null, "您和他已经是朋友啦");
                            }else{
                                JOptionPane.showMessageDialog(null, "已发送验证信息");
                                statement.execute(intoSql);

                            }

//                                jFrame.setVisible(false);
//                                new Login().init();

                        } else {
                            JOptionPane.showMessageDialog(null, "查无此人");
                        }
                    }

                } catch (Exception exception) {
                    exception.printStackTrace();
                }

            }
        });
    }

    @Override
    public void run() {
        init();
    }
}

ChangePWd.java

package QQChat;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class ChangePwd {
    public void init() {
        final JFrame jFrame = new JFrame("修改密码");
        jFrame.setSize(442, 589);
        jFrame.setLocation(700, 200);
        /*2、来个面板*/
        JPanel jPanel = new JPanel();
        jPanel.setSize(jFrame.getWidth(), jFrame.getHeight());
        /*3、添加文本框,密码框*/
        final JTextField jTextField = new JTextField(15);
        final JPasswordField jPasswordField = new JPasswordField(15);
        final JPasswordField reJPasswordField = new JPasswordField(15);
        /*4、来个标签,三个一个背景,一个用户名,一个密码*/
        JLabel label1 = new JLabel("用户名:");
        label1.setForeground(new Color(0x0E8DCE));
        JLabel label2 = new JLabel("密 码:");
        label2.setForeground(new Color(0x060D11));
        JLabel label3 = new JLabel("新密码:");
        label3.setForeground(new Color(0x07EABD));
        ImageIcon icon = new ImageIcon("D:\\Maven\\JavaWeb\\feng.javaweb.cookie\\ComeToChat\\src\\main\\img\\bj3.png");
        ;
        JLabel imgLabel = new JLabel(icon);
        imgLabel.setSize(442, 589);
        label1.setBounds(32, 122, 45, 32);
        label2.setBounds(32, 156, 45, 32);
        label3.setBounds(32, 190, 45, 32);

        /*6、加一个注册按钮*/
        JButton registerButton = new JButton("修改");
        registerButton.setBounds(150, 280, 100, 32);
        /*7、加一个修改密码的按钮*/
        jTextField.setBounds(80, 128, 270, 24);
        jPasswordField.setBounds(80, 162, 270, 24);
        reJPasswordField.setBounds(80, 196, 270, 24);
        jFrame.add(registerButton);
        jFrame.add(label1);
        jFrame.add(label2);
        jFrame.add(label3);
        jFrame.add(imgLabel);
        jFrame.add(jTextField);
        jFrame.add(jPasswordField);
        jFrame.add(reJPasswordField);
        jFrame.add(jPanel);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭
        jFrame.setResizable(false);
        jFrame.setVisible(true);
        registerButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if ( jTextField.getText().isEmpty() || jPasswordField.getText().isEmpty() || reJPasswordField.getText().isEmpty()) {
                    JOptionPane.showMessageDialog(null, "输入不可为空");
                } else {
                    String user = jTextField.getText();
                    String p1 = jPasswordField.getText();
                    String p2 = reJPasswordField.getText();

                        /*1、需要查询用户名是否重复*/
                        /*2、插入*/
                        String driver = "com.mysql.cj.jdbc.Driver";
                        String url = "jdbc:mysql://localhost:3306/smm?useSSL=true&useUnicode=true&characterEncoding=utf8";
                        String username = "root";
                        String pass = "20022";
                        Connection connection = null;
                        Statement statement = null;
                        ResultSet resultSet = null;
                        String userSql = "select * from smm.people where people.user='" + user + "' and people.pwd ="+"'"+p1+"';";
                        System.out.println(userSql);
                        try {
                            Class.forName(driver);
                            connection = DriverManager.getConnection(url, username, password);
                            statement = connection.createStatement();
                            if (jPasswordField.getText().isEmpty() || jTextField.getText().isEmpty()) {
                                JOptionPane.showMessageDialog(null, "输入不可为空");

                            } else {
                                resultSet = statement.executeQuery(userSql);
                                if (resultSet.next()) {
                                    int id = resultSet.getInt("id");
                                    String updateSql = "update smm.people set people.pwd = "+p2+" where id ="+id+"; ";
                                    statement.execute(updateSql);
                                    JOptionPane.showMessageDialog(null, "修改成功");
                                    jFrame.setVisible(false);
                                    new Login().init();

                                } else {
                                    JOptionPane.showMessageDialog(null, "原密码错误");
                                }
                            }

                        } catch (Exception exception) {
                            exception.printStackTrace();
                        }

                }
            }
        });
    }
}

ClientChat.java

package QQChat;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ClientChat implements Runnable {
    private String Myname = null;
    private JTextArea ta = new JTextArea(10, 20);
    //聊天记录输入区
    private JTextField tf = new JTextField(20);
    private Boolean flag = false;

    //端口
    // 静态常量主机端口号
    private static final String CONNSTR = "127.0.0.1";
    // 静态常量服务器端口号
    private static final int CONNPORT = 1111;
    private Socket socket = null;
    Date passDate = new Date();
    JTextArea area = new JTextArea(100, 10);
    //Client发送数据
    private DataOutputStream dataOutputStream = null;

    public ClientChat(String myname) {
        Myname = myname;
    }

    public void init() {
        try {
            socket = new Socket(CONNSTR, CONNPORT);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        if(!flag)
        {
            send(Myname+"进入群聊");
            flag=true;
        }
        passDate.setTime(0);
        JScrollPane tf = new JScrollPane(area);//为文本域添加滑动条
        final JTextField ta = new JTextField();
        JFrame jFrame = new JFrame();
        JPanel jPanel1 = new JPanel();
        jFrame.setLayout(null);
        jPanel1.setLayout(null);
        JLabel p1Label = new JLabel(Myname+"和他朋友的聊天室");
        p1Label.setFont(new Font("宋体", Font.BOLD, 25));
        p1Label.setForeground(new Color(0xD753A7D0, true));
        p1Label.setBounds(21, 10, 300, 50);
        jPanel1.add(p1Label);
        jPanel1.setBackground(new Color(250, 250, 250));
        jPanel1.setBounds(0, 0, 861, 69);
        tf.setBounds(0, 67, 861, 286);
        ta.setBounds(0, 356, 861, 150);
        ta.requestFocus();//光标聚焦
        area.setEditable(false);//聊天区域不可以输入
        JPanel jPanel2 = new JPanel();
        jPanel2.setLayout(null);
        jPanel2.setBounds(0, 285 + 207, 863, 70);
        jPanel2.setBackground(new Color(0x285856));
        jPanel1.setBackground(new Color(0x285856));
        /*发送按钮*/
        area.setFont(new Font("宋体", Font.BOLD, 20));
        tf.setBackground(Color.CYAN);
        ta.setFont(new Font("宋体", Font.BOLD, 18));
        JButton SButton = new JButton();
        SButton.setIcon(new ImageIcon("D:\\Maven\\JavaWeb\\feng.javaweb.cookie\\demo02\\src\\Chart\\fs2.png"));
        SButton.setBounds(730, 0, 110, 36);
        //加个背景
        ImageIcon icon = new ImageIcon("D:\\Maven\\JavaWeb\\feng.javaweb.cookie\\demo03\\src\\main\\img\\QQBJ.png");
        JLabel QQJlabel = new JLabel(icon);
        JLabel qqJlabel = new JLabel(icon);
        QQJlabel.setBounds(0,0,877,69);
        qqJlabel.setBounds(0,0,877,69);
        jPanel2.add(SButton);
        jFrame.add(jPanel2);
        jFrame.add(tf);
        jFrame.add(ta);
        jFrame.add(jPanel1);
        jFrame.setResizable(false);
        jFrame.setBounds(497, 110, 877, 599);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        jFrame.setVisible(true);
        ta.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String strSend = ta.getText();
                if (strSend.length() == 0) {
                    return;
                }
                Date day = new Date();
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String time = df.format(day);
                System.out.println(time);
                if((day.getTime()-passDate.getTime())>60000)
                {
                    passDate=day;
                    area.append(time + "\n");
                }
                send(Myname+":"+strSend);
                ta.setText("");
                area.setForeground(Color.BLACK);
            }
        });
        SButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                String strSend = ta.getText();
                if (strSend.length() == 0) {//判断是否为空
                    return;
                }
                Date day = new Date();
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String time = df.format(day);
                System.out.println(time);
                if((day.getTime()-passDate.getTime())>60000)
                {
                    passDate=day;
                    area.append(time + "\n");
                }
                ta.setText("");
                area.setForeground(Color.BLACK);
            }
        });
        reciver();
    }
    /**
     * 客户端发送信息到服务器上的方法
     */
    public void send(String str) {
        try {
            dataOutputStream = new DataOutputStream(socket.getOutputStream());
            dataOutputStream.writeUTF(str);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /*接收服务器传过来的信息*/
    public void reciver() {
        try {
            DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
            while (true) {
                String str = dataInputStream.readUTF();
                area.append(str + "\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        init();
    }

}

Login.java

package QQChat;

import pojo.People;

import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.*;

public class Login implements Runnable{
    void init()
    {
        /*1、来个框架*/
        final JFrame jFrame = new JFrame("登录");
        jFrame.setSize(442,589);
        jFrame.setLocation(700,200);
        /*2、来个面板*/
        JPanel jPanel = new JPanel();
        jPanel.setSize(jFrame.getWidth(),jFrame.getHeight());
        /*3、添加文本框,密码框*/
        final JTextField  jTextField = new JTextField(15);
        final JPasswordField jPasswordField = new JPasswordField(15);
        /*4、来个标签,三个一个背景,一个用户名,一个密码*/
        JLabel label1 = new JLabel("用户名:");
        JLabel label2 = new JLabel("密 码:");
        ImageIcon icon = new ImageIcon("D:\\Maven\\JavaWeb\\feng.javaweb.cookie\\demo03\\src\\main\\img\\bj2.png");;
        JLabel imgLabel = new JLabel(icon);
        imgLabel.setSize(442,589);
        label1.setBounds(32,122,45,32);
        label2.setBounds(32,156,45,32);
        /*5、来个按钮*/
        JButton loginButton = new JButton("登陆");
        loginButton.setBounds(150,221,100,32);
        /*6、加一个注册按钮*/
        JButton registerButton = new JButton("注册");
        registerButton.setBounds(150,280,100,32);
        /*7、加一个修改密码的按钮*/
        JButton updateButton = new JButton("修改密码");
        updateButton.setBounds(150,339,100,38);
//        jPanel.setLayout(null);//不设置布局
        jTextField.setBounds(80,128,270,24);
        jPasswordField.setBounds(80,162,270,24);
        jFrame.add(loginButton);
        jFrame.add(registerButton);
        jFrame.add(updateButton);
        jFrame.add(label1);
        jFrame.add(label2);
        jFrame.add(imgLabel);
        jFrame.add(jTextField);
        jFrame.add(jPasswordField);
        jFrame.add(jPanel);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭
        jFrame.setResizable(false);
        jFrame.setVisible(true);
        /*为登录按钮添加监听器*/
        loginButton.addMouseListener(new MouseAdapter() {//添加适配器,只需要重写自己想要想要的方法
            public void mouseClicked(MouseEvent e) {
                //获得文本框的内容

                //差一个sql语句用来检验,能否登录成功
                People people = null;
                String user = jTextField.getText();
                String pwd = jPasswordField.getText();
                System.out.println("账号"+user);
                System.out.println("是否等于空"+user.isEmpty());
                System.out.println("密码"+pwd);
                String driver = "com.mysql.cj.jdbc.Driver";
                String url = "jdbc:mysql://localhost:3306/smm?useSSL=true&useUnicode=true&characterEncoding=utf8";
                String username = "root";
                String paord = "222";
                Connection connection = null;
                Statement statement = null;
                ResultSet resultSet = null;
                String sql = "select * from smm.people where people.user='"+user+"' and people.pwd="+pwd;
                System.out.println(sql);
                try {
                    Class.forName(driver);
                    connection = DriverManager.getConnection(url, username, password);
                    statement = connection.createStatement();

                    if (jPasswordField.getText().isEmpty()||jTextField.getText().isEmpty())
                    {
                        JOptionPane.showMessageDialog(null,"输入不可为空");

                    }else{
                        resultSet = statement.executeQuery(sql);
//                        String hsSql = "select getuser('"+user+"','"+pwd+"');";
//                        System.out.println(hsSql);
//                        CallableStatement cs = connection.prepareCall(hsSql, Types.INTEGER, 0);
//                        cs.execute();

                        if (resultSet==null)
                        {
                            System.out.println("resultSet空的");
                        }
                        if(resultSet.next())
                        {
                            int userPort = resultSet.getInt("port");
                            JOptionPane.showMessageDialog(null,"登录成功");
                            jFrame.setVisible(false);
                            new Thread(new Screen(user,userPort)).start();

                        }else{
                            JOptionPane.showMessageDialog(null,"用户名或者密码不正确");
                        }
                    }

                } catch (Exception exception) {
                    exception.printStackTrace();
                }

            }
        });
        registerButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                //跳转到点击类
                jFrame.setVisible(false);
                new Register().init();
            }
        });
        updateButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                //调转到修改密码类
                System.out.println("点击了修改密码");
                jFrame.setVisible(false);
                new ChangePwd().init();
            }
        });
    }


    @Override
    public void run() {
        init();
    }
}

Register.java

package QQChat;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class Register {
    public void init()
    {
        final JFrame jFrame = new JFrame("注册");
        jFrame.setSize(442,589);
        jFrame.setLocation(700,200);
        /*2、来个面板*/
        JPanel jPanel = new JPanel();
        jPanel.setSize(jFrame.getWidth(),jFrame.getHeight());
        /*3、添加文本框,密码框*/
        final JTextField  jTextField = new JTextField(15);
        final JPasswordField jPasswordField = new JPasswordField(15);
        final JPasswordField reJPasswordField = new JPasswordField(15);
        final JTextField portJPasswordField = new JTextField(15);
        /*4、来个标签,三个一个背景,一个用户名,一个密码*/
        JLabel label1 = new JLabel("用户名:");
        label1.setForeground(new Color(0x0E8DCE));
        JLabel label2 = new JLabel("密 码:");
        label2.setForeground(new Color(0x060D11));
        JLabel label3 = new JLabel("确认:");
        label3.setForeground(new Color(0x07EABD));
        JLabel label4 = new JLabel("端口:");
        label4.setForeground(new Color(0x6820EF));
        ImageIcon icon = new ImageIcon("D:\\Maven\\JavaWeb\\feng.javaweb.cookie\\ComeToChat\\src\\main\\img\\bj3.png");;
        JLabel imgLabel = new JLabel(icon);
        imgLabel.setSize(442,589);
        label1.setBounds(32,122,45,32);
        label2.setBounds(32,156,45,32);
        label3.setBounds(32,190,45,32);
        label4.setBounds(32,224,45,32);
        /*6、加一个注册按钮*/
        JButton registerButton = new JButton("注册");
        registerButton.setBounds(150,280,100,32);
        /*7、加一个修改密码的按钮*/
        jTextField.setBounds(80,128,270,24);
        jPasswordField.setBounds(80,162,270,24);
        reJPasswordField.setBounds(80,196,270,24);
        portJPasswordField.setBounds(80,230,270,24);
        jFrame.add(registerButton);
        jFrame.add(label1);
        jFrame.add(label2);
        jFrame.add(label3);
        jFrame.add(label4);
        jFrame.add(imgLabel);
        jFrame.add(jTextField);
        jFrame.add(jPasswordField);
        jFrame.add(reJPasswordField);
        jFrame.add(portJPasswordField);
        jFrame.add(jPanel);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭
        jFrame.setResizable(false);
        jFrame.setVisible(true);
        registerButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(portJPasswordField.getText().isEmpty()||jTextField.getText().isEmpty()||jPasswordField.getText().isEmpty()||reJPasswordField.getText().isEmpty())
                {
                    JOptionPane.showMessageDialog(null,"输入不可为空");
                }else{
                    String user = jTextField.getText();
                    String p1 = jPasswordField.getText();
                    String p2 = reJPasswordField.getText();
                    String port = portJPasswordField.getText();
                    if(!p1.equals(p2))
                    {
                        JOptionPane.showMessageDialog(null,"两次密码输入不一致");
                    }else{
                        /*1、需要查询用户名是否重复*/
                        /*2、插入*/
                        String driver = "com.mysql.cj.jdbc.Driver";
                        String url = "jdbc:mysql://localhost:3306/smm?useSSL=true&useUnicode=true&characterEncoding=utf8";
                        String username = "root";
                        String pass = "2";
                        Connection connection = null;
                        Statement statement = null;
                        ResultSet resultSet = null;
                        String userSql = "select * from smm.people where people.user='"+user+"';";//查看user是否重复了
                        String portSql = "select * from smm.people where people.port='"+port+"';";//查看port是否重复了
                        String intoPeople = "insert into smm.people(user,pwd,port) values("+"'"+user+"'"+",'"+p1+"',"+"'"+port+"');";
                        String intoUserport = "insert into smm.userport(user,usedport,friendhost,friend,port) values("+"'"+user+"',"+1234+","+port+","+"'fx'"+","+4321+");";
                        String intoUserport2 = "insert into smm.userport(user,usedport,friendhost,friend,port) values("+"'fx'"+","+1234+","+4321+","+"'"+user+"',"+port+");";
                        System.out.println(intoPeople);
                        System.out.println(intoUserport);
                        try {
                            Class.forName(driver);
                            connection = DriverManager.getConnection(url, username, password);
                            statement = connection.createStatement();
                            if (jPasswordField.getText().isEmpty()||jTextField.getText().isEmpty())
                            {
                                JOptionPane.showMessageDialog(null,"输入不可为空");

                            }else{
                                resultSet = statement.executeQuery(userSql);
                                if(resultSet.next())
                                {

                                    JOptionPane.showMessageDialog(null,"用户名已经存在");
                                }else{
                                    resultSet = statement.executeQuery(portSql);
                                    if(resultSet.next())
                                    {
                                        JOptionPane.showMessageDialog(null,"端口号已经存在");
                                    }else{
                                        statement.execute(intoPeople);
                                        statement.execute(intoUserport);
                                        System.out.println(intoUserport2);
                                        statement.execute(intoUserport2);
                                        JOptionPane.showMessageDialog(null,"注册成功");
                                        jFrame.setVisible(false);
                                        new Login().init();
                                    }
                                }
                            }

                        } catch (Exception exception) {
                            exception.printStackTrace();
                        }
                    }
                }
            }
        });
    }

//    public static void main(String[] args) {
//        new Register().init();
//    }
}

Screen.java

package QQChat;
import QQChat.ClientChat;
import QQChat.Login;
import QQChat.WeChat;
import sun.management.snmp.jvmmib.JvmRTInputArgsEntryMBean;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.*;
import java.util.Vector;

/*搞个界面*/
public class Screen implements Runnable{


    public static String username;
    public static int userPort;
    static Vector<String>  vector = new Vector<String>();
    public Screen(String username,int userPort) {
        this.username = username;//获得用户名
        this.userPort = userPort;
    }
    static Connection connection = null;
    static Statement statement = null;
    static ResultSet resultSet = null;
    public void init() throws Exception {
        String driver = "com.mysql.cj.jdbc.Driver";
        String url = "jdbc:mysql://localhost:3306/smm?useSSL=true&useUnicode=true&characterEncoding=utf8";
        String user = "root";
        String pass = "2";
        String sql = "select * from userport where userport.user='"+username+"'";
        System.out.println(sql);
        Class.forName(driver);
        int l=0;
        int height = 0;//用于动态管理滚动条
        try {
            connection = DriverManager.getConnection(url, user, password);
            statement = connection.createStatement();
            resultSet = statement.executeQuery(sql);
            while(resultSet.next())
            {
                l++;
                System.out.println(resultSet.getString("friend"));
                vector.add(resultSet.getString("friend"));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        if(l>8)
        {
            height = 503;
        }else{
            height = l*60;
        }
        int x = 0;
        double row=3.9;
        final JFrame jFrame = new JFrame("Main Screen");
        JPanel jPanel = new JPanel();
        jPanel.setSize(358,800);
        jFrame.setLayout(null);
        jPanel.setBackground(Color.white);
        jFrame.setBackground(Color.white);
        /*1、加个头像标签*/
        ImageIcon icon = new ImageIcon("D:\\Maven\\JavaWeb\\feng.javaweb.cookie\\ComeToChat\\src\\main\\img\\lyf.png");
        JLabel txLabel = new JLabel(icon);
        /*2、好友的标签*/
        JLabel friendLabel = new JLabel("我的好友");
        friendLabel.setFont(new Font("宋体",Font.BOLD,20));
        friendLabel.setBounds(20,113,100,50);
        /*加个用户名的标签*/
        JLabel userLabel = new JLabel(username);
        userLabel.setBounds(73,36,73,36);
        userLabel.setFont(new Font("宋体",Font.BOLD,18));
        /*增加一个添加好友的功能*/
        ImageIcon addicon  = new ImageIcon("D:\\Maven\\JavaWeb\\feng.javaweb.cookie\\ComeToChat\\src\\main\\img\\添加.png");
        JButton addBtn = new JButton(addicon);
        addBtn.setBounds(255,113,31,31);
        ImageIcon messageIcon  = new ImageIcon("D:\\Maven\\JavaWeb\\feng.javaweb.cookie\\ComeToChat\\src\\main\\img\\message.png");
        JButton messageBtn = new JButton(messageIcon);
        messageBtn.setBounds(290,113,31,31);
        /*3、写个下拉框*/
        JButton jButton = new JButton("一起聊天");
        jButton.setIcon(new ImageIcon("D:\\Maven\\JavaWeb\\feng.javaweb.cookie\\demo03\\src\\main\\img\\tx.png"));
        jButton.setBounds(20,162,315,62);
        jFrame.add(jButton);
        JButton[] jbutton = new JButton[100];
        //4、写个背景图片
        ImageIcon icon1 = new ImageIcon("D:\\Maven\\JavaWeb\\feng.javaweb.cookie\\demo03\\src\\main\\img\\mainBj.png");
        JLabel jLabel = new JLabel(icon1);
        JTextPane area = new JTextPane();
        JTextArea area1 = new JTextArea((int) (l*row),10);
        System.out.println(area1.getRows());
        JScrollPane tf = new JScrollPane(area1);//为文本域添加滑动条
        /*5、写个删除按钮*/
        final String deteleL = "注销";
        JButton deleteBtn= new JButton(deteleL);
        deleteBtn.setFont(new Font("宋体",Font.BOLD,10));
        deleteBtn.setBounds(200,28,60,50);


        tf.setBackground(Color.white);
        tf.setBounds(20,220,315,height);
        area1.setLayout(null);
        area1.setBounds(0,0,315,height);
//        tf.setLayout(null);
        if (!vector.isEmpty())
        {
            int y=-63;
            for (String s : vector) {
                y+=63;
                jbutton[x] = new JButton(s);
                jbutton[x].setBounds(0,y,315,62);
                area1.add(jbutton[x++]);
            }
        }else{
            System.out.println("空的");
        }
        jFrame.add(tf);
        jFrame.add(addBtn);
        jFrame.add(messageBtn);
        jFrame.add(friendLabel);
        jFrame.add(userLabel);
        jFrame.add(txLabel);
        txLabel.setBounds(8,28,40,51);
        jFrame.setSize(358,800);
        jPanel.add(jLabel);
        jFrame.add(deleteBtn);
        jFrame.add(jPanel);
        jLabel.setBounds(-20,0,378,800);
        jFrame.setLocation(1500,50);
        jFrame.setResizable(false);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        jFrame.setVisible(true);
        jButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                /*这个地方要跳连接了*/
                System.out.println("调转到这");
                new Thread(new ClientChat(username)).start();
            }
        });
        for(int i=0;i<x;i++)
        {
            final String s = vector.elementAt(i);
            jbutton[i].addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {

                    String sql = "select * from smm.userport where user='"+username+"' and friend= '"+s+"';";
                    try {
                        ResultSet resultSet = statement.executeQuery(sql);
                        System.out.println(sql);
                        int usedport = 0;
                        int friendhost = 0;
                        String friend = null;
                        int port = 0;
                        while(resultSet.next())
                        {
                            usedport = resultSet.getInt("usedport");
                            friendhost = resultSet.getInt("friendhost");
                            friend = resultSet.getString("friend");
//                            port = resultSet.getInt("port");
                        }
                        String call = "{call check_port_username(?,?,?)}";
                        CallableStatement cs = connection.prepareCall("{call check_port_usernameTwo(?,?,?)};");
                        cs.setString(1,username);
                        cs.setString(2,friend);
                        cs.registerOutParameter(3,Types.INTEGER);
//                        System.out.println(cs.toString());
//                        cs.registerOutParameter(3, Types.INTEGER);
                        cs.execute();
                        System.out.println();
                        port = cs.getInt(3);
                        System.out.println(port);
                        new Thread(new WeChat(usedport,"localhost",friendhost,port,friend)).start();
                    } catch (SQLException throwables) {
                        throwables.printStackTrace();
                    }
                }
            });


        }
        deleteBtn.addMouseListener(new MouseAdapter() {
            int deleteI = 0;
            @Override
            public void mouseClicked(MouseEvent e) {
//                System.out.println(e.getClickCount());
                if(e.getClickCount()==2)
                {
                    System.out.println("销毁了");
                    String sql = "delete from smm.userport where user="+"'"+username+"' or friend ="+"'"+username+"';";
                    String sql2 = "delete from smm.people where user ='"+username+"';";
                    System.out.println(sql);
                    System.out.println(sql2);
                    try {
                        statement.execute(sql);
                        statement.execute(sql2);
                    } catch (Exception throwables) {
                        throwables.printStackTrace();
                    }
                    JOptionPane.showMessageDialog(null,"销毁成功");
                    jFrame.setVisible(false);
                    new Thread(new Login()).start();

                }
            }
        });
        addBtn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                new Thread(new AddUser(username,userPort)).start();
            }
        });
        messageBtn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                try {
                    new Thread(new Examine(username,userPort)).start();
                } catch (Exception classNotFoundException) {
                    classNotFoundException.printStackTrace();
                }
            }
        });
    }

    @Override
    public void run() {
        try {
            init();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

ServerChat2.java



package QQChat;

import javax.swing.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Iterator;


public class ServerChat2  {
    public static void main(String[] args)  {
       new ServerChat2().Start();
    }
    //端口
    //预留出来8890-9000给服务器端口
    private static final int PORT = 1111;
    //ServerSocket
    private ServerSocket serverSocket = null;
    private Socket socket = null;

    //Server接受数据
    private DataInputStream dataInputStream = null;

    // 多个客户端访问时,客户端对象存放入List中
    private ArrayList<ClientCoon> ccList = new ArrayList<ClientCoon>();

    // 服务器启动的标志 (其实ServerSocket ss 初始化出来时以为者服务器的启动)
    private boolean isStart = true;
    public void Start()
    {
        try {
            new ServerChat2().startServer();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }



    public void startServer() throws Exception {
        try {
            try {
                serverSocket = new ServerSocket(PORT);
                System.out.println("连接成功");
                isStart = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 可以接受多个客户端的连接
            // 接每一個信息时,服务器不可以终断,所以将其写入while()中,判断符为服务器开关的判断符
            while (isStart) {
                socket = serverSocket.accept();
                ccList.add(new ClientCoon(socket));
                System.out.println("线程池的大小是:"+ccList.size());

            }

        } catch (SocketException e) {
            System.out.println("服务器终断了!!!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    class ClientCoon implements Runnable {

        Socket socket = null;
        public ClientCoon(Socket socket) {
            this.socket = socket;
            new Thread(this).start();
        }

        //接受客户端信息(多线程run()方法)
        @Override
        public void run() {
            try {
                DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
                while (isStart) {
                    String str = dataInputStream.readUTF();
                    Iterator<ClientCoon> iterator = ccList.iterator();
                    while (iterator.hasNext()) {
                        ClientCoon clientCoon = iterator.next();
                        clientCoon.send(str);
                    }
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        // 服务器向每個连接对象发送数据的方法
        public void send(String str) {
            try {
                DataOutputStream dataOutputStream = new DataOutputStream(this.socket.getOutputStream());//建立连接了。可以发出去
                dataOutputStream.writeUTF(str);
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3、多线程

下面的代码复制粘贴几次,即代表启动几个
test.java

package QQChat;

import sun.rmi.runtime.Log;

public class test {
    public static void main(String[] args) {
        new Login().init();
    }
}

总结

大二的时候写的一个项目,由于网上没有相应的资源,加上自己写的还比较详细,所以获得了专业前三的课设成绩。这个课设写的也不算久,一个星期这样子,但是对于整个JAVA课程的巩固起到了非常大的作用,以至于即使我近半年的时间没有摸java语言,但是其中是思想我还是掌握到了的。所以把这个项目放到C站上,为大家的学习提供一个方便

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
Java 程序员
JAVA程序员的进阶之路:掌握URL与URLConnection,轻松玩转网络资源!
在Java编程中,网络资源的获取与处理至关重要。本文介绍了如何使用URL与URLConnection高效、准确地获取网络资源。首先,通过`java.net.URL`类定位网络资源;其次,利用`URLConnection`类实现资源的读取与写入。文章还提供了最佳实践,包括异常处理、连接池、超时设置和请求头与响应头的合理配置,帮助Java程序员提升技能,应对复杂网络编程场景。
55 9
|
4天前
|
缓存 Java 开发者
Java多线程并发编程:同步机制与实践应用
本文深入探讨Java多线程中的同步机制,分析了多线程并发带来的数据不一致等问题,详细介绍了`synchronized`关键字、`ReentrantLock`显式锁及`ReentrantReadWriteLock`读写锁的应用,结合代码示例展示了如何有效解决竞态条件,提升程序性能与稳定性。
|
4天前
|
安全 Java 开发者
Java中的多线程编程:从基础到实践
本文深入探讨了Java多线程编程的核心概念和实践技巧,旨在帮助读者理解多线程的工作原理,掌握线程的创建、管理和同步机制。通过具体示例和最佳实践,本文展示了如何在Java应用中有效地利用多线程技术,提高程序性能和响应速度。
28 1
|
12天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
18天前
|
安全 Java 开发者
深入解读JAVA多线程:wait()、notify()、notifyAll()的奥秘
在Java多线程编程中,`wait()`、`notify()`和`notifyAll()`方法是实现线程间通信和同步的关键机制。这些方法定义在`java.lang.Object`类中,每个Java对象都可以作为线程间通信的媒介。本文将详细解析这三个方法的使用方法和最佳实践,帮助开发者更高效地进行多线程编程。 示例代码展示了如何在同步方法中使用这些方法,确保线程安全和高效的通信。
45 9
|
21天前
|
存储 安全 Java
Java多线程编程的艺术:从基础到实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####
|
17天前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
21天前
|
Java
JAVA多线程通信:为何wait()与notify()如此重要?
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是实现线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件满足时被唤醒,从而确保数据一致性和同步。相比其他通信方式,如忙等待,这些方法更高效灵活。 示例代码展示了如何在生产者-消费者模型中使用这些方法实现线程间的协调和同步。
32 3
|
19天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
21天前
|
Java UED
Java中的多线程编程基础与实践
【10月更文挑战第35天】在Java的世界中,多线程是提升应用性能和响应性的利器。本文将深入浅出地介绍如何在Java中创建和管理线程,以及如何利用同步机制确保数据一致性。我们将从简单的“Hello, World!”线程示例出发,逐步探索线程池的高效使用,并讨论常见的多线程问题。无论你是Java新手还是希望深化理解,这篇文章都将为你打开多线程的大门。