javaGUI实现多人聊天功能

 更新时间:2022年09月15日 16:27:03   作者:段茜琳  
这篇文章主要为大家详细介绍了javaGUI实现多人聊天功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了javaGUI实现多人聊天的具体代码,供大家参考,具体内容如下

服务器

package com.ff.chat.chatserver.frame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;

public class ServerFrame extends JFrame {
    JTextArea msgArea;
    ArrayList<Socket> socketArrayList = new ArrayList<>();
    boolean serverFlag = true;//服务器启动标志
    StringBuffer sb = new StringBuffer();
    ServerSocket serverSocket;
    //创建服务器端的显示窗口
    public void creatFrame(){
        this.setTitle("聊天室-服务器端");
        this.setSize(500,500);
        this.setLocationRelativeTo(null);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

        //创建一个面板
        JPanel jp = new JPanel(new BorderLayout());

        //中间面板
        JPanel centerPanel = new JPanel();
        msgArea = new JTextArea(30,40);
        msgArea.setEditable(false);
        JScrollPane jsp = new JScrollPane(msgArea);
        centerPanel.add(jsp);

        jp.add(centerPanel);

        this.add(jp);
        this.setVisible(true);
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                int res = JOptionPane.showConfirmDialog(null,"确定要关闭服务器吗?",
                        "操作提示",JOptionPane.OK_CANCEL_OPTION);
                if(res == 0){
                    try {
                        dispose();
                        serverSocket.close();
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                }
            }
        });
    }

    //启动服务器,创建ServerSocket
    public void startServer(){
        try {
            //创建ServerSocket
            serverSocket = new ServerSocket(9998);
            System.out.println("等待客户端连接");

            //循环监听客户端连接
            while (serverFlag){
                if(serverSocket.isClosed()){
                    serverFlag = false;
                    break;
                }
                Socket socket = serverSocket.accept();

                System.out.println("客户端连接成功");
                socketArrayList.add(socket);

                //为每一个客户端开启一个线程,监听客户端发来的消息
                new ServerThread(socket).start();
            }

        } catch (BindException b) {
            b.printStackTrace();
            System.out.println("服务器端口被占用");
            System.exit(0);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("服务器启动失败");
            serverFlag = false;
        }
    }

    //创建一个内部类,开启一个线程,接收消息
    class ServerThread extends Thread{
        Socket socket;
        DataInputStream in;
        DataOutputStream out;
        boolean clientFlag = true;

        public ServerThread(Socket socket){
            this.socket = socket;
            try {
                this.in = new DataInputStream(socket.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            //监听接收客户端发送的消息
            while (clientFlag){
                if(socket.isClosed()){
                    break;
                }
                try {
                    String msg = in.readUTF();//读到客户端发送的消息
                    sb.append(msg+"\n");
                    System.out.println(sb);
                    msgArea.setText(sb.toString());

                    //从服务器端向客户端发送消息
                    if(socketArrayList.size() > 0){
                        Iterator<Socket> it = socketArrayList.iterator();
                        while (it.hasNext()){
                            Socket soc = it.next();
                            if(soc.isClosed()){//当客户端某个socket已经为关闭状态,移除此socket
                                it.remove();
                                continue;
                            }
                            //客户端socket如果没有关闭,向客户端发送消息
                            out = new DataOutputStream(soc.getOutputStream());
                            out.writeUTF(sb.toString());
                            out.flush();
                        }
                    }
                } catch (EOFException ef){
                    System.out.println("ip为:"+socket.getInetAddress()+"的客户端下线了");
                    clientFlag = false;
                }catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
package com.ff.chat.chatserver.frame;

public class ServerRun {

    public static void main(String[] args) {
        ServerFrame serverFrame = new ServerFrame();
        serverFrame.creatFrame();
        serverFrame.startServer();

    }
}

客户端

注意:要在自己的电脑上运行多次客户端需要勾选如下选项

1.登录界面

package com.ff.chat.chatclient.frame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;

public class LoginFrame extends JFrame {

    JTextField accountField = null;

    //创建窗口
    public void creatFrame(){
        this.setTitle("聊天窗口");
        this.setSize(400,400);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);

        /*
        * 创建一个4行1列的面板
        * */
        JPanel jp = new JPanel(new GridLayout(4,1));

        //欢迎登陆面板
        JPanel welcomePanel = new JPanel();
        JLabel welcomLabel = new JLabel("欢迎登陆");
        welcomePanel.add(welcomLabel);

        //账号面板
        JPanel accountPanel = new JPanel();
        JLabel accountLabel = new JLabel("账号");
        accountField = new JTextField(15);
        accountPanel.add(accountLabel);
        accountPanel.add(accountField);

        //密码面板
        JPanel passwordPanel = new JPanel();
        JLabel passwordLabel = new JLabel("密码");
        JPasswordField passwordField = new JPasswordField(15);
        passwordPanel.add(passwordLabel);
        passwordPanel.add(passwordField);

        //登录按钮面板
        JPanel btnPanel = new JPanel();
        JButton loginBtn = new JButton("登录");
        JButton regBtn = new JButton("注册");
        btnPanel.add(loginBtn);
        btnPanel.add(regBtn);

        jp.add(welcomePanel);
        jp.add(accountPanel);
        jp.add(passwordPanel);
        jp.add(btnPanel);
        this.add(jp);

        this.setVisible(true);

        //组件绑定事件监听
        loginBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //获得账号密码
                String account = accountField.getText();
                String password = new String(passwordField.getPassword());
                if(account.length() == 0){
                    JOptionPane.showMessageDialog(null,"账号不能为空",
                            "操作提示",JOptionPane.WARNING_MESSAGE);
                    return;
                }
                if(password.length() == 0){
                    JOptionPane.showMessageDialog(null,"密码不能为空",
                            "操作提示",JOptionPane.WARNING_MESSAGE);
                    return;
                }

                //预留2.0版本 与数据库交互

                //连接服务器,创建Socket对象
                try {
                    Socket socket = new Socket("192.168.31.179",9998);//该地址为要连接的服务器的地址
                    new ClientFrame(socket,account).creatFrame();
                    dispose(); //释放当前登录窗口
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                    JOptionPane.showMessageDialog(null,"服务器连接失败",
                            "操作提示",JOptionPane.WARNING_MESSAGE);
                }
            }
        });
    }


}

2.聊天界面

package com.ff.chat.chatclient.frame;

import com.ff.chat.chatclient.utils.DateUtil;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Date;

public class ClientFrame extends JFrame {

    String account;
    Socket socket;
    DataOutputStream out;//数据输出字节流
    DataInputStream in;//数据输入字节流
    JTextArea msgArea;


    //创建聊天窗口时,初始化数据
    public ClientFrame(Socket socket,String account){
        this.socket = socket;
        this.account = account;
        try {
            out = new DataOutputStream(socket.getOutputStream());
            in = new DataInputStream(socket.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    //创建聊天窗口
    public void creatFrame(){
        this.setTitle("聊天窗口-"+account);
        this.setSize(500,500);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

        //创建一个面板
        JPanel jp = new JPanel(new BorderLayout());

        //中间面板
        JPanel centerPanel = new JPanel();
        msgArea = new JTextArea(30,40);
        msgArea.setEditable(false);//不可以直接编辑
        JScrollPane jsp = new JScrollPane(msgArea);
        centerPanel.add(jsp);

        //底部面板
        JPanel bottomPanel = new JPanel();
        JTextField msg = new JTextField(30);
        JButton sendBtn = new JButton("发送");
        bottomPanel.add(msg);
        bottomPanel.add(sendBtn);

        jp.add(centerPanel);
        jp.add(bottomPanel,BorderLayout.SOUTH);

        this.add(jp);
        this.setVisible(true);

        //发送按钮添加监听事件
        sendBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String m = msg.getText(); //获得客户端输入的聊天内容
                if(m.length() == 0){
                    JOptionPane.showMessageDialog(null,"不能发送空白消息");
                    return;
                }
                //向服务器发送消息
                try {
                    String ms = account+":"+DateUtil.dateStr(new Date())+"\n"+m;
                    out.writeUTF(ms);//向服务器发送消息
                    out.flush();
                    msg.setText("");//发送成功,清空聊天文本框
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                    JOptionPane.showMessageDialog(null,"服务器连接失败");
                }

            }
        });

        //聊天窗口添加事件监听
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                int res = JOptionPane.showConfirmDialog(null,"你确定要退出吗?",
                        "操作提示",JOptionPane.OK_CANCEL_OPTION);
                if(res == 0){
                    dispose();
                    new LoginFrame().creatFrame();
                }
                try {
                    socket.close();
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }
        });

        //启动一个线程,监听服务器是否向客户端发送了消息
        new ClientThread(socket).start();
    }

    //创建一个内部类
    class ClientThread extends Thread{
        //接收从服务器发来的消息
        Socket socket;
        boolean serverFlag = true;

        public ClientThread(Socket socket){
            this.socket = socket;
        }

        @Override
        public void run(){
            //监听接收服务器发来的消息
            while (serverFlag){
                try {
                    String ms = in.readUTF();
                    msgArea.setText(ms);
                } catch (IOException e) {
                    System.out.println("客户端"+account+"下线了");
                    serverFlag = false;
                }
            }
        }
    }
}

3.运行客户端

package com.ff.chat.chatclient.frame;

public class ClientRun {

    public static void main(String[] args) {
        new LoginFrame().creatFrame();
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Hibernate连接三种数据库的配置文件

    Hibernate连接三种数据库的配置文件

    今天小编就为大家分享一篇关于Hibernate连接三种数据库的配置文件,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Mybatis-Plus如何配置分页对象

    Mybatis-Plus如何配置分页对象

    本文主要介绍了Mybatis-Plus如何配置分页对象,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Servlet3.0新特性全解

    Servlet3.0新特性全解

    Servlet3.0新特性有异步处理支持、新增的注解支持、可插性支持,下面我们将逐一讲解这些新特性,通过下面的学习,读者将能够明晰了解Servlet 3.0的变化,并能够顺利使用它进行日常的开发工作
    2023-05-05
  • Java concurrency线程池之线程池原理(二)_动力节点Java学院整理

    Java concurrency线程池之线程池原理(二)_动力节点Java学院整理

    这篇文章主要为大家详细介绍了Java concurrency线程池之线程池原理第二篇,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • Spring中实现定时调度的几种方法

    Spring中实现定时调度的几种方法

    本篇文章主要介绍了Spring中实现定时调度示例,可以在无人值守的时候系统可以在某一时刻执行某些特定的功能,有兴趣的可以了解一下。
    2017-02-02
  • Spring容器中已经存在的Bean替换示例

    Spring容器中已经存在的Bean替换示例

    这篇文章主要为大家介绍了Spring容器中已经存在的Bean替换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • SpringBoot搭建全局异常拦截

    SpringBoot搭建全局异常拦截

    这篇文章主要介绍了SpringBoot搭建全局异常拦截,本文通过详细的介绍与代码的展示,详细的说明了如何搭建该项目,包括创建,启动和测试步骤,需要的朋友可以参考下
    2021-06-06
  • java awt生成签名图片如何消除锯齿化

    java awt生成签名图片如何消除锯齿化

    这篇文章主要介绍了java awt生成签名图片如何消除锯齿化,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • java生成图片验证码功能

    java生成图片验证码功能

    最近在用ssm框架做一个管理系统,做到登录验证时,需要实现图片验证码功能,今天小编给大家分享基于java制作的图片验证码功能,感兴趣的朋友一起看看吧
    2019-12-12
  • Java计算交集,差集,并集的方法示例

    Java计算交集,差集,并集的方法示例

    这篇文章主要介绍了Java计算交集,差集,并集的方法,结合实例形式简单分析了java集合运算的简单操作技巧,需要的朋友可以参考下
    2017-10-10

最新评论