Chat client GUI front-end. More...
Public Member Functions | |
ChatClientFrame (String args[]) | |
Creates a new instance of the ChatClientFrame . | |
void | logMessage (String str) |
Logs message formated with limited HTML (limited because of JEditoPane) | |
void | logStatus (String str) |
Updates status message by updating window title. | |
void | actionPerformed (ActionEvent ae) |
Handle events from the Swing Timer. | |
void | keyPressed (KeyEvent ke) |
Implements KeyListener 's key pressed event. | |
void | parseInputMessage () |
Parses input message from inputMsg and sends it to chat server. | |
void | keyReleased (KeyEvent ke) |
Implements KeyListener 's key released event. | |
void | keyTyped (KeyEvent ke) |
Implements KeyListener 's key typed event. | |
Static Public Member Functions | |
static void | main (String args[]) |
Main entry point. | |
Private Member Functions | |
void | sendButton_Clicked (MouseEvent evt) |
Parses input message and send it to chat server. | |
Private Attributes | |
String | host = "127.0.0.1" |
Host name or IP address of the remote chat server. | |
int | port = 2000 |
TCP port where to connect to on remote chat server. | |
ChatClient | connection |
Instance of threaded connection to chat server. | |
int | reconnectTimeout = -1 |
Interconnect delay timer. | |
int | reconnectRetryCount = 0 |
Retry counter of failed connecting attempts. | |
JButton | sendButton |
JTextField | inputMsg |
JLabel | idLabel |
JTextField | userId |
JEditorPane | logArea |
Static Private Attributes | |
static final long | serialVersionUID = 7406765627069159382L |
Implements java.io.Serializable interface. | |
static final String | defaultInputMsg = "<type message here>" |
Initial message content of the input text message field. |
Chat client GUI front-end.
Definition at line 28 of file ChatClientFrame.java.
ChatClientFrame.ChatClientFrame | ( | String | args[] ) |
Creates a new instance of the ChatClientFrame
.
args | the command line arguments passed to main |
Definition at line 79 of file ChatClientFrame.java.
References connection, defaultInputMsg, host, idLabel, inputMsg, logArea, logMessage(), port, sendButton, sendButton_Clicked(), ChatClient.start(), and userId.
Referenced by main().
{ super( "IP1-4.1.1: Yet Another Simple Chat Client" ); setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE ); ////////////////////////////////////////////////////////////////////////////////// /* Top level components */ Font textFont = new Font( Font.SANS_SERIF, Font.PLAIN, 14 ); inputMsg = new JTextField( defaultInputMsg, 30 ); inputMsg.addKeyListener( this ); inputMsg.setFont( textFont ); inputMsg.selectAll (); sendButton = new JButton (); sendButton.setText( "Send" ); sendButton.addMouseListener( new MouseAdapter () { public void mouseClicked( MouseEvent evt ) { sendButton_Clicked( evt ); } } ); idLabel = new JLabel( "My ID:" ); idLabel.setFont( textFont ); userId = new JTextField( System.getProperty( "user.name" ) ); userId.addKeyListener( this ); userId.setFont( textFont ); logArea = new JEditorPane (); logArea.setFont( textFont ); logArea.setBackground( new Color( 255, 255, 224 ) ); logArea.setForeground( Color.BLACK ); logArea.setEditable( false ); logArea.setContentType( "text/html" ); logArea.setText( "<html><head></head><body>\n</body></html>" ); JScrollPane logPane = new JScrollPane (); logPane.setViewportView( logArea ); ////////////////////////////////////////////////////////////////////////////////// /* Layout (self explained?): * Upper: sendButton, inputMsg, idLabel and userId * Lower: scrolled logArea */ GroupLayout layout = new GroupLayout( getContentPane () ); getContentPane().setLayout( layout ); layout.setAutoCreateContainerGaps( true ); layout.setAutoCreateGaps( true ); layout.setHorizontalGroup ( layout .createParallelGroup( GroupLayout.Alignment.LEADING ) .addGroup ( layout .createSequentialGroup () .addGroup ( layout .createParallelGroup( GroupLayout.Alignment.LEADING ) .addGroup ( GroupLayout.Alignment.TRAILING, layout .createSequentialGroup () .addComponent( sendButton ) .addComponent( inputMsg ) .addComponent( idLabel ) .addComponent( userId ) ) .addComponent( logPane ) ) ) ); layout.setVerticalGroup ( layout .createParallelGroup( GroupLayout.Alignment.LEADING ) .addGroup ( layout .createSequentialGroup () .addGroup ( layout .createParallelGroup( GroupLayout.Alignment.BASELINE ) .addComponent( sendButton ) .addComponent( inputMsg ) .addComponent( idLabel ) .addComponent( userId ) ) .addComponent( logPane ) ) ); pack(); ////////////////////////////////////////////////////////////////////////////////// /* Adjust window dimensions not to exceed screen dimensions ... */ Dimension win = new Dimension( 1024, 600 ); Dimension scsz = Toolkit.getDefaultToolkit().getScreenSize(); win.width = Math.min( win.width, scsz.width ); win.height = Math.min( win.height, scsz.height - 40 ); setSize( win ); /* ... then center window on the screen. */ setLocation( ( scsz.width - win.width )/2, ( scsz.height - 40 - win.height )/2 ); /* Parse arguments: [ <host> [ <port> ] ] */ if ( args.length >= 1 ) { host = args[ 0 ]; if( args.length >= 2 ) try { port = Integer.parseInt( args[ 1 ] ); } catch ( NumberFormatException e ) { // TODO might report that we are using default port? } } /* Default 'usage' info... */ logMessage( "<table border='0' cellspacing='2' align='right' color='#0000FF'>" + "<td><b>Usage:</b> </td>\n" + "<td><table border='0' cellspacing='0' bgcolor='#E0F0E0'>" + "<tr><td><code>:open [ <hostname> [ <port> ] ]</code></td>" + "<td><code><em>-- open new connection</em></code></td></tr>\n" + "<tr><td><code>:close</code></td>" + "<td><code><em>-- close current connection</em></code></td></tr>\n" + "<tr><td><code>:exit</code></td>" + "<td><code><em>-- quit application</em></code></td></tr>\n" + "<tr><td><code>:who</code></td>" + "<td><code><em>-- send 'wwhhoo' to chat server</em></code></td></tr>\n" + "</table>" + "</td></tr></table>" ); /* Open communication link to server... */ connection = new ChatClient( host, port, this ); connection.start (); /* Instantiate connection monitor timer (for reconnect supervision) */ Timer timer = new Timer( 1000, this ); timer.start (); /* Ready for user to type in something... */ inputMsg.selectAll (); inputMsg.requestFocus (); }
void ChatClientFrame.actionPerformed | ( | ActionEvent | ae ) |
Handle events from the Swing Timer.
If connection is detected to be down, it will try to reconnect to chat server after some period of time. If reconnection retry count exceeded maximum, timer will stop retrying.
Definition at line 304 of file ChatClientFrame.java.
References connection, host, logMessage(), logStatus(), port, reconnectRetryCount, reconnectTimeout, and ChatClient.start().
{ final int maxRetryCount = 3; final int reconnectDelay = 2; if ( connection.isAlive () ) { reconnectTimeout = -1; // disables timer return; } if ( reconnectRetryCount >= maxRetryCount ) { if ( reconnectRetryCount == maxRetryCount ) { ++reconnectRetryCount; logMessage( "<br/><code>Press ENTER to quit or type<br/><br/>" + " :open [ <hostname> [ <port> ] ]<br/><br/>" + "to open new connection...</code><br/><br/>" ); logStatus( "Dead" ); } return; // leave to user to quit by pressing ENTER } if ( reconnectTimeout < 0 ) { logStatus( "Disconnected" ); logMessage( "<br/><code>Reconnecting in " + reconnectDelay + " seconds...</code>" ); reconnectTimeout = reconnectDelay; // start timer return; } if ( --reconnectTimeout > 0 ) { return; } logMessage( "<code>retry #" + ( ++reconnectRetryCount ) + " of max " + maxRetryCount + ":</code><br/>" ); reconnectTimeout = -1; // disables timer and restarts new connection connection = new ChatClient( host, port , this ); connection.start (); }
void ChatClientFrame.keyPressed | ( | KeyEvent | ke ) |
Implements KeyListener
's key pressed event.
Definition at line 359 of file ChatClientFrame.java.
References parseInputMessage().
{ int keyCode = ke.getKeyCode (); if( keyCode == KeyEvent.VK_ENTER ) { parseInputMessage (); } }
void ChatClientFrame.keyReleased | ( | KeyEvent | ke ) |
Implements KeyListener
's key released event.
Definition at line 441 of file ChatClientFrame.java.
{
/* unused */
}
void ChatClientFrame.keyTyped | ( | KeyEvent | ke ) |
Implements KeyListener
's key typed event.
Definition at line 449 of file ChatClientFrame.java.
{
/* unused */
}
void ChatClientFrame.logMessage | ( | String | str ) | [virtual] |
Logs message formated with limited HTML (limited because of JEditoPane)
str | message that will be logged |
Implements ChatClient.Context.
Definition at line 260 of file ChatClientFrame.java.
References logArea.
Referenced by actionPerformed(), and ChatClientFrame().
{ final String strCopy = new String( str ); java.awt.EventQueue.invokeLater( new Runnable() { public void run() { synchronized( logArea ) { /* Append the string to the end of <body> element... */ String html = logArea.getText (); html = html.replace( "</body>", strCopy + "\n</body>" ); logArea.setText( html ); } } } ); }
void ChatClientFrame.logStatus | ( | String | str ) | [virtual] |
Updates status message by updating window title.
str | new status message |
Implements ChatClient.Context.
Definition at line 286 of file ChatClientFrame.java.
Referenced by actionPerformed().
{ final String strCopy = new String( str ); java.awt.EventQueue.invokeLater( new Runnable() { public void run() { setTitle( "IP1-4.1.1 Chat Client: " + strCopy ); } } ); }
static void ChatClientFrame.main | ( | String | args[] ) | [static] |
Main entry point.
args | the command line arguments |
Definition at line 459 of file ChatClientFrame.java.
References ChatClientFrame().
{ final String[] copyOfArgs = args; java.awt.EventQueue.invokeLater( new Runnable() { public void run() { new ChatClientFrame( copyOfArgs ).setVisible( true ); } } ); }
void ChatClientFrame.parseInputMessage | ( | ) |
Parses input message from inputMsg and sends it to chat server.
Also performs various commands :open, :close, :exit ...
Definition at line 373 of file ChatClientFrame.java.
References ChatClient.close(), connection, defaultInputMsg, host, inputMsg, port, reconnectRetryCount, ChatClient.send(), ChatClient.start(), and userId.
Referenced by keyPressed(), and sendButton_Clicked().
{ /* Split string into words, removing all leading, trailing * and superfluous (btw words) white-spaces */ String[] args = inputMsg.getText().trim().split( "\\s{1,}" ); String cmd = args.length > 0 ? args[0] : ""; if ( cmd.equalsIgnoreCase( ":who" ) ) { inputMsg.setText( "" ); connection.send( "wwhhoo" ); return; } else if ( cmd.equalsIgnoreCase( ":close" ) ) { inputMsg.setText( "" ); reconnectRetryCount = Integer.MAX_VALUE; // suppresses reconnection connection.close (); return; } else if ( cmd.equalsIgnoreCase( ":open" ) ) { inputMsg.setText( "" ); reconnectRetryCount = Integer.MAX_VALUE; // suppresses reconnection connection.close (); if ( args.length >= 2 ) { host = args[ 1 ]; port = 2000; // default port if( args.length >= 3 ) try { port = Integer.parseInt( args[ 2 ] ); } catch ( NumberFormatException e ) { // TODO handle this } } connection = new ChatClient( host, port , this ); connection.start (); reconnectRetryCount = 0; return; } else if ( cmd.equalsIgnoreCase( ":exit" ) ) { inputMsg.setText( "" ); connection.close (); System.exit( 0 ); } /* Default task: send message to chat server */ if ( defaultInputMsg.equalsIgnoreCase( inputMsg.getText () ) ) { /* ignore default input message */ } else if ( userId.getText ().trim ().length () == 0 ) { // an empty userId connection.send( inputMsg.getText () ); inputMsg.setText( "" ); } else { connection.send( inputMsg.getText (), userId.getText () ); inputMsg.setText( "" ); } if ( ! connection.isAlive () ) { System.exit( 0 ); } }
void ChatClientFrame.sendButton_Clicked | ( | MouseEvent | evt ) | [private] |
Parses input message and send it to chat server.
Definition at line 249 of file ChatClientFrame.java.
References parseInputMessage().
Referenced by ChatClientFrame().
{ parseInputMessage (); }
ChatClient ChatClientFrame.connection [private] |
Instance of threaded connection to chat server.
Definition at line 54 of file ChatClientFrame.java.
Referenced by actionPerformed(), ChatClientFrame(), and parseInputMessage().
final String ChatClientFrame.defaultInputMsg = "<type message here>" [static, private] |
Initial message content of the input text message field.
Definition at line 39 of file ChatClientFrame.java.
Referenced by ChatClientFrame(), and parseInputMessage().
String ChatClientFrame.host = "127.0.0.1" [private] |
Host name or IP address of the remote chat server.
Default: localhost
Definition at line 44 of file ChatClientFrame.java.
Referenced by actionPerformed(), ChatClientFrame(), and parseInputMessage().
JLabel ChatClientFrame.idLabel [private] |
Definition at line 70 of file ChatClientFrame.java.
Referenced by ChatClientFrame().
JTextField ChatClientFrame.inputMsg [private] |
Definition at line 69 of file ChatClientFrame.java.
Referenced by ChatClientFrame(), and parseInputMessage().
JEditorPane ChatClientFrame.logArea [private] |
Definition at line 72 of file ChatClientFrame.java.
Referenced by ChatClientFrame(), and logMessage().
int ChatClientFrame.port = 2000 [private] |
TCP port where to connect to on remote chat server.
Default: 2000
Definition at line 49 of file ChatClientFrame.java.
Referenced by actionPerformed(), ChatClientFrame(), and parseInputMessage().
int ChatClientFrame.reconnectRetryCount = 0 [private] |
Retry counter of failed connecting attempts.
Definition at line 64 of file ChatClientFrame.java.
Referenced by actionPerformed(), and parseInputMessage().
int ChatClientFrame.reconnectTimeout = -1 [private] |
Interconnect delay timer.
Value -1 means 'disabled'.
Definition at line 59 of file ChatClientFrame.java.
Referenced by actionPerformed().
JButton ChatClientFrame.sendButton [private] |
Definition at line 68 of file ChatClientFrame.java.
Referenced by ChatClientFrame().
final long ChatClientFrame.serialVersionUID = 7406765627069159382L [static, private] |
Implements java.io.Serializable interface.
Definition at line 34 of file ChatClientFrame.java.
JTextField ChatClientFrame.userId [private] |
Definition at line 71 of file ChatClientFrame.java.
Referenced by ChatClientFrame(), and parseInputMessage().