Go to the documentation of this file.00001
00002 import java.awt.Color;
00003 import java.awt.Dimension;
00004 import java.awt.Font;
00005 import java.awt.Toolkit;
00006 import java.awt.event.ActionEvent;
00007 import java.awt.event.ActionListener;
00008 import java.awt.event.KeyEvent;
00009 import java.awt.event.KeyListener;
00010 import java.awt.event.MouseAdapter;
00011 import java.awt.event.MouseEvent;
00012
00013 import javax.swing.GroupLayout;
00014 import javax.swing.JButton;
00015 import javax.swing.JEditorPane;
00016 import javax.swing.JFrame;
00017 import javax.swing.JLabel;
00018 import javax.swing.JScrollPane;
00019 import javax.swing.JTextField;
00020 import javax.swing.Timer;
00021 import javax.swing.WindowConstants;
00022
00023
00024
00025
00026
00027
00028 public class ChatClientFrame extends JFrame
00029 implements ActionListener, KeyListener, ChatClient.Context
00030 {
00031
00032
00033
00034 private static final long serialVersionUID = 7406765627069159382L;
00035
00036
00037
00038
00039 private static final String defaultInputMsg = "<type message here>";
00040
00041
00042
00043
00044 private String host = "127.0.0.1";
00045
00046
00047
00048
00049 private int port = 2000;
00050
00051
00052
00053
00054 private ChatClient connection;
00055
00056
00057
00058
00059 private int reconnectTimeout = -1;
00060
00061
00062
00063
00064 private int reconnectRetryCount = 0;
00065
00066
00067
00068 private JButton sendButton;
00069 private JTextField inputMsg;
00070 private JLabel idLabel;
00071 private JTextField userId;
00072 private JEditorPane logArea;
00073
00074
00075
00076
00077
00078
00079 public ChatClientFrame( String args[] )
00080 {
00081 super( "IP1-4.1.1: Yet Another Simple Chat Client" );
00082
00083 setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
00084
00085
00086
00087
00088
00089 Font textFont = new Font( Font.SANS_SERIF, Font.PLAIN, 14 );
00090
00091 inputMsg = new JTextField( defaultInputMsg, 30 );
00092 inputMsg.addKeyListener( this );
00093 inputMsg.setFont( textFont );
00094 inputMsg.selectAll ();
00095
00096 sendButton = new JButton ();
00097 sendButton.setText( "Send" );
00098
00099 sendButton.addMouseListener(
00100 new MouseAdapter () {
00101 public void mouseClicked( MouseEvent evt ) {
00102 sendButton_Clicked( evt );
00103 }
00104 }
00105 );
00106
00107 idLabel = new JLabel( "My ID:" );
00108 idLabel.setFont( textFont );
00109
00110 userId = new JTextField( System.getProperty( "user.name" ) );
00111 userId.addKeyListener( this );
00112 userId.setFont( textFont );
00113
00114 logArea = new JEditorPane ();
00115 logArea.setFont( textFont );
00116 logArea.setBackground( new Color( 255, 255, 224 ) );
00117 logArea.setForeground( Color.BLACK );
00118 logArea.setEditable( false );
00119
00120 logArea.setContentType( "text/html" );
00121 logArea.setText( "<html><head></head><body>\n</body></html>" );
00122
00123 JScrollPane logPane = new JScrollPane ();
00124 logPane.setViewportView( logArea );
00125
00126
00127
00128
00129
00130
00131
00132 GroupLayout layout = new GroupLayout( getContentPane () );
00133 getContentPane().setLayout( layout );
00134 layout.setAutoCreateContainerGaps( true );
00135 layout.setAutoCreateGaps( true );
00136
00137 layout.setHorizontalGroup
00138 (
00139 layout
00140 .createParallelGroup( GroupLayout.Alignment.LEADING )
00141 .addGroup
00142 (
00143 layout
00144 .createSequentialGroup ()
00145 .addGroup
00146 (
00147 layout
00148 .createParallelGroup( GroupLayout.Alignment.LEADING )
00149 .addGroup
00150 (
00151 GroupLayout.Alignment.TRAILING,
00152 layout
00153 .createSequentialGroup ()
00154 .addComponent( sendButton )
00155 .addComponent( inputMsg )
00156 .addComponent( idLabel )
00157 .addComponent( userId )
00158 )
00159 .addComponent( logPane )
00160 )
00161 )
00162 );
00163
00164 layout.setVerticalGroup
00165 (
00166 layout
00167 .createParallelGroup( GroupLayout.Alignment.LEADING )
00168 .addGroup
00169 (
00170 layout
00171 .createSequentialGroup ()
00172 .addGroup
00173 (
00174 layout
00175 .createParallelGroup( GroupLayout.Alignment.BASELINE )
00176 .addComponent( sendButton )
00177 .addComponent( inputMsg )
00178 .addComponent( idLabel )
00179 .addComponent( userId )
00180 )
00181 .addComponent( logPane )
00182 )
00183 );
00184
00185 pack();
00186
00187
00188
00189
00190
00191 Dimension win = new Dimension( 1024, 600 );
00192 Dimension scsz = Toolkit.getDefaultToolkit().getScreenSize();
00193 win.width = Math.min( win.width, scsz.width );
00194 win.height = Math.min( win.height, scsz.height - 40 );
00195 setSize( win );
00196
00197
00198
00199 setLocation( ( scsz.width - win.width )/2, ( scsz.height - 40 - win.height )/2 );
00200
00201
00202
00203 if ( args.length >= 1 )
00204 {
00205 host = args[ 0 ];
00206 if( args.length >= 2 ) try {
00207 port = Integer.parseInt( args[ 1 ] );
00208 } catch ( NumberFormatException e ) {
00209
00210 }
00211 }
00212
00213
00214
00215 logMessage( "<table border='0' cellspacing='2' align='right' color='#0000FF'>"
00216 + "<td><b>Usage:</b> </td>\n"
00217 + "<td><table border='0' cellspacing='0' bgcolor='#E0F0E0'>"
00218 + "<tr><td><code>:open [ <hostname> [ <port> ] ]</code></td>"
00219 + "<td><code><em>-- open new connection</em></code></td></tr>\n"
00220 + "<tr><td><code>:close</code></td>"
00221 + "<td><code><em>-- close current connection</em></code></td></tr>\n"
00222 + "<tr><td><code>:exit</code></td>"
00223 + "<td><code><em>-- quit application</em></code></td></tr>\n"
00224 + "<tr><td><code>:who</code></td>"
00225 + "<td><code><em>-- send 'wwhhoo' to chat server</em></code></td></tr>\n"
00226 + "</table>"
00227 + "</td></tr></table>"
00228 );
00229
00230
00231
00232 connection = new ChatClient( host, port, this );
00233 connection.start ();
00234
00235
00236
00237 Timer timer = new Timer( 1000, this );
00238 timer.start ();
00239
00240
00241
00242 inputMsg.selectAll ();
00243 inputMsg.requestFocus ();
00244 }
00245
00246
00247
00248
00249 private void sendButton_Clicked( MouseEvent evt )
00250 {
00251 parseInputMessage ();
00252 }
00253
00254
00255
00256
00257
00258
00259 @Override
00260 public void logMessage( String str )
00261 {
00262 final String strCopy = new String( str );
00263
00264 java.awt.EventQueue.invokeLater(
00265 new Runnable() {
00266 public void run() {
00267 synchronized( logArea )
00268 {
00269
00270
00271 String html = logArea.getText ();
00272 html = html.replace( "</body>", strCopy + "\n</body>" );
00273 logArea.setText( html );
00274 }
00275 }
00276 }
00277 );
00278 }
00279
00280
00281
00282
00283
00284
00285 @Override
00286 public void logStatus( String str )
00287 {
00288 final String strCopy = new String( str );
00289
00290 java.awt.EventQueue.invokeLater(
00291 new Runnable() {
00292 public void run() {
00293 setTitle( "IP1-4.1.1 Chat Client: " + strCopy );
00294 }
00295 }
00296 );
00297 }
00298
00299
00300
00301
00302
00303
00304 public void actionPerformed( ActionEvent ae )
00305 {
00306 final int maxRetryCount = 3;
00307 final int reconnectDelay = 2;
00308
00309 if ( connection.isAlive () ) {
00310 reconnectTimeout = -1;
00311 return;
00312 }
00313
00314 if ( reconnectRetryCount >= maxRetryCount ) {
00315
00316 if ( reconnectRetryCount == maxRetryCount ) {
00317
00318 ++reconnectRetryCount;
00319
00320 logMessage( "<br/><code>Press ENTER to quit or type<br/><br/>"
00321 + " :open [ <hostname> [ <port> ] ]<br/><br/>"
00322 + "to open new connection...</code><br/><br/>"
00323 );
00324 logStatus( "Dead" );
00325 }
00326
00327 return;
00328 }
00329
00330 if ( reconnectTimeout < 0 ) {
00331 logStatus( "Disconnected" );
00332 logMessage( "<br/><code>Reconnecting in "
00333 + reconnectDelay + " seconds...</code>"
00334 );
00335 reconnectTimeout = reconnectDelay;
00336 return;
00337 }
00338
00339 if ( --reconnectTimeout > 0 ) {
00340 return;
00341 }
00342
00343 logMessage( "<code>retry #"
00344 + ( ++reconnectRetryCount )
00345 + " of max "
00346 + maxRetryCount
00347 + ":</code><br/>"
00348 );
00349
00350 reconnectTimeout = -1;
00351
00352 connection = new ChatClient( host, port , this );
00353 connection.start ();
00354 }
00355
00356
00357
00358
00359 public void keyPressed( KeyEvent ke ) {
00360
00361 int keyCode = ke.getKeyCode ();
00362
00363 if( keyCode == KeyEvent.VK_ENTER )
00364 {
00365 parseInputMessage ();
00366 }
00367 }
00368
00369
00370
00371
00372
00373 public void parseInputMessage ()
00374 {
00375
00376
00377
00378 String[] args = inputMsg.getText().trim().split( "\\s{1,}" );
00379
00380 String cmd = args.length > 0 ? args[0] : "";
00381
00382 if ( cmd.equalsIgnoreCase( ":who" ) ) {
00383 inputMsg.setText( "" );
00384 connection.send( "wwhhoo" );
00385 return;
00386 }
00387 else if ( cmd.equalsIgnoreCase( ":close" ) ) {
00388 inputMsg.setText( "" );
00389 reconnectRetryCount = Integer.MAX_VALUE;
00390 connection.close ();
00391 return;
00392 }
00393 else if ( cmd.equalsIgnoreCase( ":open" ) ) {
00394 inputMsg.setText( "" );
00395 reconnectRetryCount = Integer.MAX_VALUE;
00396 connection.close ();
00397
00398 if ( args.length >= 2 )
00399 {
00400 host = args[ 1 ];
00401 port = 2000;
00402 if( args.length >= 3 ) try {
00403 port = Integer.parseInt( args[ 2 ] );
00404 } catch ( NumberFormatException e ) {
00405
00406 }
00407 }
00408
00409 connection = new ChatClient( host, port , this );
00410 connection.start ();
00411 reconnectRetryCount = 0;
00412 return;
00413 }
00414 else if ( cmd.equalsIgnoreCase( ":exit" ) ) {
00415 inputMsg.setText( "" );
00416 connection.close ();
00417 System.exit( 0 );
00418 }
00419
00420
00421
00422 if ( defaultInputMsg.equalsIgnoreCase( inputMsg.getText () ) ) {
00423
00424 } else if ( userId.getText ().trim ().length () == 0 ) {
00425 connection.send( inputMsg.getText () );
00426 inputMsg.setText( "" );
00427 } else {
00428 connection.send( inputMsg.getText (), userId.getText () );
00429 inputMsg.setText( "" );
00430 }
00431
00432 if ( ! connection.isAlive () )
00433 {
00434 System.exit( 0 );
00435 }
00436 }
00437
00438
00439
00440
00441 public void keyReleased( KeyEvent ke )
00442 {
00443
00444 }
00445
00446
00447
00448
00449 public void keyTyped( KeyEvent ke )
00450 {
00451
00452 }
00453
00454
00455
00456
00457
00458
00459 public static void main( String args[] )
00460 {
00461 final String[] copyOfArgs = args;
00462
00463 java.awt.EventQueue.invokeLater(
00464 new Runnable() {
00465 public void run() {
00466 new ChatClientFrame( copyOfArgs ).setVisible( true );
00467 }
00468 }
00469 );
00470 }
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562