[JAVA] 聊天模拟器的实现(连接Mysql进行登陆注册、实时通讯、传送文件)

代码主体学习自:【Java项目-QQ聊天器实现的详细教程】https://www.bilibili.com/video/BV1yP411w7yU?vd_source=8131920da818b43b46a6caf0c2212cf4

增加了登陆注册、传送文件功能

login类(登录界面):

package com.wdzl;

import com.wdzl.util.PathUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;
import static java.lang.System.exit;

public class login extends JFrame{

    private JButton loginLbl;
    private JPasswordField mimaTfd;
    private JTextField nameTfd;
    private JButton exitLbl;
    private JButton registerLbl;

    public login(){
        init();
    }

    private void init(){
        //设置窗体大小
        setSize(650,400);
        //显示设置 默认居中显示
        setLocationRelativeTo(null);
        //设置绝对布局
        setLayout(null);
        //设置标题
        setTitle("QQ聊天模拟器---用户登录");
        //设置关闭窗体时退出程序
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        //设置禁止改变窗体大小
        setResizable(false);
        //设置窗体图标(左上角)
        String qqImgPath = PathUtil.getFilePath("img/qq.png");
        ImageIcon qqIcon = new ImageIcon(qqImgPath);
        setIconImage(qqIcon.getImage());
        //设置背景
        getContentPane().setBackground(Color.decode("#f1f9f9"));
        //创建“QQ聊天模拟器”标签
        JLabel titleLbl = new JLabel("QQ聊天模拟器");
        titleLbl.setBounds(170, 30, 400, 100);
        Font font1 = new Font("楷体", Font.PLAIN+Font.BOLD, 50);
        titleLbl.setFont(font1);
        add(titleLbl);
        //创建“用户名”标签
        JLabel nameLbl = new JLabel("用户名:");
        nameLbl.setBounds(200, 140, 80, 50);
        Font font = new Font("楷体", Font.PLAIN, 20);
        nameLbl.setFont(font);
        add(nameLbl);
        //创建用户名输入框
        nameTfd = new JTextField("");
        nameTfd.setBounds(280, 140, 140, 50);
        nameTfd.setFont(font);
        add(nameTfd);
        //创建“密码”标签
        JLabel mimaLbl = new JLabel("密码:");
        mimaLbl.setBounds(210, 195, 80, 50);
        mimaLbl.setFont(font);
        add(mimaLbl);
        //创建密码输入框
        mimaTfd = new JPasswordField("");
        mimaTfd.setBounds(280, 195, 140, 50);
        mimaLbl.setFont(font);
        add(mimaTfd);
        //创建“登录”按钮
        loginLbl = new JButton("登录");
        loginLbl.setBounds(150, 290, 70, 40);
        Font font2 = new Font("楷体", Font.PLAIN, 15);
        loginLbl.setFont(font2);
        add(loginLbl);
        //创建“注册”按钮
        registerLbl = new JButton("注册");
        registerLbl.setBounds(300, 290, 70, 40);
        registerLbl.setFont(font2);
        add(registerLbl);
        //创建“退出”按钮
        exitLbl = new JButton("退出");
        exitLbl.setBounds(445, 290, 70, 40);
        exitLbl.setFont(font2);
        add(exitLbl);

        //login页面跳转-----MainFrame页面----iflogin方法
        loginLbl.addActionListener(new ActionListener() {
            public void actionPerformed (ActionEvent e){
                if (iflogin(nameTfd.getText(), mimaTfd.getText())) {
                    JOptionPane.showMessageDialog(null, "登陆成功!", "消息", -1);
                    new MainFrame().setVisible(true);
                    setVisible(false);
                } else {
                    JOptionPane.showMessageDialog(null, "登陆失败!", "消息", -1);
                }
            }
        });

        //login页面跳转-----register页面
        registerLbl.addActionListener(new ActionListener() {
            public void actionPerformed (ActionEvent e){

                new register().setVisible(true);
                setVisible(false);
            }
        });

        //login页面跳转-----终止程序
        exitLbl.addActionListener(new ActionListener() {
            public void actionPerformed (ActionEvent e){
                JOptionPane.showMessageDialog(null, "成功退出程序!", "消息", -1);
                exit(0);
            }
        });
    }

    //判断是否可以登录---在数据库中对比账号密码
    public static boolean iflogin(String name, String password) {
        if (name == null && password == null) {//判断输入是否合理
            return false;
        }
        Connection con = null;//代表数据库连接
        PreparedStatement pre = null;//用于执行预编译的SQL语句
        ResultSet resultSet = null;//存储了从数据库查询返回的结果集
        try {
            con = DriverManager.getConnection("jdbc:mysql://localhost:3307/demo", "root", "123456");
            String sql = "SELECT * FROM login WHERE name=? AND password=?";//编写SQL语句
            pre = con.prepareStatement(sql);//将SQL查询语句作为参数传入
            pre.setString(1, name);//设置第参数的值,(参数的位置,要设置的值)
            pre.setString(2, password);
            resultSet = pre.executeQuery();//执行查询,并将返回的结果集赋值
            return resultSet.next();//判断结果集中是否有下一条记录
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

register类(连接Mysql进行注册账号):

package com.wdzl;

import com.wdzl.util.PathUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;

public class register extends JFrame implements ActionListener {

    private JTextField nametfd;
    private JPasswordField mimatfd;
    private JPasswordField mimatfd2;
    private ResultSet rs;

    public register(){
        init();
    }
    public void init() {
        //设置窗体大小
        setSize(400,650);
        //显示设置 默认居中显示
        setLocationRelativeTo(null);
        //设置绝对布局
        setLayout(null);
        //设置标题
        setTitle("QQ聊天模拟器---用户注册");
        //设置关闭窗体时退出程序
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        //设置禁止改变窗体大小
        setResizable(false);
        //设置窗体图标(左上角)
        String qqImgPath = PathUtil.getFilePath("img/qq.png");
        ImageIcon qqIcon = new ImageIcon(qqImgPath);
        setIconImage(qqIcon.getImage());
        //设置背景
        getContentPane().setBackground(Color.decode("#f1f9f9"));
        //创建“用户注册”标签
        JLabel titleLbl = new JLabel("QQ用户注册");
        titleLbl.setBounds(60, 50, 300, 150);
        Font font2 = new Font("楷体", Font.PLAIN, 50);
        titleLbl.setFont(font2);
        add(titleLbl);
        //创建“用户名”标签
        JLabel nameLbl = new JLabel("用户名:");
        nameLbl.setBounds(80, 200, 90, 50);
        Font font = new Font("楷体", Font.PLAIN, 25);
        nameLbl.setFont(font);
        add(nameLbl);
        //创建用户名输入框
        nametfd = new JTextField("");
        nametfd.setBounds(180, 200, 130, 50);
        nametfd.setFont(font);
        add(nametfd);
        //创建“密码”标签
        JLabel mimaLbl = new JLabel("密码:");
        mimaLbl.setBounds(90, 260, 130, 50);
        mimaLbl.setFont(font);
        add(mimaLbl);
        //创建密码输入框
        mimatfd = new JPasswordField("");
        mimatfd.setBounds(180, 260, 130, 50);
        mimaLbl.setFont(font);
        add(mimatfd);
        //创建“确认密码”标签
        JLabel mimaLbl2 = new JLabel("确认密码:");
        mimaLbl2.setBounds(65, 320, 130, 50);
        mimaLbl2.setFont(font);
        add(mimaLbl2);
        //创建 确认密码 输入框
        mimatfd2 = new JPasswordField("");
        mimatfd2.setBounds(180, 320, 130, 50);
        mimaLbl.setFont(font);
        add(mimatfd2);
        //确定 按钮
        JButton sureBtn = new JButton("确定");
        sureBtn.setBounds(60,500,100,50);
        Font font1 = new Font("楷体", Font.PLAIN, 20);
        sureBtn.setFont(font1);
        add(sureBtn);
        //取消 按钮
        JButton exitBtn = new JButton("取消");
        exitBtn.setBounds(230,500,100,50);
        exitBtn.setFont(font1);
        add(exitBtn);

        //register页面跳转-----login页面
        exitBtn.addActionListener(new ActionListener() {
            public void actionPerformed (ActionEvent e){
                setVisible(false);
                new login().setVisible(true);

            }
        });

        //给按钮绑定监听
        sureBtn.addActionListener(this);
    }

    //监听到被点击时,代码执行这里
    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        actionPerformed();
    }

    //注册
    public void actionPerformed() {
        String name = nametfd.getText();
        String password = mimatfd.getText();
        String password2 = mimatfd2.getText();

        if (nametfd.getText().isEmpty() || mimatfd.getText().isEmpty() ||
                mimatfd2.getText().isEmpty()) {
            JOptionPane.showMessageDialog(null, "账号或密码不能为空");
            return;
        }
        Connection con = null;
        PreparedStatement pre = null;
        rs = null;//存储了从数据库查询返回的结果集
        try {
            con = DriverManager.getConnection("jdbc:mysql://localhost:3307/demo", "root", "123456");

            //检查用户名是否已存在在
            String sql = "SELECT * FROM login WHERE name=? ";
            pre = con.prepareStatement(sql);
            pre.setString(1, name);
            rs = pre.executeQuery();//执行查询,并将返回的结果集赋值

            if (rs.next()) {       //判断用户名是否重复
                JOptionPane.showMessageDialog(null, "用户名已经存在");
            }
            else {
                if (password2.equals(password)) {   //如果两次输入密码一致
                    //数据库执行操作
                    String sql2 = "INSERT INTO login(name, password) VALUES (?, ?)";
                    pre = con.prepareStatement(sql2);
                    pre.setString(1, name);
                    pre.setString(2, password);
                    pre.executeUpdate();
                    JOptionPane.showMessageDialog(null, "注册成功");

                    new login().setVisible(true);
                    this.setVisible(false);
                }
                else {
                    JOptionPane.showMessageDialog(null, "两次密码输入不一致");
                }
            }
        } catch (SQLException e) {
            throw new RuntimeException("注册失败!", e);
        }finally {
            try {
                // 关闭连接和释放资源
                if (rs != null) rs.close();
                if (pre != null) pre.close();
                if (con != null) con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

MainFrame类(聊天界面、实时通讯、传送文件):

package com.wdzl;

import com.wdzl.util.PathUtil;//使用来自com.wdzl.util包下的PathUtil类
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.*;

public class MainFrame extends JFrame implements ActionListener {
    private ImageIcon qqIcon;
    private ImageIcon headIcon;
    private DatagramSocket socket;
    private String hostIp;
    private int hostPort;
    private JTextField ipTfd;
    private JTextField sendTfd;
    private JTextField portTfd;
    private JPanel msgPanel;
    private JTextField filePathTfd;

    public MainFrame() {
        initSocket();
        loadImg();
        initFrame();
        initHead();
        initIpPort();
        initSendRecvComponents();
        initMsgPanel();
    }
    //加载图像资源
    private void loadImg() {
        String qqImgPath = PathUtil.getFilePath("img/qq.png");
        String headImgPath = PathUtil.getFilePath("img/rabbit(1).jpg");
        qqIcon = new ImageIcon(qqImgPath);
        headIcon = new ImageIcon(headImgPath);
    }
    //初始化窗体
    private void initFrame() {
        setSize(550, 500);
        setLocationRelativeTo(null);
        setLayout(null);
        setTitle("QQ聊天模拟器 " + hostIp + " : " + hostPort);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(false);
        setIconImage(qqIcon.getImage());
        getContentPane().setBackground(new Color(203, 243, 252));
    }
    //初始化socket
    private void initSocket() {
        try {
            socket = new DatagramSocket();
            hostPort = socket.getLocalPort();
            hostIp = InetAddress.getLocalHost().getHostAddress();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        new RecevierThread().start();
    }
    //初始化头像
    private void initHead() {
        JLabel headLbl = new JLabel(headIcon);
        headLbl.setSize(headIcon.getIconWidth(), headIcon.getIconHeight());
        headLbl.setLocation(390, 30);
        add(headLbl);
    }
    //初始化ip和port
    private void initIpPort() {
        JLabel ipLbl = new JLabel("IP:");
        ipLbl.setBounds(380, 200, 140, 25);
        add(ipLbl);

        ipTfd = new JTextField("");
        ipTfd.setBounds(380, 225, 150, 25);
        add(ipTfd);

        JLabel portLbl = new JLabel("Port:");
        portLbl.setBounds(380, 260, 140, 25);
        add(portLbl);

        portTfd = new JTextField("");
        portTfd.setBounds(380, 286, 150, 25);
        add(portTfd);
    }

    private void initSendRecvComponents() {
        sendTfd = new JTextField();
        sendTfd.setBounds(5, 350, 370, 30);
        add(sendTfd);

        JButton sendTextBtn = new JButton("发送文字");
        sendTextBtn.setBounds(415, 350, 90, 30);
        sendTextBtn.addActionListener(this);
        add(sendTextBtn);

        JButton selectFileBtn = new JButton("选择文件");
        selectFileBtn.setBounds(5, 390, 100, 30);
        selectFileBtn.addActionListener(this);
        add(selectFileBtn);

        filePathTfd = new JTextField();
        filePathTfd.setEditable(false);
        filePathTfd.setBounds(110, 390, 250, 30);
        add(filePathTfd);

        JButton sendFileBtn = new JButton("发送文件");
        sendFileBtn.setBounds(365, 390, 90, 30);
        sendFileBtn.addActionListener(this);
        add(sendFileBtn);
    }
    //初始化消息面板
    private void initMsgPanel() {
        msgPanel = new JPanel();
        msgPanel.setBounds(5, 5, 370, 330);
        msgPanel.setBackground(new Color(239, 239, 239));
        add(msgPanel);
    }
    //监听到被点击时,代码执行这里
    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        JButton clickedButton = (JButton) actionEvent.getSource();
        switch (clickedButton.getText()) {
            case "发送文字":
                sendMessage();
                break;
            case "选择文件":
                chooseFile();
                break;
            case "发送文件":
                sendSelectedFile();
                break;
        }
    }
    //发送消息
    private void sendMessage() {
        sendMessageAsText(sendTfd.getText());
        sendTfd.setText("");    //清空消息栏
    }
    //获取要发送的内容
    private void sendSelectedFile() {
        String filePath = filePathTfd.getText();
        if (!filePath.isEmpty()) {
            sendFile(filePath, hostIp, portTfd.getText());
        } else {
            JOptionPane.showMessageDialog(this, "请选择一个文件");
        }
    }
    //1.选择文件
    private void chooseFile() {
        JFileChooser fileChooser = new JFileChooser();
        //弹出对话框让用户选择本地文件
        if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            File selectedFile = fileChooser.getSelectedFile();
            filePathTfd.setText(selectedFile.getAbsolutePath());
        }
    }
    //2.“发送文件”按钮触发
    private void sendMessageAsText(String msg) {
        try {
            InetAddress address = InetAddress.getByName(hostIp);
            DatagramPacket packet = new DatagramPacket(msg.getBytes(), msg.length(), address, Integer.parseInt(portTfd.getText()));
            socket.send(packet);
            msgAddToMsgPanel(msg, FlowLayout.RIGHT);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "发送失败:" + e.getMessage());
        }
    }
    //发送文件
    private void sendFile(String filePath, String ip, String portStr) {
        int port = Integer.parseInt(portStr);
        try (FileInputStream fis = new FileInputStream(filePath)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            //通过循环,每次从文件中读取一定数量的字节到一个字节数组
            while ((bytesRead = fis.read(buffer)) != -1) {
                //将这个字节数组封装
                DatagramPacket packet = new DatagramPacket(buffer, bytesRead, InetAddress.getByName(ip), port);
                socket.send(packet);
            }
            JOptionPane.showMessageDialog(this, "文件发送成功!");
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this, "文件发送失败:" + e.getMessage());
        }
    }
    //发送的消息添加到消息面板
    private void msgAddToMsgPanel(String msg, int align) {
        JLabel msgLbl = new JLabel(msg, SwingConstants.CENTER);
        msgLbl.setForeground(new Color(align == FlowLayout.LEFT ? Color.BLACK.getRGB() : Color.BLUE.getRGB()));
        msgLbl.setBackground(new Color(align == FlowLayout.LEFT ? Color.WHITE.getRGB() : new Color(27, 180, 238).getRGB()));
        msgLbl.setOpaque(true);
        msgLbl.setPreferredSize(new Dimension(370, 25));
        JPanel itemPanel = new JPanel(new FlowLayout(align));
        itemPanel.setBackground(new Color(239, 239, 239));
        itemPanel.add(msgLbl);

        msgPanel.add(itemPanel);
        msgPanel.revalidate();
        msgPanel.repaint();
    }
    //在后台线程中接收通过UDP协议发送的数据包
    class RecevierThread extends Thread {
        @Override
        public void run() {
            byte[] data = new byte[1024];
            DatagramPacket packet = new DatagramPacket(data, data.length);
            StringBuilder receivedData = new StringBuilder(); // 用于暂存接收到的数据
            while (true) {
                try {
                    socket.receive(packet); //阻塞等待直到有数据报到来
                    String msg = new String(data, 0, packet.getLength());
                    // 假设文件传输以特殊标识开始和结束
                    //以"FILESTART"开头但不以"FILEEND"结尾,将其追加到receivedData中
                    if (msg.startsWith("FILESTART") && !msg.endsWith("FILEEND")) {
                        receivedData.append(msg.substring("FILESTART".length()));
                    }
                    //以"FILEEND"结尾,说明文件传输结束
                    else if (msg.endsWith("FILEEND")) {
                        receivedData.append(msg.substring(0, msg.indexOf("FILEEND")));
                        // 文件数据接收完毕,打印接收到的整个文件内容
                        System.out.println("接收到的文件内容: " + receivedData);
                        // 清空StringBuilder以便下一次接收
                        receivedData.setLength(0);
                    }
                    else {
                        // 文本消息处理
                        SwingUtilities.invokeLater(() -> {
                            msgAddToMsgPanel(msg, FlowLayout.LEFT);
                            ipTfd.setText(packet.getAddress().getHostAddress());
                            portTfd.setText(Integer.toString(packet.getPort()));
                        });
                    }
                } catch (IOException e) {
                    JOptionPane.showMessageDialog(MainFrame.this, "接收消息失败:" + e.getMessage());
                }
            }
        }
    }
}

MainTest类:

package com.wdzl;

public class TestMain {
    public static void main(String[] args) {
        new login().setVisible(true);
    }
}

代码可运行

计算机小白,请多指教

  • 13
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java语言可以与Selenium和Appium框架一起使用来进行自动化测试,通过连接到夜神模拟器,可以在模拟器中执行自动化测试脚本。 要连接到夜神模拟器,首先需要确保已经成功安装夜神模拟器Java开发环境。然后,可以按照以下步骤连接到夜神模拟器: 1. 导入必要的类库:在Java项目中,需要导入Selenium和Appium的Java客户端库,以及用于与夜神模拟器进行交互的adb库。 2. 启动夜神模拟器:使用adb命令启动夜神模拟器,例如通过命令`adb shell am start -n com.junzhu.nemu_vbox86p_64/com.bignox.app.PlayActivity`启动夜神模拟器。 3. 配置Appium连接:创建一个DesiredCapabilities对象,并设置相关的配置参数,例如设置desiredCapabilities.setCapability("platformName", "Android")等。 4. 连接到Appium服务器:创建一个WebDriver对象,通过指定Appium服务器的IP地址和端口号来连接到Appium服务器,例如通过命令`driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), desiredCapabilities)`来连接。 5. 执行自动化测试:通过WebDriver对象,可以在夜神模拟器上执行各种操作,例如查找元素、点击按钮、输入文本等。 总结:通过以上步骤,就可以使用Java语言连接到夜神模拟器,并通过Selenium和Appium框架实现自动化测试。连接到夜神模拟器后,可以利用Java语言的强大功能来编写测试脚本,并在夜神模拟器中执行这些脚本,以自动化地完成各种测试任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值