服务器界面:
客户端登录界面:
客户端界面:
使用的是java里面的socket接口进行服务器与客户端之间的通信
具体代码:
login.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 program; 7 8 import com.mysql.jdbc.Connection; 9 import com.mysql.jdbc.Statement; 10 import java.awt.Toolkit; 11 import java.sql.DriverManager; 12 import java.sql.ResultSet; 13 import java.sql.SQLException; 14 import java.util.logging.Level; 15 import java.util.logging.Logger; 16 import javax.swing.JOptionPane; 17 18 /** 19 * 20 * @author 杉琪建 21 */ 22 public class login extends javax.swing.JFrame { 23 24 /** 25 * Creates new form login 26 */ 27 public login() { 28 initComponents();//登录界面UI的设计函数 29 int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width; 30 int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height; 31 this.setLocation((screen_width - this.getWidth()) / 2, 32 (screen_height - this.getHeight()) / 2);//设置窗口弹出为桌面正中央 33 } 34 35 /** 36 * This method is called from within the constructor to initialize the form. 37 * WARNING: Do NOT modify this code. The content of this method is always 38 * regenerated by the Form Editor. 39 */ 40 @SuppressWarnings("unchecked") 41 // <editor-fold defaultstate="collapsed" desc="Generated Code"> 42 private void initComponents() { 43 bindingGroup = new org.jdesktop.beansbinding.BindingGroup(); 44 45 jTextField1 = new javax.swing.JTextField(); 46 jPasswordField1 = new javax.swing.JPasswordField(); 47 jLabel1 = new javax.swing.JLabel(); 48 jLabel2 = new javax.swing.JLabel(); 49 jButton1 = new javax.swing.JButton(); 50 51 setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 52 53 org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("登录界面"), this, org.jdesktop.beansbinding.BeanProperty.create("title")); 54 bindingGroup.addBinding(binding); 55 56 jPasswordField1.addActionListener(new java.awt.event.ActionListener() { 57 public void actionPerformed(java.awt.event.ActionEvent evt) { 58 jPasswordField1ActionPerformed(evt); 59 } 60 }); 61 62 jLabel1.setText("用户名:"); 63 64 jLabel2.setText("密码:"); 65 66 jButton1.setText("登录"); 67 jButton1.addActionListener(new java.awt.event.ActionListener() { 68 public void actionPerformed(java.awt.event.ActionEvent evt) { 69 jButton1ActionPerformed(evt); 70 } 71 }); 72 73 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 74 getContentPane().setLayout(layout); 75 layout.setHorizontalGroup( 76 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 77 .addGroup(layout.createSequentialGroup() 78 .addContainerGap(39, Short.MAX_VALUE) 79 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 80 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 81 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 82 .addComponent(jLabel1) 83 .addComponent(jLabel2)) 84 .addGap(27, 27, 27) 85 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) 86 .addComponent(jPasswordField1, javax.swing.GroupLayout.DEFAULT_SIZE, 144, Short.MAX_VALUE) 87 .addComponent(jTextField1)) 88 .addGap(101, 101, 101)) 89 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 90 .addComponent(jButton1) 91 .addGap(31, 31, 31)))) 92 ); 93 layout.setVerticalGroup( 94 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 95 .addGroup(layout.createSequentialGroup() 96 .addGap(31, 31, 31) 97 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 98 .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 99 .addComponent(jLabel1)) 100 .addGap(18, 18, 18) 101 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 102 .addComponent(jPasswordField1, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE) 103 .addComponent(jLabel2)) 104 .addGap(18, 18, 18) 105 .addComponent(jButton1) 106 .addContainerGap(16, Short.MAX_VALUE)) 107 ); 108 109 bindingGroup.bind(); 110 111 pack(); 112 }// </editor-fold> 113 114 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 115 load(); 116 } 117 118 private void jPasswordField1ActionPerformed(java.awt.event.ActionEvent evt) { 119 load(); 120 } 121 122 public void load() {//登录判断跳转函数 123 this.setVisible(false); 124 String userName = jTextField1.getText().trim();//接受用户名 125 String passwd = new String(jPasswordField1.getPassword());//接受密码 126 try { 127 DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 128 String dbURL = "jdbc:mysql://127.0.0.1:3306/test"; 129 Connection connection = (Connection) DriverManager.getConnection(dbURL, "root", "1239842619");//进行数据库的连接 130 Statement statement = (Statement) connection.createStatement(); 131 String sql = "select * from clients where (name=‘" + userName + "‘ and passwd=‘" + passwd + "‘)";//简单的查询是否有相应的数据在数据库里面 132 ResultSet rs = statement.executeQuery(sql); 133 if (rs.next()) { 134 new Client(userName).setVisible(true); 135 } else { 136 JOptionPane.showMessageDialog(null, "用户名不存在或密码错误", "登录失败", JOptionPane.ERROR_MESSAGE); 137 System.exit(0); 138 } 139 } catch (SQLException ex) { 140 Logger.getLogger(login.class.getName()).log(Level.SEVERE, null, ex); 141 } 142 } 143 144 /** 145 * @param args the command line arguments 146 */ 147 public static void main(String args[]) { 148 /* Set the Nimbus look and feel */ 149 //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 150 /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 151 * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 152 */ 153 try { 154 for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 155 if ("Nimbus".equals(info.getName())) { 156 javax.swing.UIManager.setLookAndFeel(info.getClassName()); 157 break; 158 } 159 } 160 } catch (ClassNotFoundException ex) { 161 java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 162 } catch (InstantiationException ex) { 163 java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 164 } catch (IllegalAccessException ex) { 165 java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 166 } catch (javax.swing.UnsupportedLookAndFeelException ex) { 167 java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 168 } 169 //</editor-fold> 170 //</editor-fold> 171 //</editor-fold> 172 //</editor-fold> 173 174 /* Create and display the form */ 175 java.awt.EventQueue.invokeLater(new Runnable() { 176 public void run() { 177 new login().setVisible(true); 178 } 179 }); 180 } 181 182 // Variables declaration - do not modify 183 private javax.swing.JButton jButton1; 184 private javax.swing.JLabel jLabel1; 185 private javax.swing.JLabel jLabel2; 186 private javax.swing.JPasswordField jPasswordField1; 187 private javax.swing.JTextField jTextField1; 188 private org.jdesktop.beansbinding.BindingGroup bindingGroup; 189 // End of variables declaration 190 }
Client.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 program; 7 8 import java.awt.Toolkit; 9 import java.io.BufferedReader; 10 import java.io.InputStreamReader; 11 import java.io.PrintWriter; 12 import java.net.Socket; 13 14 /** 15 * 16 * @author 杉琪建 17 */ 18 public class Client extends javax.swing.JFrame { 19 Socket socket; 20 PrintWriter writer; 21 BufferedReader reader; 22 MessageThread messageThread; 23 String sourceName; 24 /** 25 * Creates new form Server 26 */ 27 public Client(String userName) { 28 initComponents(); 29 sourceName = userName;//接受登录界面的输入名字作为客户端进程的名字 30 setTitle(userName); 31 int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width; 32 int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height; 33 this.setLocation((screen_width - this.getWidth()) / 2, 34 (screen_height - this.getHeight()) / 2); 35 try { 36 socket = new Socket("127.0.0.1", 4705);//默认设置为本机方便测试 37 reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 38 writer = new PrintWriter(socket.getOutputStream()); 39 String message = userName; 40 sendMessage(message);//在初始化程序的同时发送一条消息到服务器,告知自己的名字 41 messageThread = new MessageThread(reader); 42 messageThread.start(); 43 } catch (Exception e) { 44 System.out.println("Error : " + e); 45 } 46 47 } 48 49 /** 50 * This method is called from within the constructor to initialize the form. 51 * WARNING: Do NOT modify this code. The content of this method is always 52 * regenerated by the Form Editor. 53 */ 54 @SuppressWarnings("unchecked") 55 // <editor-fold defaultstate="collapsed" desc="Generated Code"> 56 private void initComponents() { 57 bindingGroup = new org.jdesktop.beansbinding.BindingGroup(); 58 59 jPanel1 = new javax.swing.JPanel(); 60 jLabel1 = new javax.swing.JLabel(); 61 jScrollPane1 = new javax.swing.JScrollPane(); 62 jList1 = new javax.swing.JList<>(); 63 jScrollPane2 = new javax.swing.JScrollPane(); 64 jTextArea1 = new javax.swing.JTextArea(); 65 jTextField1 = new javax.swing.JTextField(); 66 jButton1 = new javax.swing.JButton(); 67 68 setTitle(getTitle()); 69 70 org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${name}"), this, org.jdesktop.beansbinding.BeanProperty.create("title")); 71 bindingGroup.addBinding(binding); 72 73 addWindowListener(new java.awt.event.WindowAdapter() { 74 public void windowClosing(java.awt.event.WindowEvent evt) { 75 formWindowClosing(evt); 76 } 77 }); 78 79 jLabel1.setText("成员列表"); 80 81 jList1.setModel(new javax.swing.AbstractListModel<String>() { 82 String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; 83 public int getSize() { return strings.length; } 84 public String getElementAt(int i) { return strings[i]; } 85 }); 86 jList1.addMouseListener(new java.awt.event.MouseAdapter() { 87 public void mouseClicked(java.awt.event.MouseEvent evt) { 88 jList1MouseClicked(evt); 89 } 90 }); 91 jScrollPane1.setViewportView(jList1); 92 93 javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); 94 jPanel1.setLayout(jPanel1Layout); 95 jPanel1Layout.setHorizontalGroup( 96 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 97 .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 110, Short.MAX_VALUE) 98 .addGroup(jPanel1Layout.createSequentialGroup() 99 .addComponent(jScrollPane1) 100 .addContainerGap()) 101 ); 102 jPanel1Layout.setVerticalGroup( 103 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 104 .addGroup(jPanel1Layout.createSequentialGroup() 105 .addGap(11, 11, 11) 106 .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) 107 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 108 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE)) 109 ); 110 111 jTextArea1.setEditable(false); 112 jTextArea1.setColumns(20); 113 jTextArea1.setRows(5); 114 jScrollPane2.setViewportView(jTextArea1); 115 116 jTextField1.addActionListener(new java.awt.event.ActionListener() { 117 public void actionPerformed(java.awt.event.ActionEvent evt) { 118 jTextField1ActionPerformed(evt); 119 } 120 }); 121 122 jButton1.setText("发送"); 123 jButton1.addActionListener(new java.awt.event.ActionListener() { 124 public void actionPerformed(java.awt.event.ActionEvent evt) { 125 jButton1ActionPerformed(evt); 126 } 127 }); 128 129 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 130 getContentPane().setLayout(layout); 131 layout.setHorizontalGroup( 132 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 133 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 134 .addContainerGap() 135 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) 136 .addComponent(jTextField1) 137 .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 525, Short.MAX_VALUE)) 138 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 139 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 140 .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 141 .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE))) 142 ); 143 layout.setVerticalGroup( 144 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 145 .addGroup(layout.createSequentialGroup() 146 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) 147 .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() 148 .addContainerGap() 149 .addComponent(jScrollPane2)) 150 .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 151 .addGap(18, 18, 18) 152 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 153 .addComponent(jTextField1) 154 .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 37, Short.MAX_VALUE)) 155 .addContainerGap()) 156 ); 157 158 bindingGroup.bind(); 159 160 pack(); 161 }// </editor-fold> 162 163 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 164 send(); 165 } 166 167 private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) { 168 send(); 169 } 170 171 private void formWindowClosing(java.awt.event.WindowEvent evt) { 172 String message = "用户已经下线"; 173 sendMessage(message); 174 } 175 176 private void jList1MouseClicked(java.awt.event.MouseEvent evt) { 177 send_2(); 178 } 179 180 /** 181 * @param args the command line arguments 182 */ 183 public static void main(String args[]) { 184 /* Set the Nimbus look and feel */ 185 //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 186 /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 187 * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 188 */ 189 try { 190 for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 191 if ("Nimbus".equals(info.getName())) { 192 javax.swing.UIManager.setLookAndFeel(info.getClassName()); 193 break; 194 } 195 } 196 } catch (ClassNotFoundException ex) { 197 java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 198 } catch (InstantiationException ex) { 199 java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 200 } catch (IllegalAccessException ex) { 201 java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 202 } catch (javax.swing.UnsupportedLookAndFeelException ex) { 203 java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 204 } 205 //</editor-fold> 206 //</editor-fold> 207 //</editor-fold> 208 //</editor-fold> 209 210 /* Create and display the form */ 211 java.awt.EventQueue.invokeLater(new Runnable() { 212 public void run() { 213 new Client("新用户").setVisible(true); 214 } 215 }); 216 } 217 public void send() {//发送文本输入区域的文字到服务器进行群聊 218 String message = jTextField1.getText().trim(); 219 jTextField1.setText(null); 220 if(message.equals("") || message == null) return ; 221 sendMessage(message); 222 } 223 224 public void send_2(){//发送文本输入区域的文字到服务器进行私聊 225 String choosedName=(String)this.jList1.getSelectedValue(); 226 String message = jTextField1.getText().trim(); 227 jTextField1.setText(null); 228 String temp_message = "to " + choosedName + ":" + message + "\r\n"; 229 jTextArea1.append(temp_message); 230 if(message.equals("") || message == null) return ; 231 message = "|" + choosedName + "!" + sourceName + ":" + message; 232 sendMessage(message); 233 } 234 235 public void sendMessage(String message) {//群发服务器消息 236 writer.println(message); 237 writer.flush(); 238 } 239 240 class MessageThread extends Thread{ 241 BufferedReader reader; 242 243 public MessageThread(BufferedReader reader) { 244 this.reader = reader; 245 } 246 247 @Override 248 public void run() { 249 String message = null; 250 while(true){//死循环等待接受信息的发送 251 try { 252 message = reader.readLine(); 253 if(message != null && message != ""){ 254 if(message.charAt(0) == ‘[‘){//判别接受到的消息是否是服务器发来的用户列表更新的消息 255 String[] list = message.split(", "); 256 list[0] = list[0].substring(1); 257 list[list.length-1] = list[list.length-1].substring(0, list[list.length-1].length()-1); 258 jList1.setListData(list); 259 } 260 else{ 261 message = message + "\r\n"; 262 jTextArea1.append(message); 263 } 264 } 265 } catch (Exception e) { 266 System.out.println("Error : " + e); 267 } 268 } 269 } 270 271 } 272 273 274 // Variables declaration - do not modify 275 private javax.swing.JButton jButton1; 276 private javax.swing.JLabel jLabel1; 277 private javax.swing.JList<String> jList1; 278 private javax.swing.JPanel jPanel1; 279 private javax.swing.JScrollPane jScrollPane1; 280 private javax.swing.JScrollPane jScrollPane2; 281 private javax.swing.JTextArea jTextArea1; 282 private javax.swing.JTextField jTextField1; 283 private org.jdesktop.beansbinding.BindingGroup bindingGroup; 284 // End of variables declaration 285 }
Server.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 program; 7 8 import java.awt.Toolkit; 9 import java.io.BufferedReader; 10 import java.io.InputStreamReader; 11 import java.io.PrintWriter; 12 import java.net.ServerSocket; 13 import java.net.Socket; 14 import java.util.ArrayList; 15 import java.util.Vector; 16 17 /** 18 * 19 * @author 杉琪建 20 */ 21 public class Server extends javax.swing.JFrame { 22 ServerSocket serverSocket; 23 ServerThread serverThread; 24 ArrayList<ClientThread> clients;//客户线程数组 25 Vector<String> Names = new Vector<String>();//用户列表 26 /** 27 * Creates new form Server 28 */ 29 public Server() { 30 initComponents(); 31 jList1.setListData(Names); 32 int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width; 33 int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height; 34 this.setLocation((screen_width - this.getWidth()) / 2, 35 (screen_height - this.getHeight()) / 2); 36 try { 37 clients = new ArrayList<ClientThread>(); 38 serverSocket = new ServerSocket(4705); 39 serverThread = new ServerThread(serverSocket); 40 serverThread.start(); 41 } catch (Exception e) { 42 System.out.println("Error : " + e); 43 } 44 } 45 46 /** 47 * This method is called from within the constructor to initialize the form. 48 * WARNING: Do NOT modify this code. The content of this method is always 49 * regenerated by the Form Editor. 50 */ 51 @SuppressWarnings("unchecked") 52 53 // <editor-fold defaultstate="collapsed" desc="Generated Code"> 54 private void initComponents() { 55 bindingGroup = new org.jdesktop.beansbinding.BindingGroup(); 56 57 jPanel1 = new javax.swing.JPanel(); 58 jScrollPane1 = new javax.swing.JScrollPane(); 59 jTextArea1 = new javax.swing.JTextArea(); 60 jLabel1 = new javax.swing.JLabel(); 61 jScrollPane2 = new javax.swing.JScrollPane(); 62 jList1 = new javax.swing.JList<>(); 63 jScrollBar1 = new javax.swing.JScrollBar(); 64 jTextField1 = new javax.swing.JTextField(); 65 jButton1 = new javax.swing.JButton(); 66 67 setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 68 69 org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("服务器端"), this, org.jdesktop.beansbinding.BeanProperty.create("title")); 70 bindingGroup.addBinding(binding); 71 72 jTextArea1.setEditable(false); 73 jTextArea1.setColumns(20); 74 jTextArea1.setRows(5); 75 jScrollPane1.setViewportView(jTextArea1); 76 77 jLabel1.setText("成员列表"); 78 79 jList1.setModel(jList1.getModel()); 80 jScrollPane2.setViewportView(jList1); 81 82 javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); 83 jPanel1.setLayout(jPanel1Layout); 84 jPanel1Layout.setHorizontalGroup( 85 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 86 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() 87 .addContainerGap() 88 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 432, Short.MAX_VALUE) 89 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 90 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 91 .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE) 92 .addGroup(jPanel1Layout.createSequentialGroup() 93 .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE) 94 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 95 .addComponent(jScrollBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) 96 .addContainerGap()) 97 ); 98 jPanel1Layout.setVerticalGroup( 99 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 100 .addGroup(jPanel1Layout.createSequentialGroup() 101 .addContainerGap() 102 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 103 .addComponent(jScrollPane1) 104 .addGroup(jPanel1Layout.createSequentialGroup() 105 .addComponent(jLabel1) 106 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 107 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 108 .addComponent(jScrollBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 109 .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)))) 110 .addContainerGap()) 111 ); 112 113 jTextField1.addActionListener(new java.awt.event.ActionListener() { 114 public void actionPerformed(java.awt.event.ActionEvent evt) { 115 jTextField1ActionPerformed(evt); 116 } 117 }); 118 119 jButton1.setText("发送"); 120 jButton1.addActionListener(new java.awt.event.ActionListener() { 121 public void actionPerformed(java.awt.event.ActionEvent evt) { 122 jButton1ActionPerformed(evt); 123 } 124 }); 125 126 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 127 getContentPane().setLayout(layout); 128 layout.setHorizontalGroup( 129 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 130 .addGroup(layout.createSequentialGroup() 131 .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 132 .addGap(0, 0, Short.MAX_VALUE)) 133 .addGroup(layout.createSequentialGroup() 134 .addContainerGap() 135 .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 432, javax.swing.GroupLayout.PREFERRED_SIZE) 136 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 137 .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE) 138 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 139 ); 140 layout.setVerticalGroup( 141 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 142 .addGroup(layout.createSequentialGroup() 143 .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 144 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 145 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 146 .addComponent(jTextField1) 147 .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 49, Short.MAX_VALUE)) 148 .addContainerGap()) 149 ); 150 151 bindingGroup.bind(); 152 153 pack(); 154 }// </editor-fold> 155 156 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 157 // TODO add your handling code here: 158 send(); 159 } 160 161 private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) { 162 // TODO add your handling code here: 163 send(); 164 } 165 166 /** 167 * @param args the command line arguments 168 */ 169 public static void main(String args[]) { 170 /* Set the Nimbus look and feel */ 171 //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 172 /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 173 * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 174 */ 175 try { 176 for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 177 if ("Nimbus".equals(info.getName())) { 178 javax.swing.UIManager.setLookAndFeel(info.getClassName()); 179 break; 180 } 181 } 182 } catch (ClassNotFoundException ex) { 183 java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 184 } catch (InstantiationException ex) { 185 java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 186 } catch (IllegalAccessException ex) { 187 java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 188 } catch (javax.swing.UnsupportedLookAndFeelException ex) { 189 java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 190 } 191 //</editor-fold> 192 //</editor-fold> 193 //</editor-fold> 194 //</editor-fold> 195 196 /* Create and display the form */ 197 java.awt.EventQueue.invokeLater(new Runnable() { 198 public void run() { 199 new Server().setVisible(true); 200 } 201 }); 202 } 203 204 205 class ClientThread extends Thread{ 206 Socket socket; 207 BufferedReader reader; 208 PrintWriter writer; 209 int num; 210 /** 211 * 212 * @param socket 连接的端口 213 * @param num 客户号码 214 */ 215 public ClientThread(Socket socket, int num) { 216 try { 217 this.socket = socket; 218 this.num = num; 219 reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 220 writer = new PrintWriter(socket.getOutputStream()); 221 String inf = reader.readLine(); 222 sendMessage(inf + "已经上线"); 223 Names.add(inf); 224 } catch (Exception e) { 225 System.out.println("Error : " + e); 226 } 227 } 228 229 @Override 230 public void run() { 231 String message = null; 232 while(true) { 233 try { 234 message = reader.readLine(); 235 if(message.charAt(0) == ‘|‘){//识别是否是客户端发送的私聊信息 236 message = message.substring(1, message.length()); 237 String[] list = message.split("!"); 238 send_2(list[0], list[1]); 239 } 240 else{ 241 String message1 = Names.get(this.num-1) + ":" + message; 242 sendMessage(message1); 243 if(message.equals("用户已经下线")){ 244 reader.close(); 245 writer.close(); 246 socket.close(); 247 ClientThread temp = clients.get(num - 1); 248 Names.remove(num-1); 249 UpdatejList1(); 250 clients.remove(num - 1); 251 temp.stop(); 252 return ; 253 } 254 } 255 256 } catch (Exception e) { 257 System.out.println("Error1 : " + e); 258 } 259 } 260 } 261 } 262 263 class ServerThread extends Thread{//服务器线程 264 ServerSocket serverSocket; 265 public ServerThread(ServerSocket serverSocket) { 266 this.serverSocket = serverSocket; 267 } 268 @Override 269 public void run() { 270 int num = 1; 271 while(true) {//死循环等待新客户端的连接 272 try { 273 Socket socket = serverSocket.accept(); 274 ClientThread client = new ClientThread(socket, num++); 275 client.start(); 276 clients.add(client); 277 UpdatejList1(); 278 } catch (Exception e) { 279 System.out.println("Error :" + e); 280 } 281 } 282 } 283 } 284 285 public void send() {//发送文本框中的消息 286 String message = jTextField1.getText().trim(); 287 message = "服务器 :" + message; 288 jTextArea1.append(message + "\r\n"); 289 jTextField1.setText(null); 290 sendServerMessage(message);// 群发服务器消息 291 } 292 293 public void send_2(String name, String message){ 294 for(int i = 0; i <clients.size(); i++){ 295 if(Names.get(i).equals(name)){ 296 clients.get(i).writer.println(message); 297 clients.get(i).writer.flush(); 298 } 299 } 300 } 301 /** 302 * 303 * @param message 要发送的消息 304 */ 305 public void sendMessage(String message) {//发送message消息 306 jTextArea1.append(message + "\r\n"); 307 sendServerMessage(message);// 群发服务器消息 308 } 309 public void sendServerMessage(String message) {//发送服务器信息 310 //message =message + "\r\n"; 311 for(int i = 0; i < clients.size(); i++) { 312 clients.get(i).writer.println(message); 313 clients.get(i).writer.flush(); 314 } 315 } 316 public void UpdatejList1(){//更新所有客户端的用户列表 317 jList1.setListData(Names); 318 for(int i = 0; i < clients.size(); i++) { 319 clients.get(i).writer.println(Names); 320 clients.get(i).writer.flush(); 321 } 322 } 323 324 // Variables declaration - do not modify 325 private javax.swing.JButton jButton1; 326 private javax.swing.JLabel jLabel1; 327 private javax.swing.JList<String> jList1; 328 private javax.swing.JPanel jPanel1; 329 private javax.swing.JScrollBar jScrollBar1; 330 private javax.swing.JScrollPane jScrollPane1; 331 private javax.swing.JScrollPane jScrollPane2; 332 private javax.swing.JTextArea jTextArea1; 333 private javax.swing.JTextField jTextField1; 334 private org.jdesktop.beansbinding.BindingGroup bindingGroup; 335 // End of variables declaration 336 }