001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.mina.example.chat.client; 021 022import java.awt.BorderLayout; 023import java.awt.Dimension; 024import java.awt.event.ActionEvent; 025import java.awt.event.ActionListener; 026import java.net.InetSocketAddress; 027import java.net.SocketAddress; 028 029import javax.swing.AbstractAction; 030import javax.swing.BorderFactory; 031import javax.swing.Box; 032import javax.swing.BoxLayout; 033import javax.swing.JButton; 034import javax.swing.JFrame; 035import javax.swing.JLabel; 036import javax.swing.JOptionPane; 037import javax.swing.JPanel; 038import javax.swing.JScrollBar; 039import javax.swing.JTextArea; 040import javax.swing.JTextField; 041import javax.swing.border.EmptyBorder; 042 043import org.apache.mina.example.chat.client.SwingChatClientHandler.Callback; 044import org.apache.mina.transport.socket.nio.NioSocketConnector; 045 046/** 047 * Simple chat client based on Swing & MINA that implements the chat protocol. 048 * 049 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 050 */ 051public class SwingChatClient extends JFrame implements Callback { 052 private static final long serialVersionUID = 1538675161745436968L; 053 054 private JTextField inputText; 055 056 private JButton loginButton; 057 058 private JButton quitButton; 059 060 private JButton closeButton; 061 062 private JTextField serverField; 063 064 private JTextField nameField; 065 066 private JTextArea area; 067 068 private JScrollBar scroll; 069 070 private ChatClientSupport client; 071 072 private SwingChatClientHandler handler; 073 074 private NioSocketConnector connector; 075 076 public SwingChatClient() { 077 super("Chat Client based on Apache MINA"); 078 079 connector = new NioSocketConnector(); 080 081 loginButton = new JButton(new LoginAction()); 082 loginButton.setText("Connect"); 083 quitButton = new JButton(new LogoutAction()); 084 quitButton.setText("Disconnect"); 085 closeButton = new JButton(new QuitAction()); 086 closeButton.setText("Quit"); 087 inputText = new JTextField(30); 088 inputText.setAction(new BroadcastAction()); 089 area = new JTextArea(10, 50); 090 area.setLineWrap(true); 091 area.setEditable(false); 092 scroll = new JScrollBar(); 093 scroll.add(area); 094 nameField = new JTextField(10); 095 nameField.setEditable(false); 096 serverField = new JTextField(10); 097 serverField.setEditable(false); 098 099 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 public void disconnected() { 265 append("Connection closed.\n"); 266 setLoggedOut(); 267 } 268 269 public void error(String message) { 270 notifyError(message + "\n"); 271 } 272 273 public void loggedIn() { 274 setLoggedIn(); 275 append("You have joined the chat session.\n"); 276 } 277 278 public void loggedOut() { 279 append("You have left the chat session.\n"); 280 setLoggedOut(); 281 } 282 283 public void messageReceived(String message) { 284 append(message + "\n"); 285 } 286 287 public static void main(String[] args) { 288 SwingChatClient client = new SwingChatClient(); 289 client.pack(); 290 client.setVisible(true); 291 } 292}