聊天程序 登录 私聊 群聊 退出
图1.1 聊天程序模块示意图
1.4系统类层次
定义聊天室客户端类:public class Client
定义聊天室服务器端类:public class Server implements Protocol 定义用户线程类:static class UserThread extends Thread 私聊窗口类:private class ChatWindow
接收服务器发送的信息类:class GetMsgThread extends Thread 登陆线程类:public class LoginThread extends Thread implements Protocol
聊天线程类:class ChatThread extends Thread implements Protocol 检查信息是否允许发送,包括检查敏感词汇/空信息/刷屏:private boolean isAllowed(String msg, String msgto)
5
二、详细设计
2.1聊天室客户端类
public class Client {
//主方法:启动登陆线程
public static void main(String[] args) throws Exception {
Thread login = new LoginThread();
login.start(); } }
2.2聊天线程类的实现
class ChatThread extends Thread implements Protocol { private Map users = new HashMap();
private String name;
private Socket s;
private BufferedReader in;
private PrintWriter out;
private JComboBox cb;
private JFrame f;
private JTextArea ta;
private JTextField tf;
private static long time;// 上一条信息的发出时间
6
private static int total;// 在线人数统计
public ChatThread(String name, Socket s, BufferedReader in, PrintWriter out) {
this.name = name; this.s = s; this.in = in; this.out = out; }
2.3接收服务器发送的信息类的实现
class GetMsgThread extends Thread {
public void run() { try {
String msg, name;
while (!s.isClosed()) { /*
* 不断接受服务器信息,外层循环防止读到null跳出循环
*/ while (!s.isClosed() && (msg = in.readLine()) != null) {
msg = specialMsg(msg);// 系统信息处理 if (msg.startsWith(MSG_FROM)) {
msg = msg.replaceFirst(MSG_FROM, \ name = msg.substring(0, msg.indexOf(NAME_END));
msg = msg.replaceFirst(name + NAME_END, \
JTextArea tas = ((ChatWindow) users.get(name)).tas;
tas.append(name + \说: \+ msg + \
tas.setCaretPosition(tas.getText().length());
ta.append(name + \悄悄地对你说: \msg + \
} else if (msg.contains(NAME_END)) { name = msg.substring(0, msg.indexOf(NAME_END));
msg = msg.replaceFirst(name +
7
NAME_END, \
ta.append(name + \说: \+ msg + \在窗口显示信息
} else {
ta.append(msg + \ }
ta.setCaretPosition(ta.getText().length());// 自动滚动到底部
} }
} catch (Exception e) {
out.println(SYSTEM_MSG + USER_LOGOUT);// 当异常产生时向系统发出退出信息
} finally { try {
s.close();
} catch (IOException e) { } } } }
GetMsgThread gt = new GetMsgThread(); gt.start();
2.4处理系统信息的实现
private String specialMsg(String msg) {
if (msg.startsWith(SYSTEM_MSG)) {
msg = msg.replaceFirst(SYSTEM_MSG, \ /*
* 当有人进入聊天室 */
if (msg.startsWith(ADD_USER)) {
msg = msg.replaceFirst(ADD_USER, \ cb.addItem(msg); users.put(msg,
ChatWindow(msg));//////////////////////////////
total++;
msg += \进入聊天室\ } /*
* 当有人离开聊天室 */
8
new
else if (msg.startsWith(DELETE_USER)) {
msg = msg.replaceFirst(DELETE_USER, \ cb.removeItem(msg);
((ChatWindow) users.get(msg)).tas.append(msg + \退出聊天室\\n\
users.remove(msg); total--;
msg += \退出聊天室\ } /*
* 登陆时获得的在线用户列表信息 */
else if (msg.startsWith(EXIST_USERS)) {
msg = msg.replaceFirst(EXIST_USERS, \ cb.addItem(msg);
users.put(msg, new ChatWindow(msg)); total++;
msg += \正在聊天室\ } /*
* 即时显示在线人数 */
f.setTitle(SOFTWARE + \当前在线人数:\
return msg; }
return msg; }
/**
* 检查信息是否允许发送,包括检查敏感词汇/空信息/刷屏 */
private boolean isAllowed(String msg, String msgto) { /*
* 过滤空信息 */
if (msg.length() == 0) return false;
String errmsg = null; /*
* 过滤敏感词汇 */
for (int i = 0; i < FORBID_WORDS.length; i++) { if (msg.indexOf(FORBID_WORDS[i]) > -1) {
9