本文實例為大家分享了java聊天室代碼,供大家參考,具體內容如下
主要涉及知識
·Java中GUI程序的編寫,包括事件監聽機制。
·Java的網絡通信編程,ServerSocket,Socket類的使用。
·Java中多線程的編程,Thread類,Runnable接口的使用。
源代碼
客戶端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
package project1; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import javax.swing.*; public class Client { private JFrame clientFrame; private JLabel IPLabel; private JLabel PortLabel; private JLabel sayLabel; private JLabel nicknameLabel; private JTextField IPText; private JTextField PortText; private JTextField nicknameText; private JTextField sayText; private JButton connectButton; private JButton nicknameButton; private JButton sayButton; private JPanel jPanelNorth; private JPanel jPanelSouth0; private JPanel jPanelSouth1; private JPanel jPanelSouth2; private JTextArea clientTextArea; private JScrollPane scroller; private BufferedReader reader; private PrintWriter writer; private String nickname; public static void main(String args[]) { Client aClient = new Client(); aClient.startUp(); } // 初始化組件 public Client() { nickname = "客戶端" ; clientFrame = new JFrame(); jPanelNorth = new JPanel(); IPLabel = new JLabel( "服務器IP" , JLabel.LEFT); IPText = new JTextField( 10 ); PortLabel = new JLabel( "服務器端口" , JLabel.LEFT); PortText = new JTextField( 10 ); connectButton = new JButton( "連接" ); clientTextArea = new JTextArea(); scroller = new JScrollPane(clientTextArea); jPanelSouth0 = new JPanel(); jPanelSouth1 = new JPanel(); jPanelSouth2 = new JPanel(); nicknameLabel = new JLabel( "昵稱" , JLabel.LEFT); nicknameText = new JTextField(nickname, 30 ); nicknameButton = new JButton( "確認" ); sayLabel = new JLabel( "消息" , JLabel.LEFT); sayText = new JTextField( 30 ); sayButton = new JButton( "確認" ); } // 構建GUI private void buildGUI() { // 窗口的設置 clientFrame.setTitle( "客戶端" ); clientFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); clientFrame.setSize( 550 , 550 ); // 北區的組件 jPanelNorth.add(IPLabel); jPanelNorth.add(IPText); jPanelNorth.add(PortLabel); jPanelNorth.add(PortText); jPanelNorth.add(connectButton); clientFrame.getContentPane().add(BorderLayout.NORTH, jPanelNorth); // 中間的組件 clientTextArea.setFocusable( false ); scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); clientFrame.getContentPane().add(BorderLayout.CENTER, scroller); // 南區的組件 jPanelSouth1.add(nicknameLabel); jPanelSouth1.add(nicknameText); jPanelSouth1.add(nicknameButton); jPanelSouth2.add(sayLabel); jPanelSouth2.add(sayText); jPanelSouth2.add(sayButton); jPanelSouth0.setLayout( new BoxLayout(jPanelSouth0, BoxLayout.Y_AXIS)); jPanelSouth0.add(jPanelSouth1); jPanelSouth0.add(jPanelSouth2); clientFrame.getContentPane().add(BorderLayout.SOUTH, jPanelSouth0); // 設置窗口可見 clientFrame.setVisible( true ); } // 客戶端運行 public void startUp() { buildGUI(); // 接收服務器消息的線程 Runnable incomingReader = new Runnable() { @Override public void run() { String message; try { while ((message = reader.readLine()) != null ) { clientTextArea.append(message + "\n" ); } } catch (Exception ex) { ex.printStackTrace(); } } }; // 監聽Connect按鈕,實現服務器的連接 connectButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String aServerIP = IPText.getText(); String aServerPort = PortText.getText(); if (aServerIP.equals( "" ) || aServerPort.equals( "" )) { JOptionPane.showMessageDialog(clientFrame, "請輸入 完整的 IP和端口!" ); } else { try { @SuppressWarnings ( "resource" ) Socket clientSocket = new Socket(aServerIP, Integer.parseInt(aServerPort)); InputStreamReader streamReader = new InputStreamReader(clientSocket.getInputStream()); reader = new BufferedReader(streamReader); writer = new PrintWriter(clientSocket.getOutputStream()); clientTextArea.append( "服務器已連接...\n" ); Thread readerThread = new Thread(incomingReader); readerThread.start(); } catch (Exception ex) { JOptionPane.showMessageDialog(clientFrame, "連接不上服務器!\n請確認 IP 和 端口 輸入正確。" ); } } } }); // 監聽nickname,設置昵稱 ActionListener nicknameListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String aText = nicknameText.getText(); if (!aText.equals( "" )) { nickname = aText; } } }; nicknameButton.addActionListener(nicknameListener); nicknameText.addActionListener(nicknameListener); nicknameText.addFocusListener( new FocusListener() { @Override public void focusGained(FocusEvent e) { } @Override public void focusLost(FocusEvent e) { String aText = nicknameText.getText(); if (!aText.equals( "" )) { nickname = aText; } } }); // 發送消息到服務器 ActionListener SayListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String aText = sayText.getText(); if (aText.equals( "" )) { JOptionPane.showMessageDialog(clientFrame, "內容不能為空!" ); } else { try { writer.println(nickname + ":" + aText); writer.flush(); } catch (Exception ex) { ex.printStackTrace(); } sayText.setText( "" ); } } }; sayButton.addActionListener(SayListener); sayText.addActionListener(SayListener); } } |
服務器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
package project1; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.ArrayList; import java.util.Iterator; import javax.swing.*; public class Server { private JFrame serverFrame; private JLabel portLabel; private JLabel sayLabel; private JLabel nicknameLabel; private JTextField portText; private JTextField sayText; private JTextField nicknameText; private JButton startButton; private JButton sayButton; private JButton nicknameButton; private JPanel jPanelNorth; private JPanel jPanelSouth0; private JPanel jPanelSouth1; private JPanel jPanelSouth2; private JScrollPane scroller; private JTextArea serverTextArea; private ArrayList<PrintWriter> clientOutputStreams; private String nickname; public static void main(String[] args) { Server aServer = new Server(); aServer.startUp(); } // 初始化組件 public Server() { nickname = "服務器" ; serverFrame = new JFrame(); jPanelNorth = new JPanel(); portLabel = new JLabel( "端口" , JLabel.LEFT); portText = new JTextField( 30 ); startButton = new JButton( "開始" ); serverTextArea = new JTextArea(); scroller = new JScrollPane(serverTextArea); nicknameLabel = new JLabel( "昵稱" , JLabel.LEFT); nicknameText = new JTextField(nickname, 30 ); nicknameButton = new JButton( "確認" ); jPanelSouth0 = new JPanel(); jPanelSouth1 = new JPanel(); jPanelSouth2 = new JPanel(); sayLabel = new JLabel( "消息" , JLabel.LEFT); sayText = new JTextField( 30 ); sayButton = new JButton( "確認" ); } // 構建GUI private void buildGUI() { // 窗口的設置 serverFrame.setTitle( "服務器" ); serverFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); serverFrame.setSize( 550 , 550 ); // 北區的組件 jPanelNorth.add(portLabel); jPanelNorth.add(portText); jPanelNorth.add(startButton); serverFrame.getContentPane().add(BorderLayout.NORTH, jPanelNorth); // 中間的組件 serverTextArea.setFocusable( false ); scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); serverFrame.getContentPane().add(BorderLayout.CENTER, scroller); // 南區的組件 jPanelSouth1.add(nicknameLabel); jPanelSouth1.add(nicknameText); jPanelSouth1.add(nicknameButton); jPanelSouth2.add(sayLabel); jPanelSouth2.add(sayText); jPanelSouth2.add(sayButton); jPanelSouth0.setLayout( new BoxLayout(jPanelSouth0, BoxLayout.Y_AXIS)); jPanelSouth0.add(jPanelSouth1); jPanelSouth0.add(jPanelSouth2); serverFrame.getContentPane().add(BorderLayout.SOUTH, jPanelSouth0); // 設置窗口可見 serverFrame.setVisible( true ); } // 服務器運行 public void startUp() { buildGUI(); // 監聽Start按鈕,建立端口 ActionListener startListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { clientOutputStreams = new ArrayList<PrintWriter>(); String aPort = portText.getText(); if (aPort.equals( "" )) { JOptionPane.showMessageDialog(serverFrame, "請輸入正確的端口號!" ); } else { try { // 等待客戶端連接的線程 Runnable serverRunnable = new Runnable() { @Override public void run() { ServerSocket serverSocket; try { serverSocket = new ServerSocket(Integer.parseInt(aPort)); serverTextArea.append( "正在等待客戶端連接...\n" ); while ( true ) { Socket clientSocket = serverSocket.accept(); serverTextArea.append( "客戶端已連接...\n" ); PrintWriter writer = new PrintWriter(clientSocket.getOutputStream()); clientOutputStreams.add(writer); Thread t = new Thread( new ClientHandler(clientSocket)); t.start(); } } catch (NumberFormatException | IOException e) { e.printStackTrace(); } } }; Thread serverThread = new Thread(serverRunnable); serverThread.start(); } catch (Exception ex) { ex.printStackTrace(); } } } }; startButton.addActionListener(startListener); portText.addActionListener(startListener); // 監聽nickname,設置昵稱 ActionListener nicknameListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String aText = nicknameText.getText(); if (!aText.equals( "" )) { nickname = aText; } } }; nicknameButton.addActionListener(nicknameListener); nicknameText.addActionListener(nicknameListener); nicknameText.addFocusListener( new FocusListener() { @Override public void focusGained(FocusEvent e) { } @Override public void focusLost(FocusEvent e) { String aText = nicknameText.getText(); if (!aText.equals( "" )) { nickname = aText; } } }); // 監聽Say按鈕,發送消息 ActionListener SayListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String aText = sayText.getText(); if (!aText.equals( "" )) { aText = nickname + ":" + aText; sendToEveryClient(aText); serverTextArea.append(aText + "\n" ); sayText.setText( "" ); } else { JOptionPane.showMessageDialog(serverFrame, "內容不能為空!" ); } } }; sayButton.addActionListener(SayListener); sayText.addActionListener(SayListener); } // 多客戶端的線程 public class ClientHandler implements Runnable { BufferedReader bReader; Socket aSocket; public ClientHandler(Socket clientSocket) { try { aSocket = clientSocket; InputStreamReader isReader = new InputStreamReader(aSocket.getInputStream()); bReader = new BufferedReader(isReader); } catch (Exception ex) { ex.printStackTrace(); } } @Override public void run() { String message; try { while ((message = bReader.readLine()) != null ) { sendToEveryClient(message); serverTextArea.append(message + "\n" ); } } catch (Exception ex) { ex.printStackTrace(); } } } // 發送消息給所有客戶端的方法 private void sendToEveryClient(String message) { Iterator<PrintWriter> it = clientOutputStreams.iterator(); while (it.hasNext()) { try { PrintWriter writer = (PrintWriter) it.next(); writer.println(message); writer.flush(); } catch (Exception ex) { ex.printStackTrace(); } } } } |
GUI運行截圖:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。