Java GUI编程实现在线聊天室
发布时间:2020-05-23 23:11:39 所属栏目:Java 来源:互联网
导读:引言综合应用Java的GUI编程和网络编程,实现一个能够支持多组用户同时使用的聊天室软件。该聊天室具有比较友好的GUI界面,并使用C/S模式,支持多个用户同时使用,用户可以自己选择加入或者创建房间,和房间内的其他
|
引言 综合应用Java的GUI编程和网络编程,实现一个能够支持多组用户同时使用的聊天室软件。该聊天室具有比较友好的GUI界面,并使用C/S模式,支持多个用户同时使用,用户可以自己选择加入或者创建房间,和房间内的其他用户互发信息(文字和图片) 主要功能 客户端的功能主要包括如下的功能:
服务端的功能主要包括:
架构 整个程序采用C/S设计架构,分为一个服务端和多个客户端。服务端开放一个端口给所有开客户端,客户端连接该端口并收发信息,服务端在内部维护客户端的组,并对每一个客户端都用一个子线程来收发信息 基本类的设计 User类
package User;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/**
*
* @author lannooo
*
*/
public class User {
private String name;
private long id;
private long roomId;
private Socket socket;
private BufferedReader br;
private PrintWriter pw;
/**
*
* @param name: 设置user的姓名
* @param id:设置user的id
* @param socket:保存用户连接的socket
* @throws IOException
*/
public User(String name,long id,final Socket socket) throws IOException {
this.name=name;
this.id=id;
this.socket=socket;
this.br=new BufferedReader(new InputStreamReader(
socket.getInputStream()));
this.pw=new PrintWriter(socket.getOutputStream());
}
/**
* 获得该用户的id
* @return id
*/
public long getId() {
return id;
}
/**
* 设置该用户的id
* @param id 新的id
*/
public void setId(long id) {
this.id = id;
}
/**
* 获得用户当前所在的房间号
* @return roomId
*/
public long getRoomId() {
return roomId;
}
/**
* 设置当前用户的所在的房间号
* @param roomId
*/
public void setRoomId(long roomId) {
this.roomId = roomId;
}
/**
* 设置当前用户在聊天室中的昵称
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 返回当前用户在房间中的昵称
* @return
*/
public String getName() {
return name;
}
/**
* 返回当前用户连接的socket实例
* @return
*/
public Socket getSocket() {
return socket;
}
/**
* 设置当前用户连接的socket
* @param socket
*/
public void setSocket(Socket socket) {
this.socket = socket;
}
/**
* 获得该用户的消息读取辅助类BufferedReader实例
* @return
*/
public BufferedReader getBr() {
return br;
}
/**
* 设置 用户的消息读取辅助类
* @param br
*/
public void setBr(BufferedReader br) {
this.br = br;
}
/**
* 获得消息写入类实例
* @return
*/
public PrintWriter getPw() {
return pw;
}
/**
* 设置消息写入类实例
* @param pw
*/
public void setPw(PrintWriter pw) {
this.pw = pw;
}
/**
* 重写了用户类打印的函数
*/
@Override
public String toString() {
return "#User"+id+"#"+name+"[#Room"+roomId+"#]<socket:"+socket+">";
}
}
Room类
package Room;
import java.util.ArrayList;
import java.util.List;
import User.User;
/**
*
* @author lannooo
*
*/
public class Room {
private String name;
private long roomId;
private ArrayList<User> list;
private int totalUsers;
/**
* 获得房间的名字
* @return name
*/
public String getName() {
return name;
}
/**
* 设置房间的新名字
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获得房间的id号
* @return
*/
public long getRoomId() {
return roomId;
}
/**
* 设置房间的id
* @param roomId
*/
public void setRoomId(long roomId) {
this.roomId = roomId;
}
/**
* 向房间中加入一个新用户
* @param user
*/
public void addUser(User user) {
if(!list.contains(user)){
list.add(user);
totalUsers++;
}else{
System.out.println("User is already in Room<"+name+">:"+user);
}
}
/**
* 从房间中删除一个用户
* @param user
* @return 目前该房间中的总用户数目
*/
public int delUser(User user){
if(list.contains(user)){
list.remove(user);
return --totalUsers;
}else{
System.out.println("User is not in Room<"+name+">:"+user);
return totalUsers;
}
}
/**
* 获得当前房间的用户列表
* @return
*/
public ArrayList<User> getUsers(){
return list;
}
/**
* 获得当前房间的用户昵称的列表
* @return
*/
public String[] getUserNames(){
String[] userList = new String[list.size()];
int i=0;
for(User each: list){
userList[i++]=each.getName();
}
return userList;
}
/**
* 使用房间的名称和id来new一个房间
* @param name
* @param roomId
*/
public Room(String name,long roomId) {
this.name=name;
this.roomId=roomId;
this.totalUsers=0;
list = new ArrayList<>();
}
}
RoomList类
package Room;
import java.awt.image.DirectColorModel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import User.User;
/**
*
* @author lannooo
*
*/
public class RoomList {
private HashMap<Long,Room> map;
private long unusedRoomId;
public static long MAX_ROOMS = 9999;
private int totalRooms;
/**
* 未使用的roomid从1算起,起始的房间总数为0
*/
public RoomList(){
map = new HashMap<>();
unusedRoomId = 1;
totalRooms = 0;
}
/**
* 创建一个新的房间,使用未使用的房间号进行创建,如果没有可以使用的则就创建失败
* @param name: 房间的名字
* @return 创建的房间的id
*/
public long createRoom(String name){
if(totalRooms<MAX_ROOMS){
if(name.length()==0){
name = ""+unusedRoomId;
}
Room room = new Room(name,unusedRoomId);
map.put(unusedRoomId,room);
totalRooms++;
return unusedRoomId++;
}else{
return -1;
}
}
/**
* 用户加入一个房间
* @param user
* @param roomID
* @return
*/
public boolean join(User user,long roomID){
if(map.containsKey(roomID)){
map.get(roomID).addUser(user);
return true;
}else{
return false;
}
}
/**
* 用户退出他的房间
* @param user
* @param roomID
* @return
*/
public int esc(User user,long roomID){
if(map.containsKey(roomID)){
int number = map.get(roomID).delUser(user);
/*如果这个房间剩下的人数为0,那么删除该房间*/
if(number==0){
map.remove(roomID);
totalRooms--;
return 0;
}
return 1;
}else{
return -1;
}
}
/**
* 列出所有房间的列表,返回一个二维数组,strings[i][0]放房间的id,string[i][1]放房间的name
* @return
*/
public String[][] listRooms(){
String[][] strings = new String[totalRooms][2];
int i=0;
/*将map转化为set并使用迭代器来遍历*/
Set<Entry<Long,Room>> set = map.entrySet();
Iterator<Entry<Long,Room>> iterator = set.iterator();
while(iterator.hasNext()){
Map.Entry<Long,Room> entry = iterator.next();
long key = entry.getKey();
Room value = entry.getValue();
strings[i][0]=""+key;
strings[i][1]=value.getName();
}
return strings;
}
/**
* 通过roomID来获得房间
* @param roomID
* @return
*/
public Room getRoom(long roomID){
if(map.containsKey(roomID)){
return map.get(roomID);
}
else
return null;
}
}
服务端 Server
package Server;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.json.*;
import Room.Room;
import Room.RoomList;
import User.User;
/**
*
* @author lannooo
*
*/
public class Server {
private ArrayList<User> allUsers;
private RoomList rooms;
private int port;
private ServerSocket ss;
private long unusedUserID;
public final long MAX_USERS = 999999;
/**
* 通过port号来构造服务器端对象
* 维护一个总的用户列表和一个房间列表
* @param port
* @throws Exception
*/
public Server(int port) throws Exception {
allUsers = new ArrayList<>();
rooms = new RoomList();
this.port=port;
unusedUserID=1;
ss = new ServerSocket(port);
System.out.println("Server is builded!");
}
/**
* 获得下一个可用的用户id
* @return
*/
private long getNextUserID(){
if(unusedUserID < MAX_USERS)
return unusedUserID++;
else
return -1;
}
/**
* 开始监听,当接受到新的用户连接,就创建一个新的用户,并添加到用户列表中
* 然后创建一个新的服务线程用于收发该用户的消息
* @throws Exception
*/
public void startListen() throws Exception{
while(true){
Socket socket = ss.accept();
long id = getNextUserID();
if(id != -1){
User user = new User("User"+id,id,socket);
System.out.println(user.getName() + " is login...");
allUsers.add(user);
ServerThread thread = new ServerThread(user,allUsers,rooms);
thread.start();
}else{
System.out.println("Server is full!");
socket.close();
}
}
}
/**
* 测试用main方法,设置侦听端口为9999,并开始监听
* @param args
*/
public static void main(String[] args) {
try {
Server server = new Server(9999);
server.startListen();
} catch (Exception e) {
e.printStackTrace();
}
}
}
(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
