1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.example.chat.client;
21
22 import java.awt.BorderLayout;
23 import java.awt.Dimension;
24 import java.awt.event.ActionEvent;
25 import java.awt.event.ActionListener;
26 import java.net.InetSocketAddress;
27 import java.net.SocketAddress;
28
29 import javax.swing.AbstractAction;
30 import javax.swing.BorderFactory;
31 import javax.swing.Box;
32 import javax.swing.BoxLayout;
33 import javax.swing.JButton;
34 import javax.swing.JFrame;
35 import javax.swing.JLabel;
36 import javax.swing.JOptionPane;
37 import javax.swing.JPanel;
38 import javax.swing.JScrollBar;
39 import javax.swing.JTextArea;
40 import javax.swing.JTextField;
41 import javax.swing.border.EmptyBorder;
42
43 import org.apache.mina.example.chat.client.SwingChatClientHandler.Callback;
44 import org.apache.mina.transport.socket.nio.NioSocketConnector;
45
46
47
48
49
50
51 public class SwingChatClient extends JFrame implements Callback {
52 private static final long serialVersionUID = 1538675161745436968L;
53
54 private JTextField inputText;
55
56 private JButton loginButton;
57
58 private JButton quitButton;
59
60 private JButton closeButton;
61
62 private JTextField serverField;
63
64 private JTextField nameField;
65
66 private JTextArea area;
67
68 private JScrollBar scroll;
69
70 private ChatClientSupport client;
71
72 private SwingChatClientHandler handler;
73
74 private NioSocketConnector connector;
75
76 public SwingChatClient() {
77 super("Chat Client based on Apache MINA");
78
79 connector = new NioSocketConnector();
80
81 loginButton = new JButton(new LoginAction());
82 loginButton.setText("Connect");
83 quitButton = new JButton(new LogoutAction());
84 quitButton.setText("Disconnect");
85 closeButton = new JButton(new QuitAction());
86 closeButton.setText("Quit");
87 inputText = new JTextField(30);
88 inputText.setAction(new BroadcastAction());
89 area = new JTextArea(10, 50);
90 area.setLineWrap(true);
91 area.setEditable(false);
92 scroll = new JScrollBar();
93 scroll.add(area);
94 nameField = new JTextField(10);
95 nameField.setEditable(false);
96 serverField = new JTextField(10);
97 serverField.setEditable(false);
98
99 JPanel h = new JPanel();
100 h.setLayout(new BoxLayout(h, BoxLayout.LINE_AXIS));
101 h.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
102 JLabel nameLabel = new JLabel("Name: ");
103 JLabel serverLabel = new JLabel("Server: ");
104 h.add(nameLabel);
105 h.add(Box.createRigidArea(new Dimension(10, 0)));
106 h.add(nameField);
107 h.add(Box.createRigidArea(new Dimension(10, 0)));
108 h.add(Box.createHorizontalGlue());
109 h.add(Box.createRigidArea(new Dimension(10, 0)));
110 h.add(serverLabel);
111 h.add(Box.createRigidArea(new Dimension(10, 0)));
112 h.add(serverField);
113
114 JPanel p = new JPanel();
115 p.setLayout(new BoxLayout(p, BoxLayout.LINE_AXIS));
116 p.setBorder(new EmptyBorder(10, 10, 10, 10));
117
118 JPanel left = new JPanel();
119 left.setLayout(new BoxLayout(left, BoxLayout.PAGE_AXIS));
120 left.add(area);
121 left.add(Box.createRigidArea(new Dimension(0, 5)));
122 left.add(Box.createHorizontalGlue());
123 left.add(inputText);
124
125 JPanel right = new JPanel();
126 right.setLayout(new BoxLayout(right, BoxLayout.PAGE_AXIS));
127 right.add(loginButton);
128 right.add(Box.createRigidArea(new Dimension(0, 5)));
129 right.add(quitButton);
130 right.add(Box.createHorizontalGlue());
131 right.add(Box.createRigidArea(new Dimension(0, 25)));
132 right.add(closeButton);
133
134 p.add(left);
135 p.add(Box.createRigidArea(new Dimension(10, 0)));
136 p.add(right);
137
138 getContentPane().add(h, BorderLayout.NORTH);
139 getContentPane().add(p);
140
141 closeButton.addActionListener(new ActionListener() {
142 public void actionPerformed(ActionEvent e) {
143 client.quit();
144 connector.dispose();
145 dispose();
146 }
147 });
148 setLoggedOut();
149 setDefaultCloseOperation(EXIT_ON_CLOSE);
150 }
151
152 public class LoginAction extends AbstractAction {
153 private static final long serialVersionUID = 3596719854773863244L;
154
155 public void actionPerformed(ActionEvent e) {
156
157 ConnectDialog dialog = new ConnectDialog(SwingChatClient.this);
158 dialog.pack();
159 dialog.setVisible(true);
160
161 if (dialog.isCancelled()) {
162 return;
163 }
164
165 SocketAddress address = parseSocketAddress(dialog
166 .getServerAddress());
167 String name = dialog.getUsername();
168
169 handler = new SwingChatClientHandler(SwingChatClient.this);
170 client = new ChatClientSupport(name, handler);
171 nameField.setText(name);
172 serverField.setText(dialog.getServerAddress());
173
174 if (!client.connect(connector, address, dialog.isUseSsl())) {
175 JOptionPane.showMessageDialog(SwingChatClient.this,
176 "Could not connect to " + dialog.getServerAddress()
177 + ". ");
178 }
179 }
180 }
181
182 private class LogoutAction extends AbstractAction {
183 private static final long serialVersionUID = 1655297424639924560L;
184
185 public void actionPerformed(ActionEvent e) {
186 try {
187 client.quit();
188 setLoggedOut();
189 } catch (Exception e1) {
190 JOptionPane.showMessageDialog(SwingChatClient.this,
191 "Session could not be closed.");
192 }
193 }
194 }
195
196 private class BroadcastAction extends AbstractAction {
197
198
199
200 private static final long serialVersionUID = -6276019615521905411L;
201
202 public void actionPerformed(ActionEvent e) {
203 client.broadcast(inputText.getText());
204 inputText.setText("");
205 }
206 }
207
208 private class QuitAction extends AbstractAction {
209 private static final long serialVersionUID = -6389802816912005370L;
210
211 public void actionPerformed(ActionEvent e) {
212 if (client != null) {
213 client.quit();
214 }
215 SwingChatClient.this.dispose();
216 }
217 }
218
219 private void setLoggedOut() {
220 inputText.setEnabled(false);
221 quitButton.setEnabled(false);
222 loginButton.setEnabled(true);
223 }
224
225 private void setLoggedIn() {
226 area.setText("");
227 inputText.setEnabled(true);
228 quitButton.setEnabled(true);
229 loginButton.setEnabled(false);
230 }
231
232 private void append(String text) {
233 area.append(text);
234 }
235
236 private void notifyError(String message) {
237 JOptionPane.showMessageDialog(this, message);
238 }
239
240 private SocketAddress parseSocketAddress(String s) {
241 s = s.trim();
242 int colonIndex = s.indexOf(":");
243 if (colonIndex > 0) {
244 String host = s.substring(0, colonIndex);
245 int port = parsePort(s.substring(colonIndex + 1));
246 return new InetSocketAddress(host, port);
247 } else {
248 int port = parsePort(s.substring(colonIndex + 1));
249 return new InetSocketAddress(port);
250 }
251 }
252
253 private int parsePort(String s) {
254 try {
255 return Integer.parseInt(s);
256 } catch (NumberFormatException nfe) {
257 throw new IllegalArgumentException("Illegal port number: " + s);
258 }
259 }
260
261 public void connected() {
262
263 }
264
265 public void disconnected() {
266 append("Connection closed.\n");
267 setLoggedOut();
268 }
269
270 public void error(String message) {
271 notifyError(message + "\n");
272 }
273
274 public void loggedIn() {
275 setLoggedIn();
276 append("You have joined the chat session.\n");
277 }
278
279 public void loggedOut() {
280 append("You have left the chat session.\n");
281 setLoggedOut();
282 }
283
284 public void messageReceived(String message) {
285 append(message + "\n");
286 }
287
288 public static void main(String[] args) {
289 SwingChatClient client = new SwingChatClient();
290 client.pack();
291 client.setVisible(true);
292 }
293 }