基于java网络聊天室--客户端
ChatClient.java
包含名为ChatClient的public类,其主要功能为定义客户端的界面,添加时间监听与事件处理。该类定义了Connect()与DisConnect()方法实现与客户端的连接与断开连接。当登陆到指定的服务器时,调用ClientReceive类实现消息收发,同时该类还定义了SendMessaga()方法来其他用户发送带有表情的消息或悄悄话。
1 /* 2 * To change this license header, choose License Headers in Project Properties. 3 * To change this template file, choose Tools | Templates 4 * and open the template in the editor. 5 */ 6 package com.silianbo.client; 7 8 /** 9 * 10 * @author silianbo 11 * 客户端主界面 12 */ 13 import com.silianbo.CaptureScreen; 14 import static com.silianbo.CaptureScreen.captureScreen; 15 import com.silianbo.client.ConnectConf; 16 import com.silianbo.client.Help; 17 import com.silianbo.client.UserConf; 18 19 import com.sun.security.ntlm.Client; 20 import java.awt.BorderLayout; 21 import java.awt.Component; 22 import java.awt.Container; 23 import java.awt.Dimension; 24 import java.awt.GridBagConstraints; 25 import java.awt.GridBagLayout; 26 import java.awt.Insets; 27 import java.awt.Toolkit; 28 import java.awt.event.ActionEvent; 29 import java.awt.event.ActionListener; 30 import java.awt.event.WindowAdapter; 31 import java.awt.event.WindowEvent; 32 import java.io.ObjectInputStream; 33 import java.io.ObjectOutputStream; 34 import java.net.Socket; 35 import java.util.logging.Level; 36 import java.util.logging.Logger; 37 import javax.swing.JButton; 38 import javax.swing.JCheckBox; 39 import javax.swing.JComboBox; 40 import javax.swing.JFrame; 41 import javax.swing.JLabel; 42 import javax.swing.JMenu; 43 import javax.swing.JMenuBar; 44 import javax.swing.JMenuItem; 45 import javax.swing.JOptionPane; 46 import javax.swing.JPanel; 47 import javax.swing.JScrollPane; 48 import javax.swing.JTextArea; 49 import javax.swing.JTextField; 50 import javax.swing.JToolBar; 51 import javax.swing.UIManager; 52 import javax.swing.UnsupportedLookAndFeelException; 53 54 /* 55 * 聊天客户端的主框架类 56 */ 57 public final class ChatClient extends JFrame implements ActionListener { 58 59 /** 60 * 版本控制,默认版本控制1L 61 */ 62 private static final long serialVersionUID = 1L; 63 64 String ip = "127.0.0.1"; //连接到服务端的ip地址 65 int port = 8888; //连接到服务端的端口号 66 String userName = "silianbo"; //用户名 67 int type = 0; //,用户连接标记,其中0表示未连接,1表示已连接 68 69 JComboBox combobox; //选择发送消息的接受者 70 JTextArea messageShow; //客户端的信息显示 71 JScrollPane messageScrollPane; //信息显示的滚动条 72 73 JLabel express, sendToLabel, messageLabel; 74 75 JTextField clientMessage;//客户端消息的发送 76 JCheckBox checkbox;//悄悄话 77 JComboBox actionlist;//表情选择 78 JButton clientMessageButton;//发送消息 79 JTextField showStatus;//显示用户连接状态 80 81 Socket socket; 82 ObjectOutputStream output;//网络套接字输出流 83 ObjectInputStream input;//网络套接字输入流 84 85 ClientReceive recvThread; 86 87 //建立菜单栏 88 JMenuBar jMenuBar = new JMenuBar(); 89 //建立菜单组 90 JMenu operateMenu = new JMenu("操作"); 91 //建立菜单项 92 JMenuItem loginItem = new JMenuItem("用户登录"); 93 JMenuItem logoffItem = new JMenuItem("用户注销"); 94 JMenuItem exitItem = new JMenuItem("退出"); 95 96 JMenu conMenu = new JMenu("设置"); 97 JMenuItem userItem = new JMenuItem("用户设置"); 98 JMenuItem connectItem = new JMenuItem("连接设置"); 99 100 JMenu helpMenu = new JMenu("帮助"); 101 JMenuItem helpItem = new JMenuItem("帮助"); 102 103 //建立工具栏 104 JToolBar toolBar = new JToolBar(); 105 106 //建立工具栏中的按钮组件 107 JButton loginButton;//用户登录 108 JButton logoffButton;//用户注销 109 JButton userButton;//用户信息的设置 110 JButton connectButton;//连接设置 111 JButton exitButton;//退出按钮 112 JButton captureScreenButton; //截屏按钮 113 114 //框架的大小 115 Dimension faceSize = new Dimension(550, 550); 116 117 JPanel downPanel; 118 GridBagLayout girdBag; 119 GridBagConstraints girdBagCon; 120 121 public ChatClient() { 122 init();//初始化程序 123 124 //添加框架的关闭事件处理 125 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 126 this.pack(); 127 //设置框架的大小 128 this.setSize(faceSize); 129 130 //设置运行时窗口的位置 131 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 132 this.setLocation((int) (screenSize.width - faceSize.getWidth()) / 2, 133 (int) (screenSize.height - faceSize.getHeight()) / 2); 134 this.setResizable(false); 135 this.setTitle("聊天室客户端"); //设置标题 136 137 setVisible(true); 138 139 //为操作菜单栏设置热键'V' 140 operateMenu.setMnemonic('O'); 141 142 } 143 144 /** 145 * 程序初始化函数 146 */ 147 public void init() { 148 149 Container contentPane = getContentPane(); 150 contentPane.setLayout(new BorderLayout()); 151 152 //添加菜单栏,对应55行相关介绍 153 jMenuBar.add(operateMenu); //操作(1.2.3) 154 operateMenu.add(loginItem); //1.用户登录 155 operateMenu.add(logoffItem); //2.用户注销 156 operateMenu.add(exitItem); //2.退出 157 158 jMenuBar.add(conMenu); //设置(a.b) 159 conMenu.add(userItem); //a.用户设置 160 conMenu.add(connectItem); //b.连接设置 161 162 jMenuBar.add(helpMenu); //帮助(I) 163 helpMenu.add(helpItem); //I.帮助 164 165 setJMenuBar(jMenuBar); 166 167 //初始化按钮 168 loginButton = new JButton("登录"); 169 logoffButton = new JButton("注销"); 170 userButton = new JButton("用户设置"); 171 connectButton = new JButton("连接设置"); 172 exitButton = new JButton("退出"); 173 captureScreenButton = new JButton("全屏截屏"); 174 JButton screenShotButton = new JButton("区域截图"); 175 176 //当鼠标放上显示信息 177 loginButton.setToolTipText("连接到指定的服务器"); 178 logoffButton.setToolTipText("与服务器断开连接"); 179 userButton.setToolTipText("设置用户信息"); 180 connectButton.setToolTipText("设置所要连接到的服务器信息"); 181 captureScreenButton.setToolTipText("现在只能全屏截下全屏"); 182 //将按钮添加到工具栏 183 toolBar.add(userButton); 184 Component add = toolBar.add(connectButton); 185 toolBar.addSeparator();//添加分隔栏 186 toolBar.add(loginButton); 187 toolBar.add(logoffButton); 188 toolBar.addSeparator();//添加分隔栏 189 toolBar.add(exitButton); 190 toolBar.add(captureScreenButton); 191 toolBar.add(screenShotButton); 192 193 contentPane.add(toolBar, BorderLayout.NORTH); 194 195 checkbox = new JCheckBox("悄悄话"); 196 checkbox.setSelected(false); 197 198 actionlist = new JComboBox(); 199 actionlist.addItem("@/微笑@"); 200 actionlist.addItem("@/高兴@"); 201 actionlist.addItem("@/轻轻@"); 202 actionlist.addItem("@/生气@"); 203 actionlist.addItem("@/小心@"); 204 actionlist.addItem("@/静静@"); 205 actionlist.setSelectedIndex(0); 206 207 //初始时 208 loginButton.setEnabled(true); 209 logoffButton.setEnabled(false); 210 211 //为菜单栏添加事件监听 212 loginItem.addActionListener(this); 213 logoffItem.addActionListener(this); 214 exitItem.addActionListener(this); 215 userItem.addActionListener(this); 216 connectItem.addActionListener(this); 217 helpItem.addActionListener(this); 218 219 //添加按钮的事件侦听 220 loginButton.addActionListener(this); 221 logoffButton.addActionListener(this); 222 userButton.addActionListener(this); 223 connectButton.addActionListener(this); 224 exitButton.addActionListener(this); 225 226 /* 227 *全屏截屏事件监听处理 228 */ 229 captureScreenButton.addActionListener((ActionEvent e) -> { 230 try { 231 CaptureScreen.RandomName filename = new CaptureScreen.RandomName(); 232 captureScreen("C:\\Users\\silianbo\\Desktop\\计算机网络课程设计\\image", filename + ".png"); 233 } catch (Exception ex) { 234 Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex); 235 } 236 }); 237 /** 238 * 区域截屏监听 239 */ 240 screenShotButton.addActionListener(this); 241 242 combobox = new JComboBox(); 243 combobox.insertItemAt("所有人", 0); 244 combobox.setSelectedIndex(0); 245 246 messageShow = new JTextArea(); 247 messageShow.setEditable(false); 248 //添加滚动条 249 messageScrollPane = new JScrollPane(messageShow, 250 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 251 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 252 messageScrollPane.setPreferredSize(new Dimension(400, 400)); 253 messageScrollPane.revalidate(); 254 255 clientMessage = new JTextField(23); 256 clientMessage.setEnabled(false); 257 clientMessageButton = new JButton(); 258 clientMessageButton.setText("发送"); 259 260 //添加系统消息的事件侦听 261 clientMessage.addActionListener(this); 262 clientMessageButton.addActionListener(this); 263 264 sendToLabel = new JLabel("发送至:"); 265 express = new JLabel(" 表情: "); 266 messageLabel = new JLabel("发送消息:"); 267 downPanel = new JPanel(); 268 girdBag = new GridBagLayout(); 269 downPanel.setLayout(girdBag); 270 271 girdBagCon = new GridBagConstraints(); 272 girdBagCon.gridx = 0; 273 girdBagCon.gridy = 0; 274 girdBagCon.gridwidth = 5; 275 girdBagCon.gridheight = 2; 276 girdBagCon.ipadx = 5; 277 girdBagCon.ipady = 5; 278 JLabel none = new JLabel(" "); 279 girdBag.setConstraints(none, girdBagCon); 280 downPanel.add(none); 281 282 girdBagCon = new GridBagConstraints(); 283 girdBagCon.gridx = 0; 284 girdBagCon.gridy = 2; 285 girdBagCon.insets = new Insets(1, 0, 0, 0); 286 //girdBagCon.ipadx = 5; 287 //girdBagCon.ipady = 5; 288 girdBag.setConstraints(sendToLabel, girdBagCon); 289 downPanel.add(sendToLabel); 290 291 girdBagCon = new GridBagConstraints(); 292 girdBagCon.gridx = 1; 293 girdBagCon.gridy = 2; 294 girdBagCon.anchor = GridBagConstraints.LINE_START; 295 girdBag.setConstraints(combobox, girdBagCon); 296 downPanel.add(combobox); 297 298 girdBagCon = new GridBagConstraints(); 299 girdBagCon.gridx = 2; 300 girdBagCon.gridy = 2; 301 girdBagCon.anchor = GridBagConstraints.LINE_END; 302 girdBag.setConstraints(express, girdBagCon); 303 downPanel.add(express); 304 305 girdBagCon = new GridBagConstraints(); 306 girdBagCon.gridx = 3; 307 girdBagCon.gridy = 2; 308 girdBagCon.anchor = GridBagConstraints.LINE_START; 309 //girdBagCon.insets = new Insets(1,0,0,0); 310 //girdBagCon.ipadx = 5; 311 //girdBagCon.ipady = 5; 312 girdBag.setConstraints(actionlist, girdBagCon); 313 downPanel.add(actionlist); 314 315 girdBagCon = new GridBagConstraints(); 316 girdBagCon.gridx = 4; 317 girdBagCon.gridy = 2; 318 girdBagCon.insets = new Insets(1, 0, 0, 0); 319 // girdBagCon.ipadx = 5; 320 // girdBagCon.ipady = 5; 321 girdBag.setConstraints(checkbox, girdBagCon); 322 downPanel.add(checkbox); 323 324 girdBagCon = new GridBagConstraints(); 325 girdBagCon.gridx = 0; 326 girdBagCon.gridy = 3; 327 girdBag.setConstraints(messageLabel, girdBagCon); 328 downPanel.add(messageLabel); 329 330 girdBagCon = new GridBagConstraints(); 331 girdBagCon.gridx = 1; 332 girdBagCon.gridy = 3; 333 girdBagCon.gridwidth = 3; 334 girdBagCon.gridheight = 1; 335 girdBag.setConstraints(clientMessage, girdBagCon); 336 downPanel.add(clientMessage); 337 338 girdBagCon = new GridBagConstraints(); 339 girdBagCon.gridx = 4; 340 girdBagCon.gridy = 3; 341 girdBag.setConstraints(clientMessageButton, girdBagCon); 342 downPanel.add(clientMessageButton); 343 344 showStatus = new JTextField(35); 345 showStatus.setEditable(false); 346 girdBagCon = new GridBagConstraints(); 347 girdBagCon.gridx = 0; 348 girdBagCon.gridy = 5; 349 girdBagCon.gridwidth = 5; 350 girdBag.setConstraints(showStatus, girdBagCon); 351 downPanel.add(showStatus); 352 353 contentPane.add(messageScrollPane, BorderLayout.CENTER); 354 contentPane.add(downPanel, BorderLayout.SOUTH); 355 356 //关闭程序时的操作 357 this.addWindowListener( 358 new WindowAdapter() { 359 @Override 360 public void windowClosing(WindowEvent e) { 361 if (type == 1) { 362 DisConnect(); 363 } 364 System.exit(0); 365 } 366 } 367 ); 368 } 369 370 /** 371 * 事件处理 372 */ 373 @Override 374 public void actionPerformed(ActionEvent e) { 375 Object obj = e.getSource(); 376 377 if (obj == userItem || obj == userButton) { //用户信息设置 378 //调出用户信息设置对话框 379 UserConf userConf = new UserConf(this, userName); 380 userConf.setVisible(true); 381 userName = userConf.userInputName; 382 } else if (obj == connectItem || obj == connectButton) { //连接服务端设置 383 //调出连接设置对话框 384 ConnectConf conConf = new ConnectConf(this, ip, port); 385 conConf.setVisible(true); 386 ip = conConf.userInputIp; 387 port = conConf.userInputPort; 388 } else if (obj == loginItem || obj == loginButton) { //登录 389 Connect(); 390 } else if (obj == logoffItem || obj == logoffButton) { //注销 391 DisConnect(); 392 showStatus.setText(""); 393 } else if (obj == clientMessage || obj == clientMessageButton) { //发送消息 394 SendMessage(); 395 clientMessage.setText(""); 396 } else if (obj == exitButton || obj == exitItem) { //退出 397 int j = JOptionPane.showConfirmDialog( 398 this, "真的要退出吗?", "退出", 399 JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE); 400 401 if (j == JOptionPane.YES_OPTION) { 402 if (type == 1) { 403 DisConnect(); 404 } 405 System.exit(0); 406 } 407 } else if (obj == helpItem) { //菜单栏中的帮助 408 //调出帮助对话框 409 Help helpDialog = new Help(this); 410 helpDialog.setVisible(true); 411 } 412 } 413 /** 414 * 连接服务器 415 */ 416 public void Connect() { 417 try { 418 socket = new Socket(ip, port); 419 } catch (Exception e) { 420 JOptionPane.showConfirmDialog( 421 this, "不能连接到指定的服务器。\n请确认连接设置是否正确。", "提示", 422 JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE); 423 return; 424 } 425 426 try { 427 output = new ObjectOutputStream(socket.getOutputStream()); 428 output.flush(); 429 430 input = new ObjectInputStream(socket.getInputStream()); 431 432 output.writeObject(userName); 433 output.flush(); 434 435 recvThread = new ClientReceive(socket, output, input, combobox, messageShow, showStatus); 436 recvThread.start(); 437 438 loginButton.setEnabled(false); 439 loginItem.setEnabled(false); 440 userButton.setEnabled(false); 441 userItem.setEnabled(false); 442 connectButton.setEnabled(false); 443 connectItem.setEnabled(false); 444 logoffButton.setEnabled(true); 445 logoffItem.setEnabled(true); 446 clientMessage.setEnabled(true); 447 messageShow.append("连接服务器 " + ip + ":" + port + " 成功...\n"); 448 type = 1;//标志位设为已连接 449 } catch (Exception e) { 450 System.out.println(e); 451 } 452 } 453 454 /** 455 *服务器注销 456 */ 457 public void DisConnect() { 458 loginButton.setEnabled(true); 459 loginItem.setEnabled(true); 460 userButton.setEnabled(true); 461 userItem.setEnabled(true); 462 connectButton.setEnabled(true); 463 connectItem.setEnabled(true); 464 logoffButton.setEnabled(false); 465 logoffItem.setEnabled(false); 466 clientMessage.setEnabled(false); 467 468 if (socket.isClosed()) { 469 return; 470 } 471 472 try { 473 output.writeObject("用户下线"); 474 output.flush(); 475 476 input.close(); 477 output.close(); 478 socket.close(); 479 messageShow.append("已经与服务器断开连接...\n"); 480 type = 0;//标志位设为未连接 481 } catch (Exception e) { 482 // 483 } 484 } 485 486 public void SendMessage() { 487 String toSomebody = combobox.getSelectedItem().toString(); 488 String status = ""; 489 if (checkbox.isSelected()) { 490 status = "悄悄话"; 491 } 492 493 String action = actionlist.getSelectedItem().toString(); 494 String message = clientMessage.getText(); 495 496 if (socket.isClosed()) { 497 return; 498 } 499 500 try { 501 output.writeObject("聊天信息"); 502 output.flush(); 503 output.writeObject(toSomebody); 504 output.flush(); 505 output.writeObject(status); 506 output.flush(); 507 output.writeObject(action); 508 output.flush(); 509 output.writeObject(message); 510 output.flush(); 511 } catch (Exception e) { 512 // 513 } 514 } 515 516 public static void main(String[] args) throws UnsupportedLookAndFeelException { 517 try { 518 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 519 } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { 520 } 521 ChatClient chatClient = new ChatClient(); 522 } 523 }
ConnectConf.java
该类继承自Jdialog,是用户对所有要连接的服务器IP及监听端口进行修改配置的类
1 /* 2 * To change this license header, choose License Headers in Project Properties. 3 * To change this template file, choose Tools | Templates 4 * and open the template in the editor. 5 */ 6 package com.silianbo.client; 7 8 import java.awt.BorderLayout; 9 import java.awt.Container; 10 import java.awt.Dimension; 11 import java.awt.GridLayout; 12 import java.awt.Label; 13 import java.awt.Toolkit; 14 import java.awt.event.ActionEvent; 15 import java.awt.event.WindowAdapter; 16 import java.awt.event.WindowEvent; 17 import java.net.InetAddress; 18 import java.net.UnknownHostException; 19 import javax.swing.JButton; 20 import javax.swing.JDialog; 21 import javax.swing.JFrame; 22 import javax.swing.JLabel; 23 import javax.swing.JPanel; 24 import javax.swing.JTextField; 25 26 /** 27 * 28 * @author silianbo 29 * 生成连接信息输入的对话框 让用户输入连接服务器的IP和端口 30 */ 31 public class ConnectConf extends JDialog { 32 33 /** 34 * 35 */ 36 private static final long serialVersionUID = 1L; 37 JPanel panelUserConf = new JPanel(); 38 JButton save = new JButton(); 39 JButton cancel = new JButton(); 40 JLabel DLGINFO = new JLabel( 41 " 默认连接设置为 127.0.0.1:8888"); 42 43 JPanel panelSave = new JPanel(); 44 JLabel message = new JLabel(); 45 46 String userInputIp; 47 int userInputPort; 48 49 JTextField inputIp; 50 JTextField inputPort; 51 52 public ConnectConf(JFrame frame, String ip, int port) { 53 super(frame, true); 54 this.userInputIp = ip; 55 this.userInputPort = port; 56 try { 57 jbInit(); 58 } catch (Exception e) { 59 } 60 //设置运行位置,使对话框居中 61 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 62 this.setLocation((int) (screenSize.width - 400) / 2 + 50, 63 (int) (screenSize.height - 600) / 2 + 150); 64 this.setResizable(false); 65 } 66 67 private void jbInit() throws Exception { 68 this.setSize(new Dimension(300, 130)); 69 this.setTitle("连接设置"); 70 message.setText(" 请输入服务器的IP地址:"); 71 inputIp = new JTextField(10); 72 inputIp.setText(userInputIp); 73 inputPort = new JTextField(4); 74 inputPort.setText("" + userInputPort); 75 save.setText("保存"); 76 cancel.setText("取消"); 77 78 panelUserConf.setLayout(new GridLayout(2, 2, 1, 1)); 79 panelUserConf.add(message); 80 panelUserConf.add(inputIp); 81 panelUserConf.add(new JLabel(" 请输入服务器的端口号:")); 82 panelUserConf.add(inputPort); 83 84 panelSave.add(new Label(" ")); 85 panelSave.add(save); 86 panelSave.add(cancel); 87 panelSave.add(new Label(" ")); 88 89 Container contentPane = getContentPane(); 90 contentPane.setLayout(new BorderLayout()); 91 contentPane.add(panelUserConf, BorderLayout.NORTH); 92 contentPane.add(DLGINFO, BorderLayout.CENTER); 93 contentPane.add(panelSave, BorderLayout.SOUTH); 94 95 //保存按钮的事件处理 96 save.addActionListener((ActionEvent a) -> { 97 int savePort; 98 //判断端口号是否合法 99 try { 100 userInputIp = "" + InetAddress.getByName(inputIp.getText()); 101 userInputIp = userInputIp.substring(1); 102 } catch (UnknownHostException e) { 103 DLGINFO.setText( 104 " 错误的IP地址!"); 105 106 return; 107 } 108 //userInputIp = inputIP; 109 110 //判断端口号是否合法 111 try { 112 savePort = Integer.parseInt(inputPort.getText()); 113 114 if (savePort < 1 || savePort > 65535) { 115 DLGINFO.setText(" 侦听端口必须是0-65535之间的整数!"); 116 inputPort.setText(""); 117 return; 118 } 119 userInputPort = savePort; 120 dispose(); 121 } catch (NumberFormatException e) { 122 DLGINFO.setText(" 错误的端口号,端口号请填写整数!"); 123 inputPort.setText(""); 124 } 125 }); 126 127 //关闭对话框时的操作 128 this.addWindowListener( 129 new WindowAdapter() { 130 @Override 131 public void windowClosing(WindowEvent e) { 132 DLGINFO.setText(" 默认连接设置为 127.0.0.1:8888"); 133 } 134 } 135 ); 136 137 //取消按钮的事件处理 138 cancel.addActionListener((ActionEvent e) -> { 139 DLGINFO.setText(" 默认连接设置为 127.0.0.1:8888"); 140 dispose(); 141 }); 142 } 143 }
UserConf.java
该类继承自Jdialog,是用户对链接到服务器时所显示的用户名进行修改配置的类。
1 /* 2 * To change this license header, choose License Headers in Project Properties. 3 * To change this template file, choose Tools | Templates 4 * and open the template in the editor. 5 */ 6 package com.silianbo.client; 7 8 import java.awt.*; 9 import javax.swing.*; 10 import java.awt.event.*; 11 /** 12 * 13 * @author silianbo 14 * 生成用户信息输入对话框的类 15 * 让用户输入自己的用户名 16 */ 17 public class UserConf extends JDialog { 18 /** 19 * 20 */ 21 private static final long serialVersionUID = 1L; 22 JPanel panelUserConf = new JPanel(); 23 JButton save = new JButton(); 24 JButton cancel = new JButton(); 25 JLabel DLGINFO=new JLabel( 26 " 默认用户名为:silianbo"); 27 28 JPanel panelSave = new JPanel(); 29 JLabel message = new JLabel(); 30 String userInputName; 31 32 JTextField userName ; 33 34 public UserConf(JFrame frame,String str) { 35 super(frame, true); 36 this.userInputName = str; 37 try { 38 jbInit(); 39 } 40 catch (Exception e) { 41 e.printStackTrace(); 42 } 43 //设置运行位置,使对话框居中 44 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 45 this.setLocation( (int) (screenSize.width - 400) / 2 + 50, 46 (int) (screenSize.height - 600) / 2 + 150); 47 this.setResizable(false); 48 } 49 50 private void jbInit() throws Exception { 51 this.setSize(new Dimension(300, 120)); 52 this.setTitle("用户设置"); 53 message.setText("请输入用户名:"); 54 userName = new JTextField(10); 55 userName.setText(userInputName); 56 save.setText("保存"); 57 cancel.setText("取消"); 58 59 panelUserConf.setLayout(new FlowLayout()); 60 panelUserConf.add(message); 61 panelUserConf.add(userName); 62 63 panelSave.add(new Label(" ")); 64 panelSave.add(save); 65 panelSave.add(cancel); 66 panelSave.add(new Label(" ")); 67 68 Container contentPane = getContentPane(); 69 contentPane.setLayout(new BorderLayout()); 70 contentPane.add(panelUserConf, BorderLayout.NORTH); 71 contentPane.add(DLGINFO, BorderLayout.CENTER); 72 contentPane.add(panelSave, BorderLayout.SOUTH); 73 74 //保存按钮的事件处理 75 save.addActionListener( 76 new ActionListener() { 77 public void actionPerformed (ActionEvent a) { 78 if(userName.getText().equals("")){ 79 DLGINFO.setText( 80 " 用户名不能为空!"); 81 userName.setText(userInputName); 82 return; 83 } 84 else if(userName.getText().length() > 15){ 85 DLGINFO.setText(" 用户名长度不能大于15个字符!"); 86 userName.setText(userInputName); 87 return; 88 } 89 userInputName = userName.getText(); 90 dispose(); 91 } 92 } 93 ); 94 95 //关闭对话框时的操作 96 this.addWindowListener( 97 new WindowAdapter(){ 98 @Override 99 public void windowClosing(WindowEvent e){ 100 DLGINFO.setText(" 默认用户名为:silianbo"); 101 } 102 } 103 ); 104 105 //取消按钮的事件处理 106 cancel.addActionListener((ActionEvent e) -> { 107 DLGINFO.setText(" 默认用户名为:silianbo"); 108 dispose(); 109 }); 110 } 111 }
Help.java
客户端程序的帮助类
1 /* 2 * To change this license header, choose License Headers in Project Properties. 3 * To change this template file, choose Tools | Templates 4 * and open the template in the editor. 5 */ 6 package com.silianbo.client; 7 8 /** 9 * 10 * @author silianbo 11 */ 12 import java.awt.*; 13 import javax.swing.*; 14 import java.awt.event.*; 15 16 /** 17 * 生成设置对话框的类 18 */ 19 public class Help extends JDialog { 20 21 /** 22 * 23 */ 24 private static final long serialVersionUID = 1L; 25 JPanel titlePanel = new JPanel(); 26 JPanel contentPanel = new JPanel(); 27 JPanel closePanel = new JPanel(); 28 29 JButton close = new JButton(); 30 JLabel title = new JLabel("聊天室客户端帮助"); 31 JTextArea help = new JTextArea(); 32 33 Color bg = new Color(255,255,255); 34 35 public Help(JFrame frame) { 36 super(frame, true); 37 try { 38 jbInit(); 39 } 40 catch (Exception e) { 41 e.printStackTrace(); 42 } 43 //设置运行位置,使对话框居中 44 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 45 this.setLocation( (int) (screenSize.width - 400) / 2 + 25, 46 (int) (screenSize.height - 320) / 2); 47 this.setResizable(false); 48 } 49 50 private void jbInit() throws Exception { 51 this.setSize(new Dimension(350, 270)); 52 this.setTitle("帮助"); 53 54 titlePanel.setBackground(bg);; 55 contentPanel.setBackground(bg); 56 closePanel.setBackground(bg); 57 58 help.setText("1、设置所要连接服务端的IP地址和端口"+ 59 "(默认设置为\n 127.0.0.1:8888)。\n"+ 60 "2、输入你的用户名(默认设置为:silianbo)。\n"+ 61 "3、点击“登录”便可以连接到指定的服务器;\n"+ 62 " 点击“注销”可以和服务器端开连接。\n"+ 63 "4、选择需要接受消息的用户,在消息栏中写入消息,\n"+ 64 " 同时选择表情,之后便可发送消息。\n"); 65 help.setEditable(false); 66 67 titlePanel.add(new Label(" ")); 68 titlePanel.add(title); 69 titlePanel.add(new Label(" ")); 70 71 contentPanel.add(help); 72 73 closePanel.add(new Label(" ")); 74 closePanel.add(close); 75 closePanel.add(new Label(" ")); 76 77 Container contentPane = getContentPane(); 78 contentPane.setLayout(new BorderLayout()); 79 contentPane.add(titlePanel, BorderLayout.NORTH); 80 contentPane.add(contentPanel, BorderLayout.CENTER); 81 contentPane.add(closePanel, BorderLayout.SOUTH); 82 83 close.setText("关闭"); 84 //事件处理 85 close.addActionListener((ActionEvent e) -> { 86 dispose(); 87 }); 88 } 89 }
ClientReceive.java
该类是实现服务器端与客户端消息收发的类
1 /* 2 * To change this license header, choose License Headers in Project Properties. 3 * To change this template file, choose Tools | Templates 4 * and open the template in the editor. 5 */ 6 package com.silianbo.client; 7 8 import java.io.IOException; 9 import java.io.ObjectInputStream; 10 import java.io.ObjectOutputStream; 11 import java.net.Socket; 12 import javax.swing.JComboBox; 13 import javax.swing.JTextArea; 14 import javax.swing.JTextField; 15 16 /** 17 * 18 * @author silianbo 19 * 聊天客户端消息收发类 20 */ 21 public class ClientReceive extends Thread { 22 private final JComboBox combobox; 23 private final JTextArea textarea; 24 25 Socket socket; 26 ObjectOutputStream output; 27 ObjectInputStream input; 28 JTextField showStatus; 29 30 public ClientReceive(Socket socket,ObjectOutputStream output, 31 ObjectInputStream input,JComboBox combobox,JTextArea textarea,JTextField showStatus){ 32 33 this.socket = socket; 34 this.output = output; 35 this.input = input; 36 this.combobox = combobox; 37 this.textarea = textarea; 38 this.showStatus = showStatus; 39 } 40 41 @Override 42 public void run(){ 43 while(!socket.isClosed()){ 44 try{ 45 String type = (String)input.readObject(); 46 47 if(type.equalsIgnoreCase("系统信息")){ 48 String sysmsg = (String)input.readObject(); 49 textarea.append("系统信息: "+sysmsg); 50 } 51 else if(type.equalsIgnoreCase("服务关闭")){ 52 output.close(); 53 input.close(); 54 socket.close(); 55 56 textarea.append("服务器已关闭!\n"); 57 58 break; 59 } 60 else if(type.equalsIgnoreCase("聊天信息")){ 61 String message = (String)input.readObject(); 62 textarea.append(message); 63 } 64 else if(type.equalsIgnoreCase("用户列表")){ 65 String userlist = (String)input.readObject(); 66 String usernames[] = userlist.split("\n"); 67 combobox.removeAllItems(); 68 69 int i =0; 70 combobox.addItem("所有人"); 71 while(i < usernames.length){ 72 combobox.addItem(usernames[i]); 73 i ++; 74 } 75 combobox.setSelectedIndex(0); 76 showStatus.setText("在线用户 " + usernames.length + " 人"); 77 } 78 } 79 catch (IOException | ClassNotFoundException e ){ 80 System.out.println(e); 81 } 82 } 83 } 84 }