java实现的聊天程序
//利用GUI和网络编程知识,建立一个简单的聊天程序。package cn.itcast.udp.exercise;import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;public class GUI_Chat extends Frame {private static final long serialVersionUID = 1L;private Button sendButton;private Button clearButton;private Button logButton;private Button shakeButton;private TextField textField;private TextArea viewTextArea;private TextArea sendTextArea;private DatagramSocket socket;private BufferedWriter writer;/** 构造函数* 初始化* 生成2个Panel, 以及界面组件* 处理事件* 显示窗体* 启动接收消息的线程 */public GUI_Chat() {init(); // 设置标题, 大小, 位置, 处理关闭事件generateSouthPanel(); // 生成那边的Panel, 包含TextField和4个ButtongenerateCenterPanel(); // 生成中间的Panel, 包含2个TextAreahandleChatEvent(); // 各种事件的处理setVisible(true); // 显示new ReceiveThread().start(); // 开启接收消息的线程}/** 初始化* 设置标题, 大小, 位置* 创建Socket和Writer*/private void init() {setTitle("GUI聊天室");setSize(400, 600);setLocation(600, 50);try {socket = new DatagramSocket();writer = new BufferedWriter(new FileWriter("msg.txt", true));} catch (Exception e) {e.printStackTrace();}}/** 创建南边的Panel* 其中包含用来输入IP的TextField和4个Button*/private void generateSouthPanel() {textField = new TextField(20);sendButton = new Button("发送");clearButton = new Button("清屏");logButton = new Button("记录");shakeButton = new Button("震动");Panel southPanel = new Panel(); // 用来布局的Panel, 默认流式布局. 文本框和按钮都放在Panel中southPanel.add(textField); southPanel.add(sendButton);southPanel.add(clearButton);southPanel.add(logButton);southPanel.add(shakeButton);add(southPanel, BorderLayout.SOUTH); // Panel放在Frame的南边textField.setText("127.0.0.1");}/** 创建中间的Panel* 其中包含2个TextView*/private void generateCenterPanel() {viewTextArea = new TextArea();sendTextArea = new TextArea(5, 1); // 指定行数和列数, 列数由于是边界布局所以无效Panel centerPanel = new Panel(); // 把Panel改为边界布局, 1个TextArea在中间, 另一个在南边centerPanel.setLayout(new BorderLayout()); centerPanel.add(viewTextArea, BorderLayout.CENTER);centerPanel.add(sendTextArea, BorderLayout.SOUTH);add(centerPanel, BorderLayout.CENTER); // Panel放在Frame的中间viewTextArea.setEditable(false); // 用来显示的TextArea不能修改(会修改背景色为灰色)viewTextArea.setBackground(Color.WHITE); // 背景色改回白色}/** 处理各种事件* 窗体关闭* 4个按钮* 发送快捷键*/private void handleChatEvent() {addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {try {socket.close();writer.close();System.exit(0);} catch (IOException e1) {e1.printStackTrace();}}});sendButton.addActionListener(new ActionListener() { // 发送按钮被点击的时候, 执行send()方法public void actionPerformed(ActionEvent e) {send();}});clearButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {viewTextArea.setText("");}});sendTextArea.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER || e.isAltDown() && e.getKeyCode() == KeyEvent.VK_S) {e.consume(); // 取消当前事件send();}}});logButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {showLog();}});shakeButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {sendData(new byte[] { -1 }, textField.getText());}});}/** 把指定的数据发送到指定的IP地址上*/private void sendData(byte[] data, String ip) {try {DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(ip), 6789); // 创建Packetsocket.send(packet);} catch (Exception e) {e.printStackTrace();}}/** 发送消息的方法* 发送之后会在TextView显示* 并且会保存聊天记录*/private void send() {String text = sendTextArea.getText(); // 获取文本框中的文本String ip = textField.getText(); // 获取IP地址ip = ip.trim().length() == 0 ? "255.255.255.255" : ip; // IP为空时, 群发try {String dateStr = getCurrentTime(); // 获取当前时间synchronized(this) { // 为了让发送消息并显示之后才执行接收端的显示, 所以同步sendData(text.getBytes(), ip);String msg = dateStr + " 我对 " + (ip.equals("255.255.255.255") ? "所有人" : ip) + " 说:\r\n" + text + "\r\n\r\n";viewTextArea.append(msg); // 在TextArea中显示发送的消息writer.write(msg); // 保存聊天记录}sendTextArea.setText(""); // 清空TextArea} catch (Exception e) {e.printStackTrace();}}/** 获取当前时间*/private String getCurrentTime() {Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return sdf.format(date);}/** 用来接收数据的线程* 不停地接收数据, 显示到TextView, 并且保存聊天记录*/private class ReceiveThread extends Thread { public void run() {try {DatagramSocket socket = new DatagramSocket(6789); // 接收端SocketDatagramPacket packet = new DatagramPacket(new byte[1024000], 1024000); // 接收端Packetwhile (true) { // 循环接收socket.receive(packet); // 收到数据byte[] data = packet.getData(); // 获取数据int len = packet.getLength(); // 获取长度if (len == 1 && data[0] == -1) { // 收到特殊的消息, 震动shake();continue;}String ip = packet.getAddress().getHostAddress(); // 获取IPString text = new String(data, 0, len); // 把收到的数据转为StringString timeStr = getCurrentTime(); // 获取当前时间synchronized(GUI_Chat.this) { // 为了确保在发送端显示之后再显示, 所以同步String msg = timeStr + " " + ip + " 对我说:\r\n" + text + "\r\n\r\n";viewTextArea.append(msg); // 把收到的数据显示writer.write(msg); // 保存聊天记录}}} catch (Exception e) {e.printStackTrace();}}}/** 震动*/private void shake() {int x = getLocation().x; // 获取当前位置int y = getLocation().y;try {setLocation(x + 20, y + 20);Thread.sleep(20);setLocation(x - 20, y - 20);Thread.sleep(20);setLocation(x - 20, y + 20);Thread.sleep(20);setLocation(x + 20, y - 20);Thread.sleep(20);setLocation(x, y);} catch (InterruptedException e) {e.printStackTrace();}}/** 显示聊天记录* 从文件中读取数据, 显示到TextView*/private void showLog() {try {viewTextArea.setText(""); // 清空viewTextAreawriter.flush(); // 刷出缓冲区中数据FileInputStream fis = new FileInputStream("msg.txt"); ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len;while ((len = fis.read(buffer)) != -1) // 从文件读取数据到内存baos.write(buffer, 0, len);fis.close();baos.close();String log = new String(baos.toByteArray()); // 把内存中数据转为StringviewTextArea.setText(log); // 显示到viewTextArea} catch (IOException e) {e.printStackTrace();}}/** 测试方法, 创建聊天室对象*/public static void main(String[] args) {new GUI_Chat(); }
}
java实现的聊天程序相关推荐
- 利用java编写网络聊天程序并加密信息
利用java编写网络聊天程序并加密信息 优化了代码后的地址:https://blog.csdn.net/qq_43483251/article/details/125470514?spm=1001.2 ...
- 设计一个聊天窗口java代码,Java 设计的聊天程序-完整代码
[实例简介] 这是一个Java 课程设计,模仿MSN.QQ等的界面.压缩包内有源码跟使用方法! [实例截图] [核心代码] Java设计的聊天程序-完整源码 └── Java 设计的聊天程序-完整源码 ...
- java多客户端聊天程序,java – 多客户端聊天程序,向所有客户端广播聊天?
我正在尝试制作一个可以容纳多个客户端的非常简单的聊天程序.我有一个多线程服务器,可以连接多个客户端,但服务器只与单个客户端通信(因为它应该,每个客户端都在自己的线程上)我需要帮助让服务器发送来自所有连 ...
- Java使用UDP聊天程序
主要想测试Java UDP通信.Java UDP使用DatagramSocket和DatagramPacket完成UDP通信 主要思路: 1.本机通信,ip地址为:127.0.0.1 2.开一个线程监 ...
- java udp简单聊天程序_Java基于UDP协议实现简单的聊天室程序
最近比较闲,一直在抽空回顾一些java方面的技术应用. 今天没什么事做,基于udp协议,写了一个非常简单的聊天室程序. 现在的工作,很少用到socket,也算是对java网络编程方面的一个简单回忆. ...
- java c s聊天程序_Java建立C/S 模式聊天室服务器和客户端
时间:2018-12-01 概述:聊天室 服务器 客户端 在网络上经常进各种聊天室,本例通过编程实现了C/S 模式的聊天室服务器和客户端.实现方法:ChatServer 类实现了一个聊天室服务器端, ...
- 用java编写一个聊天程序_基于JAVA实现的一个简单的网络聊天程序
一.Java Socket的概述 1.Socket套接字方便了开发网络应用程序.TCP面向连接的可靠传输协议.具有数据确认和数据重传机制.保证了发送数据一定能到达通信的对方.UPD协议无连接,不可靠的 ...
- Java丨即时聊天程序的实现
继续昨天的代码丨多客户端通信实现 想要建立多客户端即时通信,必须具有这几个条件(类): 1.客户端: 2.服务器: 3.消息类(数据封包): 4.消息类型. Demo; package Task.de ...
- Java实现网络聊天程序的设计与实现(基于UDP协议)
目录 TCP/IP协议介绍 Java中socket编程 测试结果 TCP/IP协议介绍 TCP/IP协议包含的范围非常的广,它是一种四层 ...
最新文章
- C#3.0-新增加功能浅析(1)
- 整了个程序员专用的红包封面,喜欢的来领咯!
- 黑马程序员Linux系统开发视频之mmap使用注意事项
- windows cmd post请求_cmd命令集合
- SVN专题(Visual SVN Server + TortoiseSVN + Visual SVN)
- 客户端网络pomelo学习笔记 (3) node.js 与 c 客户端 Diffie-Hellman 密钥交换算法的实现客户端网络...
- Android单元测试(五):依赖注入,将mock方便的用起来
- 利用python更改图片格式和分辨率
- 微信小程序打包超过2M 解决方法
- php网页地图上自定义,如何添加在线自定义地图
- 【通識:人生哲學與幸福】青年心理學 Part2 成熟
- python打开文件,路径存在'\t'被转义
- Havel算法-Python实现
- 添加Adobe PDF 打印机
- 417. 太平洋大西洋水流问题(medium) -力扣(leetCode)逆流而上,JS图的深度优先遍历算法
- 天源财富:“中国天眼”发现201颗新脉冲星
- “RSoft光电器件设计仿真技术与应用”专题培训通知
- Oralcle中特殊字符的处理
- ubuntu18.04合并pdf文件
- 织梦全站自动关键词内链插件可指定关键词批量插入内链
热门文章
- Unity 大面积草风吹动效果+受人物影响
- YoMail 隐藏小功能之怎样在yomail里使用石墨文档?
- ionic组件-Slides轮播图
- windows技巧--win7修改锁屏壁纸(不用软件)
- Android 插件开发实现
- python打包成exe其他电脑运行不了_将python文件打包成exe程序,复制到每台电脑都可以运行-exe是什么文件...
- 一次变天之后的踏春之旅
- Jinja2安装与基本API用法
- html如何设置网页的背景图片,使放大或缩小浏览器时,页面排版和背景可以随浏览器放大缩小而排版不会改变,
- 全民程序员时代来了吗?解锁低代码流行背后的秘密