使用 Java 创建聊天客户端-2
1.项目截图

java聊天核心代码:
MyJavaChatClient
====================================================================================================================================
ChatManager.java
package com.nantian.javachatclient.main;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import com.nantian.javachatclient.view.MainWindow;
public class ChatManager {
//界面中只能向chatManager发送数据,那么接收到数据后怎样放到界面上呢?
//需要对MainWindow有个引用,并为它实现setWindow方法
MainWindow window;
//创建本地socket对象
Socket socket;
//声明ip
String IP;
//输入流
BufferedReader reader;
//输出流
PrintWriter writer;
public void setWindow(MainWindow window) {
this.window=window;
//传递之后
window.appendText("文本框已经和ChatManager绑定了!");
}
//将类单例化的步骤就是讲他的构造方法变成private
//ChatManager就会有唯一的实例
private ChatManager() {}
private static final ChatManager instance=new ChatManager();
public static ChatManager getChatManager() {
return instance;
}
//具体实现连接服务器的操作
public void connect(String ip) {
this.IP=ip;
//呼叫连接的时候需要创建新的线程
new Thread() {
//覆盖thread的run方法
@Override
public void run() {
//核心内容处理方法
try {
socket=new Socket(IP,12345);
//将OutPutStream包装成OutPutStreamWriter,然后再包装成PrintWriter
writer=new PrintWriter(
new OutputStreamWriter(
socket.getOutputStream()));
//读取的输入流
reader=new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
//循环监听当前输入流是否有数据
//本地创建字符串
String line;
//首先让line读取一行数据
while((line=reader.readLine())!=null) {
//输出到界面当中
window.appendText("收到:"+line);
}
//关闭流
writer.close();
reader.close();
//关闭流之后赋值为空
writer=null;
reader=null;
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
//"发送"按钮发送内容函数
public void send(String out) {
//点击"发送"按钮,需要首先判断writer是否为空,不为空继续
if (writer!=null) {
//服务器没有提示在控制台输出内容,这是因为没有添加\n,这时flush才可以将这行内容输出
writer.write(out+"\n");
//强制刷新输出
writer.flush();
}else {
window.appendText("当前的连接已经中断!!!");
}
}
}
====================================================================================================================================
StartClient.java
package com.nantian.javachatclient.main;
import java.awt.EventQueue;
import com.nantian.javachatclient.view.MainWindow;
public class StartClient {
/**
* 将窗体主方法放到了这里
* @param args
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow frame = new MainWindow();
frame.setVisible(true);
//创建window的时候,对MainWindow有个引用
ChatManager.getChatManager().setWindow(frame);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
===================================================================================================================================
MainWindow.java
package com.nantian.javachatclient.view;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import com.nantian.javachatclient.main.ChatManager;
import javax.swing.JTextArea;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class MainWindow extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel contentPane;
//文本控件声明到类中,让他作为类的变量
JTextArea txt;
private JTextField IP;
private JTextField send;
/**
* Create the frame.
*/
public MainWindow() {
//因为每次创建客户端会把它压在下面,所以设置如下
setAlwaysOnTop(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
txt = new JTextArea();
txt.setText("Ready...");
IP = new JTextField();
IP.setText("127.0.0.1");
IP.setColumns(10);
JButton button = new JButton("连接到服务器");
button.addMouseListener(new MouseAdapter() {
//mouse-->clicked自动创建的代码
@Override
public void mouseClicked(MouseEvent e) {
//为"连接到服务器"按钮添加动作
//使用函数把它和这个按钮的监听事件绑定起来
ChatManager.getChatManager().connect(IP.getText());
}
});
send = new JTextField();
send.setText("你好!");
send.setColumns(10);
JButton button_1 = new JButton("发送");
button_1.addMouseListener(new MouseAdapter() {
//为"发送"按钮添加动作
@Override
public void mouseClicked(MouseEvent e) {
//当前文本发送呢内容
ChatManager.getChatManager().send(send.getText());
appendText("我说:"+send.getText());
//发送出去后,需要将当前文本框清空
send.setText("");
}
});
GroupLayout gl_contentPane = new GroupLayout(contentPane);
gl_contentPane.setHorizontalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(Alignment.TRAILING, gl_contentPane.createSequentialGroup()
.addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING)
.addComponent(txt, GroupLayout.DEFAULT_SIZE, 414, Short.MAX_VALUE)
.addGroup(Alignment.LEADING, gl_contentPane.createSequentialGroup()
.addComponent(IP)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(button))
.addGroup(gl_contentPane.createSequentialGroup()
.addComponent(send, GroupLayout.DEFAULT_SIZE, 295, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(button_1, GroupLayout.PREFERRED_SIZE, 129, GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
gl_contentPane.setVerticalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
.addComponent(IP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(button))
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(txt, GroupLayout.DEFAULT_SIZE, 193, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
.addComponent(send, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(button_1)))
);
contentPane.setLayout(gl_contentPane);
}
public void appendText(String in) {
txt.append("\n"+in);
}
}
====================================================================================================================================
TestMyServerSocket代码在前面项目
先启动服务端:

后启动客户端:


断开连接:

使用 Java 创建聊天客户端-2的更多相关文章
- 使用 Java 创建聊天客户端-1
1.聊天客户端文本框的搭建. 项目截图:java project 代码: (1).ChatManager.java package com.nantian.javachatclient.main; i ...
- 使用Java建立聊天客户端
---------------siwuxie095 关于 聊天服务器,详见本人博客的分类:来一杯Java, 里面的 使用ServerSocket ...
- 搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 (1)
搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 原文地址(英文):http://www.networkcomms.net/creating ...
- [转载]Java创建WebService服务及客户端实现
Java创建WebService服务及客户端实现 Java创建WebService服务及客户端实现
- Java Socket聊天室编程(二)之利用socket实现单聊聊天室
这篇文章主要介绍了Java Socket聊天室编程(二)之利用socket实现单聊聊天室的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下 在上篇文章Java Socket聊天室编程(一)之 ...
- Java Socket聊天室编程(一)之利用socket实现聊天之消息推送
这篇文章主要介绍了Java Socket聊天室编程(一)之利用socket实现聊天之消息推送的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下 网上已经有很多利用socket实现聊天的例子了 ...
- Spring Kafka整合Spring Boot创建生产者客户端案例
每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 创建一个kafka-producer-master的maven工程.整个项目结构如下: ...
- Java NIO 聊天室实例
最近写了个Java NIO聊天室聊天的程序,NIO学习起来比较困难的,我的代码能给大家起到一个抛砖引玉的作用! 服务端: package test.javanio; /** * @author * @ ...
- Java11新特性 - 标准Java异步HTTP客户端
Java9开始引入的一个处理 HTTP 请求的的 HTTP Client API,该 API 支持同步和异步,而在 Java 11 中已经为正式可用状态,你可以在 java.net 包中找到这个 AP ...
随机推荐
- python内置模块介绍(一)
本文主要介绍模块列表如下: os sys re time datetime random shutil subprocess os模块 os.getcwd() ...
- Python--拦截接口
- vue.js+DRF跨域访问图片
一.背景 在前后端分离过程时,后端服务器只开放本地接口,而前端则开放IP接口,在DRF响应请求时,会把域名(locahost+port)响应给前端服务器,前端服务器把再把数据响应给浏览器,浏览器在解析 ...
- 海量数据处理的 Top K 相关问题
Top-k的最小堆解决方法 问题描述:有N(N>>10000)个整数,求出其中的前K个最大的数.(称作Top k或者Top 10) 问题分析:由于(1)输入的大量数据:(2)只要前K个,对 ...
- JS 客户端(浏览器)存储数据之 localStorage、sessionStorage和indexDB
基本概念 1.localStorage和sessionStorage是HTML5 Web存储的提供的两种存储方式,在IE7以上以及大多数浏览器都是支持的 2.localStorage和sessionS ...
- C# 求余 int a = 371 / 100 % 10,求a的结果为多少?//nt 和int类型计算得到的结果还是int类型
//int 和int类型计算得到的结果还是int类型 eg:int a = 371 / 100 % 10,求a的结果为多少? 首先371除以100,再让此结果除以10求余数. 一 371除以100得到 ...
- vue-resource发送请求
<!DOCTYPE html> <html> <head> <title>vue-resource</title> <meta cha ...
- [LeetCode] 234. 回文链表 ☆(翻转链表)
描述 请判断一个链表是否为回文链表. 示例 1: 输入: 1->2输出: false示例 2: 输入: 1->2->2->1输出: true 进阶:你能否用 O(n) 时间复杂 ...
- python之约束、加密及logging模块
一.什么是约束? 在生活中的约束大概就是有什么原因,导致你不能做这件事情了,称之为约束.而在python中的约束是在当多个类中,都需要使用某些方法时,需要人为抛出异常或使用基类+异常处理来进行约束 c ...
- 解决mybatis实体类和数据库列名不匹配的两种办法
我们在实际开发中,会遇到实体类与数据库类不匹配的情况,在开发中就会产生各种各样的错误,那么我们应该怎么去解决这一类的错误呢?很简单,下面我们介绍两种解决方法: 首先我们看一下数据库和实体类不匹配的情况 ...