本文基於一個完整的 Java Swing Socket 聊天室客戶端,從通訊模組與UI 模組兩大維度,深度剖析其多執行緒架構、心跳機制、訊息路由分發、以及 UI 與業務邏輯的解耦設計,附完整代碼結構與關鍵類別說明。


Socket、固定大小 2 的 ExecutorService (接收 + 心跳)Callback 介面,實現訊息處理邏輯的可插拔start() 啟動 ReceiveListener;keepAlive() 啟動 KeepAliveDogKEEP_ALIVE_PERIOD 秒發送 AliveMessage (JSON 序列化)PrintWriter 寫入 Socket 輸出流,flush() 確保送達BufferedReader,累積完整行LoggerUtil.trach 記錄 → callback.doWork() 分發FILE 類型,Thread.sleep(MESSAGE_PERIOD) 讓位給檔案流讀取Callback 單一方法 doWork(Socket, Object),業務邏輯完全外置DefaultCallback 處理三類訊息:
CHAT:路由至對應分頁 JTextArea 顯示FILE:直接寫入 CLIENT_RECEIVE_DIR,未經使用者確認 (可改進)RETURN:根據 Key 分發給對應 HandlerHandler 介面單一方法 handle(Object)HF.getHandler(key) 簡易工廠回傳具體實作:LoginHdl、RegisterHdl、ListUserHdl、NotifyHdl、TipHdlRouter 取得) 完成登入跳轉、用戶列表刷新、通知彈窗等靜態持有 Client 實例,供全域存取 (如 Action 發送訊息)。
public interface View {
View create(); // 延遲初始化
Container container(); // 給 JOptionPane 用
JComponent getComponent(String key); // 供 Handler 取得元件
void display(); // setVisible(true)
void trash(); // dispose()
}
Map<String, View> 快取已建立視圖getView(Class) 反射實例化並快取BorderLayout 中央 JTabbedPane (聊天分頁)、東側 JList (線上用戶)、底部輸入區 (文字/檔案/發送)RegisterAndLoginAction:組裝 RegisterMessage/LoginMessage 經 SendHelper 發送ChatRoomAction:處理發送文字、上傳檔案 (非廣播模式)ResultWrapper 封裝 JScrollPane + JTextAreaResultHolder 以 Map<String, ResultWrapper> 快取,鍵為對方用戶名public class NiloayChat {
public static void main(String[] args) {
View loginView = Router.getView(RegisterAndLoginView.class).create();
loginView.display();
try {
Client client = new Client(new DefaultCallback());
client.start();
ClientHolder.setClient(client);
} catch (IOException e) {
JOptionPane.showMessageDialog(loginView.container(), e.getMessage());
}
}
}
ScheduledExecutorService 更精準該客戶端展示了經典的「固定執行緒池 + 回調分發 + 介面導向 UI」架構。通訊層與 UI 層透過 Callback/Handler/Router 徹底解耦,擴充新訊息類型只需新增 Handler 並註冊至 HF,符合開放封閉原則。代碼結構清晰,適合作為 Java Socket 程式設計的進階學習範本。