用Java实现简易聊天室

article/2025/10/23 8:43:41

 

说明:如果一个 类,需要有界面的显示,那么该类就需要继承自JFrame,此时,该类就可以被称为一个“窗体类"。

 

服务端代码:

package cn.qy.chat;import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;//说明:如果一个类,需要有界面的显示,那么该类就需要继承自JFrame,此时,该类就可以被称为一个“窗体类"
//1.定义JFrame窗体中的组件
//2.在构造方法中初始化组件
//3.使用网络编程完成数据的传输(TCP,UDP协议)
//4.实现“发送”按钮的监听点击事件。需要注意的是,文本域拼接数据时,需要自己换行,不要在发送数据时换行。
public class ServerChatMain extends JFrame implements ActionListener, KeyListener {public static void main(String[] args) {// 调用构造器new ServerChatMain();}//属性//文本域private JTextArea jta;//滚动条private JScrollPane jsp;//面板private JPanel jp;//文本框private JTextField jtf;//按钮private JButton jb;//流BufferedReader br;BufferedWriter bw;//服务端端口号private static int serverPort;//静态代码块加载外部配置文件//特点1:在类加载时,自动执行//特点2:一个类只会加载一次,因此静态代码块只会执行一次static {Properties prop = new Properties();try {prop.load(new FileReader("chat.properties"));serverPort =Integer.parseInt(prop.getProperty("serverPort"));} catch (IOException e) {e.printStackTrace();}}//创建空参构造器public ServerChatMain(){//初始化组件//初始化文本域jta = new JTextArea();//设置文本域不可编辑jta.setEditable(false);//将文本域添加到滚动条中,实现滚动效果jsp = new JScrollPane(jta);//面板jp = new JPanel();jtf = new JTextField(15);jb = new JButton("发送");//将文本框与按钮添加到面板中jp.add(jtf);jp.add(jb);//将滚动条与面板全部添加到窗体中this.add(jsp, BorderLayout.CENTER);this.add(jp, BorderLayout.SOUTH);//设置 标题,大小,位置,关闭,是否可见this.setTitle("QQ 服务端");this.setSize(300,300);this.setLocation(600,300);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭,程序退出this.setVisible(true);/******************TCP 服务端 start*****************///给发送按钮绑定一个监听点击事件jb.addActionListener(this);//给文本框绑定一个键盘点击事件jtf.addKeyListener(this);//接收客户端数据,并回显到自己的文本域try {//1.创建一个服务端的套接字socketServerSocket serverSocket = new ServerSocket(serverPort);//2.等待客户端的链接Socket socket = serverSocket.accept();//客户端对象//3.获取socket 通道的输入流(输入流是实现读取数据的,一行一行读取,因此用BufferedReader-->readLinebr = new BufferedReader(new InputStreamReader(socket.getInputStream()));//4.获取socket 通道的输出流(输出流实现写出数据,也是写一行,换一行,刷新)BufferedWriter-->new Line()//什么时候需要写出数据?当用户点击发送按钮时bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));//循环读取数据,并把它拼接到文本域中String line = null;while ((line=br.readLine())!=null){//将读取的数据拼接到文本域中显示jta.append(line+System.lineSeparator());}//5.关闭serverSocket 通道serverSocket.close();} catch (IOException e) {e.printStackTrace();}/******************TCP 服务端 end*****************/}//行为/*** 重新ActionListener中的1个方法,实现点击 发送键 发送* @param e*/@Overridepublic void actionPerformed(ActionEvent e) {sendDataToSocket();}/*** 重写KeyListener中的3个方法,实现Enter键发送* @param e*/@Overridepublic void keyPressed(KeyEvent e) {//回车键if (e.getKeyCode()== KeyEvent.VK_ENTER){//发送数据到socket通道sendDataToSocket();}}@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyReleased(KeyEvent e) {}//方法功能:发送数据到客户端,并将内容回显到自己的文本域public void sendDataToSocket(){//1.获取文本框中的内容String text = jtf.getText();//2.拼接需要发送的数据内容text = "服务端对客户端说:"+text;//3.自己也需要显示jta.append(text+System.lineSeparator());try {//4.发送bw.write(text);bw.newLine();bw.flush();//5.清空文本框jtf.setText("");} catch (Exception exception) {exception.printStackTrace();}}
}

客户端代码:

package cn.qy.chat;import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.net.Socket;
import java.util.Properties;//说明:如果一个类,需要有界面的显示,那么该类就需要继承自JFrame,此时,该类就可以被称为一个“窗体类
//1.定义JFrame窗体中的组件
//2.在构造方法中初始化组件
public class ClientChatMain extends JFrame implements ActionListener, KeyListener {public static void main(String[] args) {// 调用构造器new ClientChatMain();}//属性//文本域private JTextArea jta;//滚动条private JScrollPane jsp;//面板private JPanel jp;//文本框private JTextField jtf;//按钮private JButton jb;//流BufferedReader br;BufferedWriter bw;//通信的IP和Portprivate static int clientPort;private static String clientIP;//静态代码块加载外部配置文件//特点1:在类加载时,自动执行//特点2:一个类只会加载一次,因此静态代码块只会执行一次static {Properties prop = new Properties();try {prop.load(new FileReader("chat.properties"));clientPort = Integer.parseInt(prop.getProperty("clientPort"));clientIP = prop.getProperty("clientIP");} catch (IOException e) {e.printStackTrace();}}//创建构造器public ClientChatMain(){//初始化组件//初始化文本域jta = new JTextArea();//设置文本域不可编辑jta.setEditable(false);//将文本域添加到滚动条中,实现滚动效果jsp = new JScrollPane(jta);//面板jp = new JPanel();jtf = new JTextField(15);jb = new JButton("发送");//将文本框与按钮添加到面板中jp.add(jtf);jp.add(jb);//将滚动条与面板全部添加到窗体中this.add(jsp, BorderLayout.CENTER);this.add(jp, BorderLayout.SOUTH);//设置 标题 大小,位置,关闭,是否可见this.setTitle("QQ 客户端");this.setSize(300,300);this.setLocation(300,300);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭,程序退出this.setVisible(true);/******************TCP 客户端 start*****************///给发送按钮绑定一个监听点击事件jb.addActionListener(this);//给键盘绑定单击事件jtf.addKeyListener(this);//接受服务端数据,并回显到自己的文本域try {//1.创建一个客户端的套接字socketSocket socket = new Socket(clientIP, clientPort);//2.获取socket 通道的输入流br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//3.获取socket 通道的输出流bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));//循环读取数据,并把它拼接到文本域中String line =null;while ((line=br.readLine())!=null){jta.append(line+System.lineSeparator());}//4.关闭socket 通道socket.close();} catch (Exception e) {e.printStackTrace();}/******************TCP 客户端 end*****************/}//行为/*** 重新ActionListener中的1个方法,实现点击 发送键 发送* @param e*/@Overridepublic void actionPerformed(ActionEvent e) {sendDataToSocket();}/*** 重写KeyListener中的3个方法,实现Enter键发送* @param e*/@Overridepublic void keyPressed(KeyEvent e) {if (e.getKeyCode()==KeyEvent.VK_ENTER){sendDataToSocket();}}@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyReleased(KeyEvent e) {}//方法功能:发送数据到服务端,并将内容回显到自己的文本域private void sendDataToSocket(){//1.获取文本框中的内容String text = jtf.getText();//2.拼接需要发送的数据内容text = "客户端对服务端说:"+text;//3.自己也需要显示jta.append(text+System.lineSeparator());try {//4.发送bw.write(text);bw.newLine();bw.flush();//5.清空文本框jtf.setText("");} catch (Exception exception) {exception.printStackTrace();}}
}

 启动时,必须先启动服务端,再启动客户端。

最终效果:

 

 

 


http://chatgpt.dhexx.cn/article/EnhQCjpF.shtml

相关文章

微信小程序购物车功能实现(干货满满)

微信小程序定制好看的购物车页面,实现购物车功能,希望对您有所帮助! 1. 应用场景 2. 思路分析 3. 代码分析 4. 具体实现代码 效果截图: 1.应用场景 适用于商城、秒杀、商品购买等类型的小程序,负责将顾客浏览的商…

微信小程序微商城(八):缓存实现商品购物车功能

IT实战联盟博客:http://blog.100boot.cn 上一篇:微信小程序微商城(七):动态API实现商品分类 看效果 购物车.gif 开发计划 1、商品详情页将商品信息放入缓存 2、购物车页面读取缓存获取商品信息 3、购物车商品计算…

微信小程序开发一个小型商城(六、购物车页面)

上一篇文章:微信小程序开发一个小型商城(五、商品详情) 当我们在商品详情界面中点击添加购物后,会跳转到购物车界面,购物车界面是一个tabbar,在跳转的时候需要加上ope-type。看下购物车的静态页面把&#x…

微信小程序实现一个购物车页面的简易列表效果

本文只是简单的模仿天猫APP的购物车列表的样式效果&#xff0c;并实现了部分事件功能&#xff0c;功能并不完善&#xff0c;请降低期待观看。 天猫APP的购物车效果&#xff1a; 小程序模仿的实现效果&#xff1a; wxml部分的代码&#xff1a; <view wx:if"{{!isCartEmp…

【Python之pymysql库学习】一、分析fetchone()、fetchmany()、fetchall()(保姆级图文+实现代码)

目录 实现效果实现思路实现代码总结 欢迎关注 『Python之pymysql库学习』 系列&#xff0c;持续更新中 欢迎关注 『Python之pymysql库学习』 系列&#xff0c;持续更新中 实现效果 实现思路 其实有半数代码是创建数据库和创建数据表并插入数据这些环境配置部分我都写好了&…

fetchone、fetchall

fetchone(): 该方法获取下一个查询结果集。结果集是一个对象,读取一行结果&#xff0c;读取完指向下一行&#xff0c;到空为止 fetchall():接收全部的返回结果行&#xff0c;到空为止 fetchone() &#xff1a; 返回单个的元组&#xff0c;也就是一条记录(row)&#xff0c;如果没…

python fetchall方法_Python连接MySQL并使用fetchall()方法过滤特殊字符

python3.3从mysql里取出的数据莫名其妙有括号和逗号每天跟自己喜欢的人一起&#xff0c;通电话&#xff0c;旅行&#xff0c;重复一个承诺和梦想&#xff0c;听他第二十八次提起童年往事&#xff0c;每年的同一天和他庆祝生日&#xff0c;每年的情人节圣诞节除夕&#xff0c;也…

pdo fetchAll

作用 fetchAll()方法是获取结果集中的所有行.其返回值是一个包含结果集中所有数据的二维数组。 PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument[, array$ctor_args array() ]]] ) fetch_style:控制结果的返回方式 PDO::FETCH_ASSOC 关联数组形式 PD…

记录一个常用函数fetchall()的使用过程

fetchall() 作用是返回多个元组&#xff0c;即对应数据库里的多条数据概念&#xff1b; 常见用法是 cursor.execute(‘select * from table’) value cursor.fetchall() 此时&#xff0c;print(value)则会输出以下二维元组&#xff0c;如下图 拓展&#xff1a; 同类函数fet…

Python从Oracle数据库中获取数据——fetchall(),fetchone(),fetchmany()函数功能分析

Python从Oracle数据库中获取数据——fetchall(),fetchone(),fetchmany()函数功能分析 一、fetchall()&#xff0c;fetchone()&#xff0c;fetchmany()简单介绍 1、fetchall()函数,它的返回值是多个元组,即返回多个行记录,如果没有结果,返回的是() 2、fetchone()函数,它的返回…

KITTI数据集可视化(一):点云多种视图的可视化实现

如有错误&#xff0c;恳请指出。 在本地上&#xff0c;可以安装一些软件&#xff0c;比如&#xff1a;Meshlab&#xff0c;CloudCompare等3D查看工具来对点云进行可视化。而这篇博客是将介绍一些代码工具将KITTI数据集进行可视化操作&#xff0c;包括点云鸟瞰图&#xff0c;FOV…

KITTI数据集的点云格式转PCD格式

参考文章&#xff1a;https://blog.csdn.net/xinguihu/article/details/78922005 KITTI数据集应该不用多做介绍了&#xff0c;基本上做自动驾驶的都知道这个东西。最近本人用到这个数据集想看看里面的点云长什么模样&#xff0c;却发现有点别扭&#xff0c;没有直接可以看的工…

使用kitti数据集实现自动驾驶——发布照片、点云、IMU、GPS、显示2D和3D侦测框

本次内容主要是使用kitti数据集来可视化kitti车上一些传感器&#xff08;相机、激光雷达、IMU&#xff09;采集的资料以及对行人和车辆进行检测并在图像中画出行人和车辆的2D框、在点云中画出行人和车辆的3D框。 首先先看看最终实现的效果&#xff1a; 自动驾驶视频 看了上面的…

KITTI数据集-label解析笔记

笔记摘自&#xff1a;KITTI数据集--label解析与传感器间坐标转换参数解析_苏源流的博客-CSDN博客 KITTI数据集是自动驾驶领域最知名的数据集之一。 一、kitti数据集&#xff0c;label解析 16个数代表的含义&#xff1a; 第1个字符串&#xff1a;代表目标的类别 Car, Van, Tru…

16个车辆信息检测数据集收集汇总(简介及链接)

16个车辆信息检测数据集收集汇总&#xff08;简介及链接) 转载自&#xff1a;https://blog.csdn.net/u014546828/article/details/109089621?utm_mediumdistribute.pc_relevant.none-task-blog-baidujs_baidulandingword-1&spm1001.2101.3001.4242 目录 1. UA-DETRAC …

双目网络公开数据集的特性

文章目录 概述SceneFlowKITTI 2012 & 2015ETH3D 2017Middlebury 2014 概述 参考文章&#xff1a;Rethinking Training Strategy in Stereo Matching 主流双目公开数据集有&#xff1a;SceneFlow、KITTI、ETH3D、MB。 各个双目网络主流训练数据视差分布的直方图&#xff1a;…

KITTI数据集下载及介绍

KITTI数据集下载及介绍 KITTI数据集由德国卡尔斯鲁厄理工学院和丰田美国技术研究院联合创办&#xff0c;是目前国际上最大的自动驾驶场景下的计算机视觉算法评测数据集。该数据集用于评测立体图像(stereo)&#xff0c;光流(optical flow)&#xff0c;视觉测距(visual odometry…

KITTI 数据集--下载链接

Visual Odometry / SLAM Evaluation 2012 数据集主页&#xff1a;The KITTI Vision Benchmark Suite (cvlibs.net) 里程计基准由22个立体序列组成&#xff0c;以无损失png格式保存。 11个具有真实轨迹的序列&#xff08;00-10&#xff09;用于训练&#xff0c;11个没有真实…

KITTI数据集下载及解析

KITTI数据集下载及解析 W.P. Xiao, Vision group&#xff0c;SHUSV 版本更新时间更新内容作者1V 1.02020.01.09完成主体内容W.P. Xiao2 文章目录 KITTI Dataset1 简介1.1 数据采集平台1.2 坐标系 2 数据解析2.1 image文件2.2 velodyne文件2.3 calib文件2.4 label文件 3 KITTI可…

无人驾驶之KITTI数据集介绍与应用(一)——数据组织方式介绍

本系列博客旨在介绍无人驾驶领域中颇负盛名的KITTI公开数据集&#xff0c;首先整体介绍该数据集的由来、数据组织方式、官方开发工具的使用&#xff0c;重点详细介绍其中对于Object、Tracking和raw data的数据使用&#xff0c;主要分享了我在使用这些数据集时开发的一些工具&am…