• Main Page
  • Related Pages
  • Classes
  • Files
  • File List

ChatServerFrame.java

Go to the documentation of this file.
00001 
00002 import java.awt.BorderLayout;
00003 import java.awt.Color;
00004 import java.awt.Dimension;
00005 import java.awt.Font;
00006 import java.awt.Toolkit;
00007 import java.text.SimpleDateFormat;
00008 import java.util.Calendar;
00009 
00010 import javax.swing.JFrame;
00011 import javax.swing.JScrollPane;
00012 import javax.swing.JTextArea;
00013 import javax.swing.WindowConstants;
00014 
00015 /**
00016  *  Simple multi-threaded chat server with GUI
00017  * 
00018  *  @author Mikica B Kocic
00019  */
00020 public class ChatServerFrame extends JFrame implements ChatServer.Context
00021 {
00022     /**
00023      *  Implements java.io.Serializable interface
00024      */
00025     private static final long serialVersionUID = 7408497530711923022L;
00026 
00027     /**
00028      *  TCP port that chat server listens for new connections 
00029      */
00030     private int port = 2000;
00031     
00032     /*  GUI components
00033      */
00034     private JTextArea logArea;
00035 
00036     /**
00037      *  Creates a new instance of the <code>ChatClientFrame</code>.
00038      *  
00039      *  @param args the command line arguments passed to main
00040      */
00041     public ChatServerFrame( String args[] )
00042     {
00043         super( "IP1-4.1.2: Yet Another Simple Chat Server" );
00044         
00045         setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
00046 
00047         //////////////////////////////////////////////////////////////////////////////////
00048         
00049         /* Top level components
00050          */
00051         Font textFont = new Font( Font.MONOSPACED, Font.PLAIN, 14 );
00052         
00053         logArea = new JTextArea ();
00054         logArea.setFont( textFont );
00055         logArea.setBackground( new Color( 0, 0, 128 ) );
00056         logArea.setForeground( new Color( 220, 220, 192 ) );
00057         logArea.setLineWrap( true );
00058         logArea.setWrapStyleWord( true );
00059         logArea.setEditable( false );
00060         
00061         JScrollPane logPane = new JScrollPane ();
00062         logPane.setViewportView( logArea );
00063 
00064         add( logPane, BorderLayout.CENTER );
00065         
00066         /* Adjust window dimensions not to exceed screen dimensions ...
00067          */
00068         Dimension win = new Dimension( 1024, 600 );
00069         Dimension scsz = Toolkit.getDefaultToolkit().getScreenSize();
00070         win.width  = Math.min( win.width, scsz.width );
00071         win.height = Math.min( win.height, scsz.height - 40 );
00072         setSize( win );
00073         
00074         /* ... then center window on the screen.
00075          */
00076         setLocation( ( scsz.width - win.width )/2, ( scsz.height - 40 - win.height )/2 );
00077         
00078         /* Parse arguments: [ <port> ]
00079          */
00080         if ( args.length >= 1 ) {
00081             try {
00082                 port = Integer.parseInt( args[ 0 ] );
00083             } catch ( NumberFormatException e ) {
00084                 // TODO might report that we are using default port?
00085             }
00086         }
00087         
00088         /* Start receiving connections
00089          */
00090         ChatServer server = new ChatServer( port, this );
00091         server.start();
00092     }
00093     
00094     /**
00095      *  Gets current time stamp
00096      *  
00097      *  @return time in ISO format 
00098      */
00099     private static String now ()
00100     {
00101         Calendar cal = Calendar.getInstance ();
00102         SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
00103         return sdf.format( cal.getTime() );
00104     }
00105 
00106     /**
00107      *  Logs message in log area.
00108      *  
00109      *  @param str    actual message
00110      */
00111     @Override
00112     public void logMessage( String str )
00113     {
00114         synchronized( logArea )
00115         {
00116             logArea.append( now () + "  " + str + "\n" );
00117             logArea.setRows( logArea.getRows () + 1 );
00118             logArea.setCaretPosition( logArea.getText().length () );
00119         }
00120     }
00121     
00122     /**
00123      *  Updates status message by setting window title.
00124      *  
00125      *  @param str    new status message
00126      */
00127     @Override
00128     public void logStatus( String str )
00129     {
00130         setTitle( "IP1-4.1.2 Chat Server " + str );
00131 
00132         /* Change background color to dark red if the socket is dead.
00133          */
00134         if ( str.contains( ", dead") ) {
00135             logArea.setBackground( new Color( 92, 0, 0 ) );
00136         }
00137     }
00138 
00139     /**
00140      *  Main entry point
00141      *  
00142      *  @param args the command line arguments
00143      */
00144     public static void main( String args[] ) 
00145     {
00146         final String[] copyOfArgs = args;
00147         
00148         java.awt.EventQueue.invokeLater( 
00149                 new Runnable() {
00150                     public void run() {
00151                         new ChatServerFrame( copyOfArgs ).setVisible( true );
00152                     }
00153                 }
00154             );
00155     }
00156 }
00157 
00158 /*! 
00159  *  \mainpage Yet Another Chat Server
00160  *
00161  *  \section s_intro Introduction
00162  *  
00163  *  The package implements solution to \ref p_task as a part of 
00164  *  the <a href="http://dsv.su.se/utbildning/distans/ip1" target="_blank"><b>SU/IP1 
00165  *  course</b></a>.
00166  *  
00167  *  \image html chatServer.png
00168  *  
00169  *  \section s_desc Description
00170  *  
00171  *  Chat server's principal class is ChatServer that listens on socket for new 
00172  *  connections. It instantiates a new threaded client back-end for each new connection 
00173  *  (as instance of the ChatServerClient class) and keeps all such client connections
00174  *  in the ChatServer.clients list. Client back-end thread purges itself 
00175  *  from the list after remote end is disconnected.
00176  *  
00177  *  ChatServerClient will receive messages in ChatServerClient.run() from the remote 
00178  *  client and call-back servers's ChatServer.broadcast() method that will distribute 
00179  *  message to all connected clients.
00180  *  
00181  *  Server may also opriginate its own messages, which will be prefixed 
00182  *  with the "[System] :: ".
00183  *  
00184  *  After receiving "wwhhoo" message, server will broadcast a list of all connected
00185  *  clients in the form: <code>WWHHOO: &lt;client-hostname&gt;:&lt;port&gt;</code>.
00186  *  
00187  *  One can start application with the following command:
00188  *  
00189  *   - <code>java -jar <a href="../chatServer.jar">chatServer.jar</a>
00190  *     [ &lt;port&gt; ]</code>
00191  *   
00192  *  where the default port is <code>2000</code>
00193  *  
00194  *  \section s_eliza Joseph Weizenbaum's Eliza
00195  *  
00196  *  If the server detects that the user is alone in the chat-room, it will offer to user
00197  *  to talk to an instance of 
00198  *  <a href="http://en.wikipedia.org/wiki/ELIZA" target="_blank"> Joseph Weizenbaum's 
00199  *  Eliza</a>, a simulation of a Rogerian 
00200  *  psychoterapist implemented by 
00201  *  <a href="http://chayden.net/eliza/Eliza.html" target="_blank">Charles Chayeden</a>.
00202  *  
00203  *  The server will start Eliza in respond to user message <code>talk eliza</code>
00204  *  (ignoring spaces and character cases).
00205  *  
00206  *  \section s_jar Executable
00207  *  
00208  *  The jar file of the package can be found <a href="../chatServer.jar"><b>here</b></a>.
00209  *   
00210  *  \section s_src Sources
00211  *  
00212  *  Source files:
00213  *   - \ref ChatServer.java
00214  *   - \ref ChatServerClient.java
00215  *   - \ref ChatServerFrame.java
00216  *
00217  */
00218 /*! \page p_task IP1-4.1.2 Uppgift
00219  *
00220  *  Gör ett fristående program med ett grafiskt användargränssnitt som implementerar en
00221  *  chat-server som kan sända och ta emot text-meddelanden. Chat-servern ska använda
00222  *  stream-sockets.
00223  *
00224  *  Chat-servern ska kunna ta emot begäran om uppkoppling från nya chat-klienter och 
00225  *  placera alla chat-klienter i en egen tråd för att kunna ta emot ytterligare 
00226  *  chat-klienter. Varje chat-klient-tråd ligger och väntar på att en chat-klient 
00227  *  ska skicka ett text-meddelande. När så sker så ska chat-servern "broadcasta" 
00228  *  detta meddelande till samtliga chat-klienter. Chat-servern måste således hålla 
00229  *  reda på alla anslutna chat-klienter i någon datasamling.
00230  *
00231  *  Alla text-meddelanden som sänds från chat-klienterna ska visas en en lämplig 
00232  *  swing-komponent, exempelvis en text-area. För samtliga text-meddelanden så ska 
00233  *  följande skrivas ut i denna swing-komponent: 
00234  *  
00235  *   - Chat-klientens IP-adress
00236  *   - Text-meddelandet från chat-klienten
00237  *   
00238  *  Chat-servern ska gå att starta på två sätt:
00239  *  
00240  *   -# <code>java Server</code> (då ska port default bli 2000)
00241  *   -# <code>java Server &lt;port&gt;</code>
00242  *   
00243  *   Efter detta ska chat-servern göra sig redo för att ta emot förfrågningar om 
00244  *   anslutning från chat-klienter. Om detta lyckas så ska det i chat-serverns 
00245  *   titelrad stå den host och port som chat-servern kör på samt antalet chat-klienter 
00246  *   som är uppkopplade.
00247  *   
00248  *   Observera! Chat-servern ska upptäcka när en klient inte längre är ansluten och 
00249  *   då ta bort den ur datasamlingen och döda tråden (eventuellt kan tråden döda sig 
00250  *   själv). 
00251  */

Generated on Thu Dec 16 2010 14:26:32 for Chat Server by  doxygen 1.7.2