java小程序---简陋版多人聊天室
功能需求:
1 每运行一次主函数,创建一个客户端聊天界面;
2 客户端界面分三块,公屏(显示所有客户端发送的信息),私屏(用于输入个人想要发送的信息),发送按钮(点击一次,将客户端信息发送到服务端)
3 进入客户端时公屏提示 欢迎xxx来到多人聊天室,关闭客户端时提示 xxx已离开聊天室
4 客户端展示在文末,源文件地址也在文末,可以直接转尾部
============================================================================
所需知识:
1 IO流基础知识,用于读写发送的信息
2 Jframe jpane,用于创建图形界面
3 socket基础知识,用于创建客户端,服务端,互相传递信息
4 线程基础知识
5 计时器基础知识
======================================================================
主要思路:
1 创建客户端界面,
2 在界面中创建客户端,每点击一次,就发送信息到服务端
3 服务端一直开启,持续接受客户端信息.然后将接受到的信息发送到所有客户端
4 客户端将服务器发送的信息显示在公屏
===========================================================================
代码如下:
第一步:画客户端外边框
/**
* @Title: chatJFrame.java
* @Package view
* @Description:
* @author Mr.Yao
* @date 2019年8月28日下午4:53:47
* @version V1.0
*/
package chatview; import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.Scanner; import javax.swing.JFrame; /**
* @ClassName: chatJFrame
* @Description: 继承JFrame,画聊天界面外边框
* @author Mr.Yao
* @date 2019年8月28日下午4:53:47
*
*/
public class ChatJFrame extends JFrame {
//重写构造方法
public ChatJFrame() {
//输出让用户输入用户名,作为之后客户端的名字
System.out.println("请输入用户名");
Scanner input=new Scanner(System.in);
String name=input.next();
//设置聊天室的名称
this.setTitle(name);
//获取屏幕
Toolkit dt = Toolkit.getDefaultToolkit();
Dimension ss = dt.getScreenSize();
//获取屏幕宽高
int width = (int)ss.getWidth();
int height = (int)ss.getHeight();
//设置居中和宽高
this.setBounds((width - 500) /2,(height - 500)/2,500,500);
//添加chatJPanl对象,添加画布,并传入姓名
this.add(new ChatJPanel(name));
//设置禁止窗口缩放
this.setResizable(false);
//当关闭窗口时关闭JVm,
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
//设置可见
this.setVisible(true); } }
=====================================================================
第二步 创建画布,并建立客户端
如何做到点击send按钮发送信息-?---------->建按钮点击事件,点击一次就获取当前文本输入框的信息,并用write()方法写出到服务端
如何做到持续接受服务端发来的信息?----------->利用计时器,每0.5s执行一次,如果服务端有发送信息,则将其显示到公屏中
/**
* @Title: chatJPane.java
* @Package view
* @Description:
* @author Mr.Yao
* @date 2019年8月28日下午4:54:05
* @version V1.0
*/
package chatview; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Timer;
import java.util.TimerTask; import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextArea; /**
* @ClassName: chatJPane
* @Description: 继承JPanl类,用于画图形中三块区域,并建立客户端发送信息和接受信息的功能
* @author Mr.Yao
* @date 2019年8月28日下午4:54:05
*
*/
public class ChatJPanel extends JPanel{
//声明姓名字符串,用于接收chatJFrame传过来的用户姓名
public String name; //添加文本域,作为聊天信息公屏框
public JTextArea screen;
//添加文本域,作为用户信息输入框
public JTextArea input;
//添加发送按钮,点击按钮,将输入框信息发送出去
public JButton send; //申明客户端
public Socket socket;
//申明客户端输出,输入流
OutputStream os;
InputStream is; //无参构造方法
public ChatJPanel() {} //有参构造
public ChatJPanel(String name) {
//接收用户姓名
this.name=name;
//取消流式布局
this.setLayout(null); //创建公屏并设置宽高
screen=new JTextArea();
screen.setBounds(20, 20, 450, 280);
this.add(screen); //创建输入框并设置宽高
input=new JTextArea();
input.setBounds(20,320,300,120);
this.add(input); //创建按钮,并设置宽高
//按钮对象
send = new JButton();
send.setBounds(340, 320, 100, 120);
send.setText("SEND");
this.add(send); //新建客户端对象,并设置ip地址和端口号
try {
socket=new Socket("127.0.0.01",12321);
//获取客户端输入 输出流
os=socket.getOutputStream();
is=socket.getInputStream();
//输出欢迎xxx来到聊天室
String s="欢迎"+name+"来到聊天室!!!!";
os.write(s.getBytes());
os.flush();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} /*给按钮添加点击功能,点击按钮时将输入框信息发送到服务端*/
send.addActionListener(new ActionListener() { @Override
//重写方法
public void actionPerformed(ActionEvent e) {
//获取输入框当前的内容,并加上用户姓名
String text = name+"说:"+input.getText();
//将输入框输出到服务端
try {
//写出数据
os.write(text.getBytes());
//刷新
os.flush();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//清空输入框
input.setText("");
}
});
//创建计时器,每500毫秒启动一次,接受服务端发出来的信息
new Timer().schedule(new TimerTask() { @Override
//重写方法,接受服务端的信息
public void run() {
// TODO Auto-generated method stub
//定义字符串,接受服务器返回的信息
String text="";
try {
//创建byte数组,保存服务器返回的字节信息
byte[] b=new byte[1024];
//定义变量记录读取的字节数
int len=-1;
//读取服务器返回字节
len=is.read(b);
//转换为字符
text=new String(b,0,len); } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(text!="") {
//添加到屏幕
screen.append(text+"\n");
}
}
},500,500);
}
}
===========================================================================
第三步 创建服务端
如何做到服务持续接受不同客户端信息并发送到所有客户端?-------> 服务一直开启,利用死循环 while()不停接受客户端soket,每接受一个就添加到一个集合中,并创建一个线程.线程的内容是遍历集合,将服务端接受的信息发送到所有客户端
创建集合,用于保存服务端接受到的socket
/**
* @Title: ServerList.java
* @Package chatserver
* @Description:
* @author Mr.Yao
* @date 2019年8月28日下午7:56:41
* @version V1.0
*/
package chatserver; import java.net.Socket;
import java.util.ArrayList; /**
* @ClassName: ServerList
* @Description: 创建集合,保存每个客户端的socket
* @author Mr.Yao
* @date 2019年8月28日下午7:56:41
*
*/
public class ServerList {
//创建集合
public static ArrayList<Socket> list=new ArrayList<Socket>();
}
server类用于接受客户端并开启线程,还需建立一个线程类,并重写run方法,重写后的run方法用于遍历集合并将信息输出到所有客户端
/**
* @Title: Server.java
* @Package chatserver
* @Description:
* @author Mr.Yao
* @date 2019年8月28日下午7:53:37
* @version V1.0
*/
package chatserver; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
* @ClassName: Server
* @Description: 创建服务器,持续接受客户端信息
* @author Mr.Yao
* @date 2019年8月28日下午7:53:37
*
*/
public class Server {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建服务器
ServerSocket ss = null;
try {
ss=new ServerSocket(12321);
//循环接受客户端
while(true) {
Socket socket = ss.accept();
//将socket添加到数组
ServerList.list.add(socket);
//创建匿名线程并启动
new Thread(new ServerThread(socket)).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
ServerThread类实现了runnable接口,重写run方法
/**
* @Title: ServerThread.java
* @Package chatserver
* @Description:
* @author Mr.Yao
* @date 2019年8月29日上午11:58:47
* @version V1.0
*/
package chatserver; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket; /**
* @ClassName: ServerThread
* @Description: 创建线程类,用于循环接受客户端的信息和将信息发送到所有的客户端
* @author Mr.Yao
* @date 2019年8月29日上午11:58:47
*
*/
public class ServerThread implements Runnable {
//声明变量,接受用户客户端名称,用于输出XXX下线了
public String name=null;
//声明socket对象
public Socket socket;
//无参构造
public ServerThread() {}
//传参构造
public ServerThread(Socket socket) {
this.socket=socket;
} //重写run方法
@Override
public void run() {
// TODO Auto-generated method stub
//创建输入流
try {
InputStream is=socket.getInputStream();
//持续接受客户端信息
while(true) {
//接受客户端信息
byte[] b=new byte[1024];
int len=-1;
len=is.read(b);
//获取客户名称,从第一句 欢迎xxx来到客户端中截取出名称
String string=new String(b,0,len);
if(string.contains("欢迎")&&name==null) {
//截取名称
name=string.substring(2,string.indexOf("来"));
}
//将该信息发送到每个客户端
for(Socket socket:ServerList.list) {
//创建输出流
OutputStream os=socket.getOutputStream();
//输出信息
os.write(b, 0, len);
//刷新
os.flush();
}
}
}catch (IOException e) {
// TODO: handle exception
//出现异常,说明该客户端已关闭,向其他在线客户端发送信息:xxx下线了
// e.printStackTrace();
//将集合中的已关闭的socket对象删除,
ServerList.list.remove(this.socket);
//循环输出信息
for(Socket socket:ServerList.list) {
//创建输出流
try {
OutputStream os = socket.getOutputStream();
//输出信息
os.write((name+"下线了").getBytes());
//刷新
os.flush();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
}
第四步 创建启动类,写主函数
/**
* @Title: ChatStart.java
* @Package chatstart
* @Description:
* @author Mr.Yao
* @date 2019年8月28日下午7:51:14
* @version V1.0
*/
package chatstart; import chatview.ChatJFrame; /**
* @ClassName: ChatStart
* @Description: 主方法,程序入口
* @author Mr.Yao
* @date 2019年8月28日下午7:51:14
*
*/
public class ChatStart {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建jf边框对象
ChatJFrame jf=new ChatJFrame();
} }
==============================================================================================
运行效果展示:
---->需要先运行server,开启服务端.然后运行主函数,每运行一次,就会创建一个客户端

-----源文件目录结构:

源码:
链接:https://pan.baidu.com/s/18aPqsoJsP4ZZYf6ZkWzU-g
提取码:exva
java小程序---简陋版多人聊天室的更多相关文章
- Java版多人聊天室
server.java import java.io.*; import java.net.*; import java.text.SimpleDateFormat; import java.util ...
- [JAVA小项目]GUI界面的局域网聊天室
思路: 1.服务端: 1.1 创建ServerSocket 监听本地端口 1.2 循环接收多个客户端的连接,并且把多个客户端连接的每个管道都为其创建线程. 服务端类的成员:链表--每个成员都是线程类- ...
- 多人聊天室(Java)
第1部分 TCP和UDP TCP:是一种可靠地传输协议,是把消息按一个个小包传递并确认消息接收成功和正确才发送下一个包,速度相对于UDP慢,但是信息准确安全:常用于一般不要求速度和需要准确发送消息的场 ...
- 输出多行字符的一个简单JAVA小程序
public class JAVA { public static void main(String[] args) { System.out.println("-------------- ...
- 浏览器兼容java小程序配置说明
最近在使用的一个web应用系统是内嵌了java小程序,遇到了各种浏览器兼容性问题,现梳理如下: 1.通过以下链接检测当前电脑是否已经安装有java https://java.com/zh_CN/dow ...
- java socket之多人聊天室Demo
一.功能介绍 该功能实现了一个类似QQ的最简单多人聊天室,如下图所示. 二.目录结构 三.服务端 1)SocketServer类,该类是服务端的主类,主要负责创建聊天窗口,创建监听客户端的线程: pa ...
- 微信小程序横版日历,tab栏
代码地址如下:http://www.demodashi.com/demo/14243.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...
- 框架一般用作Java应用程序的窗口,而Applet是Java小程序的窗口
框架一般用作Java应用程序的窗口,而Applet是Java小程序的窗口. 与Frame不同,Applet是在网页中显示的,也可以通过添加Panel进行组件布局. package TomAwt; im ...
- 微慕WordPress小程序增强版
2017年1月9日,张小龙在2017微信公开课Pro上发布的微信小程序正式上线.在过去的2年多的时间里,微信小程序领头,各大互联网平台也不甘落后,陆续推出自己的小程序.2018年7月4日,百度智能小程 ...
随机推荐
- idea中Entity实体中报错:cannot resolve column/table/...解决办法。
idea中Entity实体中报错:cannot resolve column/table/...解决办法. 若idea中Entity实体中报错: cannot resolve column.... c ...
- SQL Server强制释放内存
--强制释放内存 CREATE procedure [dbo].ClearMemory as begin --清除所有缓存 DBCC DROPCLEANBUFFERS --打开高级配置 EXEC (' ...
- 【微信小程序】抽象组件使用示例
1.配置页面路径 ./app.json { "pages":[ "pages/index/index", "pages/logs/logs&q ...
- Android Xutils3 完全解析
1.先来认识一下xUtils3 1)xUtils3简介 xUtils是基于Afinal开发的目前功能比较完善的一个Android开源框架,最近又发布了xUtil3.0,在增加新功能的同时又提高了框架的 ...
- Linux的yum管理
前面介绍了软件的管理的方式rpm.但有个缺点,rpm不能解决依赖. 下面介绍的yum软件管理.可以完美的解决这个问题. 使用yum的方式管理rpm软件 优势:自动解决软件的依赖关系 ...
- nginx日志设置
环境:nginx1.16.1 (1)日志类型:access_log(访问日志) error_log(错误日志)rewrite_log 访问日志:通过访问日志我们可以得到用户的IP地址.浏览器的信息,请 ...
- Mysql数据库之慢查询
一.简介 开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能. 二.参数说明 slow_query_log 慢查询开启状态 slow_ ...
- ASS/SSA字幕格式
[时间:2019-04] [状态:Open] [关键词:字幕,ASS,SSA,文件格式,v4 Styles,字幕特效] 0 引言 SubStation Alpha(Sub Station Alpha) ...
- 20180610模拟赛T1——脱离地牢
Description 在一个神秘的国度里,年轻的王子Paris与美丽的公主Helen在一起过着幸福的生活.他们都随身带有一块带磁性的阴阳魔法石,身居地狱的魔王Satan早就想着得到这两块石头了,只要 ...
- selenium 滚动条的滚动
如果是一个页面自带的滚动条(即网页的的滚动条) 可直接用js js="window.scrollTo(x,y);" x(横向),y(纵向)代表的就是位置 ,具体移动到哪里 ...