Client And Server With Swing Interface
Description: toolbar,tooltips,help,documentation
A chatting software based loosely on IRC system. There is a central server handling all communications to and from clients. Each user can run the client program and connect to server to start chatting. All clients and server will have list of online users. List is updated as soon as the status of some client changes. There is one main chat room in which all messages can be seen by all clients. Users can also choose to chat in private with any one on the list. Multiple chat rooms have not been implemented but provisions are provided in code for easy deployment.
//Chatclient.java--chatclient
package chatclient;
import protocols.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
//MAIN CLASS THAT HANDLES THE CONNECTION TO SERVER
public class ChatClient
{
private boolean connected;
int serverSocketNumber;
String serverAddress;
private Socket socket;
String Name;
private int clientID;
ObjectOutputStream out;
ObjectInputStream in;
DefaultListModel clientList;
private InputListener listener;
ClientInterface window;
//RESPONSIBLE FOR LISTENING TO INPUT STREAM FOR INCOMING MESSAGES
class InputListener extends Thread
{
//Provides a way to pause the listener
boolean running = false;
public void run()
{
//Loops forever but if listener is paused then skips code
while( true )
{
if( running )
{
//Detect the type of message and take appropriate action
try
{
Object serverMsg = in.readObject();
if( serverMsg instanceof Message )
{
window.showMessage( (Message)serverMsg );
}
else if( serverMsg instanceof ChatRequest )
{
window.openNewTab( ((ChatRequest)serverMsg).senderId );
}
else if( serverMsg instanceof UpdateList )
{
//If informationis about new user logging in
if( ((UpdateList)serverMsg).requestType == true )
{
clientList.addElement( ((UpdateList)serverMsg).newClient );
}
//If information is about user logging out
else
{
window.notifyUserLeft( ((UpdateList)serverMsg).newClient );
clientList.removeElement( ((UpdateList)serverMsg).newClient );
}
}
else if( serverMsg instanceof ServerShutDown )
{
disconnectFromServer( false );
window.notifyDisconnect();
JOptionPane.showMessageDialog( window,"Server Has Been Shut Down","Connection Error",JOptionPane.ERROR_MESSAGE );
}
else if( serverMsg instanceof KickedOutNotice )
{
disconnectFromServer( false );
window.notifyDisconnect();
JOptionPane.showMessageDialog( window,"Server Kicked You Out","Connection Error",JOptionPane.ERROR_MESSAGE );
}
}
catch( ClassNotFoundException cnfe )
{
JOptionPane.showMessageDialog( window, "Class of a serialized object cannot be found.", "Termination Error", JOptionPane.ERROR_MESSAGE );
shutDown();
}
catch( InvalidClassException ice )
{
JOptionPane.showMessageDialog( window, "Something is wrong with a class used by serialization.", "Termination Error", JOptionPane.ERROR_MESSAGE );
shutDown();
}
catch( StreamCorruptedException sce )
{
JOptionPane.showMessageDialog( window, "Control information in the stream is inconsistent.", "Termination Error", JOptionPane.ERROR_MESSAGE );
shutDown();
}
catch( OptionalDataException ode )
{
JOptionPane.showMessageDialog( window, "Primitive data was found in the stream instead of objects.", "Termination Error", JOptionPane.ERROR_MESSAGE );
shutDown();
}
catch( IOException ioe)
{
//JOptionPane.showMessageDialog( null, "Any of the usual Input/Output related exceptions.", "Termination Error", JOptionPane.ERROR_MESSAGE );
//shutDown();
}
}
}
}
}
//Transmit the message from user to server for the main room
void sendPublicMessage( String userMsg ) throws IOException
{
Message msg = new Message();
msg.audience = true;
msg.roomNumber = 0;
msg.senderId = clientID;
msg.message = Name + " says > " + userMsg;
out.writeObject( msg );
out.flush();
}
//Transmit the message from user to server for one intended client
void sendPrivateMessage( int recipient, String userMsg ) throws IOException
{
Message msg = new Message();
msg.audience = false;
msg.recieverId = recipient;
msg.senderId = clientID;
msg.message = Name + " says > " + userMsg;
out.writeObject( msg );
out.flush();
}
//Transmit a request that this user wants to chat privately with
//someone on the list
void sendChatRequest( int recieverId )
{
ChatRequest request = new ChatRequest();
request.recieverId = recieverId;
request.senderId = clientID;
try
{
out.writeObject( request );
}
catch( IOException io_e )
{}
}
//Save new configuration values to file
void setConfiguration( String newServer, int newPort )
{
try
{
FileWriter configFile = new FileWriter("clientConfig.cfg");
configFile.write( newServer.trim() + ";" + newPort + ";" );
configFile.close();
}
catch( IOException io_e )
{
JOptionPane.showMessageDialog( window,"Cannot Save Configuration File","File Error",JOptionPane.ERROR_MESSAGE );
}
}
//Get configuration options from file and store in variables
void getConfiguration()
{
try
{
char[] buffer = new char[255];
FileReader configFile = new FileReader("clientConfig.cfg");
configFile.read( buffer );
serverAddress = String.copyValueOf( buffer );
String[] temp = serverAddress.split(";");
serverAddress = temp[0];
serverSocketNumber = Integer.parseInt( temp[1] );
}
catch( FileNotFoundException fnf_e )
{
JOptionPane.showMessageDialog( window,"Configuration File Not Found, Using Defaults","Configuration File Missing",JOptionPane.ERROR_MESSAGE );
serverSocketNumber = 1665;
serverAddress = "localhost";
}
catch( IOException io_e )
{
JOptionPane.showMessageDialog( window,"Error Reading Configuration File, Using Defaults","Configuration Error",JOptionPane.ERROR_MESSAGE );
serverSocketNumber = 1665;
serverAddress = "localhost";
}
}
//Take steps to disconnect from server.
// reason = true means user choice
//reason = false means by server
synchronized void disconnectFromServer( boolean reason )
{
try
{
if( connected )
{
//Pause the listener thread
listener.running = false;
if( reason = true )
{
out.writeObject( new LogOut() );
out.flush();
}
out.close();
socket.close();
clientList.clear();
connected = false;
}
}
catch( IOException ex )
{}
}
//Take steps to conect to the server
synchronized boolean connectToServer()
{
getConfiguration();
try
{
InetAddress addr = InetAddress.getByName( serverAddress );
socket = new Socket( addr,serverSocketNumber );
}
catch( UnknownHostException e )
{
JOptionPane.showMessageDialog( window,"Host Not Found, Reconfigure...","Host Lookup Error",JOptionPane.ERROR_MESSAGE );
return false;
}
catch( IOException e )
{
JOptionPane.showMessageDialog( window,"Server Not Found, Check If Server Exists...","Socket Error",JOptionPane.ERROR_MESSAGE );
return false;
}
try
{
in = new ObjectInputStream( socket.getInputStream() );
out = new ObjectOutputStream( socket.getOutputStream() );
}
catch( IOException e )
{
JOptionPane.showMessageDialog( window,"Cannot Create Data Stream, Closing Client...","Data Stream Error",JOptionPane.ERROR_MESSAGE );
try
{
socket.close();
}
catch( IOException io_e )
{}
return false;
}
if( !handShake() )
return false;
listener.running = true;
//If connecting for first time start the listener object
if( listener.isAlive() == false )
{
listener.start();
}
connected = true;
return true;
}
//Set up parameters with the server
private boolean handShake()
{
try
{
if( ((ConnectionNotice)in.readObject()).status )
{
out.writeObject( Name );
if( ((ConnectionNotice)in.readObject()).status == false )
{
JOptionPane.showMessageDialog( window,"Name Already In Use. Change Login Name","Nick Error",JOptionPane.ERROR_MESSAGE );
return false;
}
clientList = (DefaultListModel)in.readObject();
clientID = clientList.getSize()-1;
return true;
}
else
{
JOptionPane.showMessageDialog( window, "Maximum User Limit Reached. Server Rejected Connection", "Connection Rejected", JOptionPane.ERROR_MESSAGE );
}
}
catch( Exception e )
{}
return false;
}
void shutDown()
{
disconnectFromServer( true );
listener = null;
System.exit(0);
}
ChatClient()
{
connected = false;
listener = new InputListener();
window = new ClientInterface( this );
}
public static void main( String args[] ) throws IOException
{
new ChatClient();
}
}
//ClientInterface.java--chatclient
package chatclient;
import java.io.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import protocols.*;
public class ClientInterface extends JFrame
{
private ChatClient client;
//Have to create a new object each time so that ObjectStream will read it
//private protocols.Message msg = new protocols.Message();
JList lstClients;
//Holds references to all message windows
protected Vector messageWindows;
//Provides mapping of tab number to clientId
protected Vector tabToClient;
protected JButton bSend;
protected JTextField tfMessage;
protected JScrollPane scrlClients;
protected JMenuBar menuBar;
protected JMenu hlpMenu;
protected JMenu tabMenu;
protected JMenu fileMenu;
protected JMenuItem exitFMenu;
protected JMenuItem webHlpMenu;
protected JMenuItem helpHlpMenu;
protected JMenuItem aboutHlpMenu;
protected JMenuItem closeTabMenu;
protected JMenuItem connectFMenu;
protected JMenuItem configureFMenu;
protected JMenuItem disconnectFMenu;
protected JMenuItem closeAllTabsMenu;
protected JTabbedPane tbChatWindows;
ClientInterface( ChatClient client )
{
super( "Fruit Cha(a)t Plate" );
//this.setIconImage( new ImageIcon("Icons/dukeWaveRed.gif") );
this.client = client;
setUpMenu();
setUpMainInterface();
setVisible(true);
tfMessage.requestFocus();
}
protected void setUpMenu()
{
exitFMenu = new JMenuItem("Exit",KeyEvent.VK_X);
webHlpMenu = new JMenuItem("Fruit Cha(a)t on the WEB");
helpHlpMenu = new JMenuItem("Help",KeyEvent.VK_H);
connectFMenu = new JMenuItem("Connect",KeyEvent.VK_C);
aboutHlpMenu = new JMenuItem("About",KeyEvent.VK_A);
closeTabMenu = new JMenuItem( "Close Tab",KeyEvent.VK_C );
configureFMenu = new JMenuItem("Configure");
disconnectFMenu = new JMenuItem("Disconnect",KeyEvent.VK_D);
closeAllTabsMenu = new JMenuItem( "Close All Tabs",KeyEvent.VK_A );
/*
connectFMenu.setIcon( new ImageIcon("icons/lan.gif") );
configureFMenu.setIcon( new ImageIcon("icons/log.gif") );
helpHlpMenu.setIcon( new ImageIcon("icons/about.gif") );
aboutHlpMenu.setIcon( new ImageIcon("icons/about.gif") );
webHlpMenu.setIcon( new ImageIcon("icons/internet.gif") );
*/
fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F);
fileMenu.add(connectFMenu);
fileMenu.add(disconnectFMenu);
fileMenu.add(configureFMenu);
fileMenu.addSeparator();
fileMenu.add(exitFMenu);
tabMenu = new JMenu( "Tabs" );
tabMenu.setMnemonic( KeyEvent.VK_T );
tabMenu.add( closeTabMenu );
tabMenu.add( closeAllTabsMenu );
hlpMenu = new JMenu("Help");
hlpMenu.setMnemonic(KeyEvent.VK_H);
hlpMenu.add(helpHlpMenu);
hlpMenu.addSeparator();
hlpMenu.add(aboutHlpMenu);
hlpMenu.add(webHlpMenu);
menuBar = new JMenuBar();
menuBar.add(fileMenu);
menuBar.add( tabMenu );
menuBar.add(hlpMenu);
setJMenuBar(menuBar);
}
protected void setUpListeners()
{
configureFMenu.addActionListener( new ConfigureFMenu() );
exitFMenu.addActionListener( new ExitButton() );
helpHlpMenu.addActionListener( new HelpHlpMenu() );
aboutHlpMenu.addActionListener( new AboutHlpMenu() );
webHlpMenu.addActionListener( new WebHlpMenu() );
connectFMenu.addActionListener( new ConnectFMenu() );
disconnectFMenu.addActionListener( new DisconnectFMenu() );
closeTabMenu.addActionListener( new CloseTabButton() );
closeAllTabsMenu.addActionListener( new CloseAllTabsMenu() );
bSend.addActionListener( new SendButton() );
tfMessage.addActionListener( new SendMessage() );
//tfMessage.addFocusListener( new FocusMessageField() );
lstClients.addMouseListener( new SelectClient() );
addWindowListener( new OnExit() );
}
protected void setUpProperties()
{
setSize(475,280);
setResizable(false);
bSend.setEnabled( false );
bSend.setToolTipText( "Send Your Message" );
tfMessage.setEnabled( false );
tfMessage.setToolTipText( "Enter Your Message Here" );
disconnectFMenu.setEnabled( false );
tabMenu.setEnabled( false );
closeTabMenu.setEnabled( false );
closeAllTabsMenu.setEnabled( false );
lstClients.setFixedCellWidth(101);
lstClients.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
lstClients.setToolTipText( "Double Click To Chat Privately" );
scrlClients = new JScrollPane( lstClients );
scrlClients.setColumnHeaderView( new JLabel("Online Users" ) );
tbChatWindows.setToolTipText( "Conversation Windows. Choose Recipient" );
setUpListeners();
}
protected void setUpMainInterface()
{
bSend = new JButton(" Send ");
tfMessage = new JTextField(32);
lstClients = new JList();
setUpTabs();
setUpProperties();
Box displayBox = Box.createHorizontalBox();
displayBox.add( tbChatWindows );
displayBox.add( Box.createHorizontalStrut(3) );
displayBox.add( scrlClients );
Box commandBox = Box.createHorizontalBox();
commandBox.add( tfMessage );
commandBox.add( Box.createHorizontalStrut(3) );
commandBox.add( bSend );
Container cp = this.getContentPane();
cp.setLayout( new FlowLayout(FlowLayout.LEFT) );
cp.add( displayBox );
cp.add( commandBox );
}
protected void setUpTabs()
{
messageWindows = new Vector(5,2);
tabToClient = new Vector(5,2);
tbChatWindows = new JTabbedPane( JTabbedPane.TOP,JTabbedPane.SCROLL_TAB_LAYOUT );
//Set up the main room tab. This tab cannot be closed
messageWindows.addElement( new JTextArea(10,30) );
((JTextArea)messageWindows.elementAt(0)).setLineWrap(true);
((JTextArea)messageWindows.elementAt(0)).setEditable(false);
tbChatWindows.addTab( "Main",new JScrollPane( (JTextArea)
messageWindows.elementAt(0),
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
tbChatWindows.setIconAt( 0,new ImageIcon( "icons/usmenu.gif" ) );
//tbChatWindows.setForegroundAt( 0, Color.BLUE );
}
//Open a tab to chat with specified friend
void openNewTab( int friendId )
{
//Check if a conversation tab is already open for the friend
//If yes then set focus to that tab
int index = tabToClient.indexOf( new Integer( friendId ) );
if( index != -1 )
{
tbChatWindows.setSelectedIndex( index );
return;
}
//Open a new conversation tab. Add a new message window to
//list, map the client to tab, set properties and add tab
messageWindows.addElement( new JTextArea(10,30) );
tabToClient.addElement( new Integer(friendId) );
((JTextArea)messageWindows.lastElement()).setLineWrap(true);
((JTextArea)messageWindows.lastElement()).setEditable(false);
lstClients.setSelectedIndex( friendId );
tbChatWindows.addTab( (String)lstClients.getSelectedValue(),(new JScrollPane( (JTextArea)messageWindows.lastElement() ) ) );
tbChatWindows.setIconAt( tabToClient.size(),new ImageIcon( "icons/aol.gif" ) );
tabMenu.setEnabled( true );
closeTabMenu.setEnabled( true );
closeAllTabsMenu.setEnabled( true );
}
private void showMessage( int tabSelected, String message )
{
((JTextArea)messageWindows.elementAt(tabSelected)).append( message );
}
void showMessage( Message userMsg )
{
int tabIndex = 0;
//If message is public show in main room tab else sort the
//the message to a tab using mappin in tabToClient
if( ((Message)userMsg).audience == true )
{
((JTextArea)messageWindows.elementAt(tabIndex)).append( ((Message)userMsg).message + "\n");
}
else
{
tabIndex = tabToClient.indexOf( new Integer(((Message)userMsg).senderId) );
//if( tabIndex == -1 )
//JOptionPane.showMessageDialog( client.window, "Index Not Found", "Index Error", JOptionPane.INFORMATION_MESSAGE );
((JTextArea)messageWindows.elementAt(tabIndex+1)).append( ((Message)userMsg).message + "\n");
}
//JScrollBar hBar = scrlMessages.getVerticalScrollBar();
//hBar.setValue( hBar.getMaximum() );
}
protected void sendMessage()
{
String str = tfMessage.getText();
int tabSelected = tbChatWindows.getSelectedIndex();
if( str.length() != 0 )
{
try
{
if( tabSelected == 0 )
{
client.sendPublicMessage( str );
}
else
{
Integer clientIndex = (Integer)tabToClient.elementAt( tabSelected-1 );
client.sendPrivateMessage( clientIndex.intValue(),str );
((JTextArea)messageWindows.elementAt( tabSelected )).append(client.Name + " says > " + str + "\n");
}
}
catch( IOException io_ex )
{
showMessage( tabSelected,"\n\nCannot Send Message...\n\n" );
}
tfMessage.setText("");
}
}
//Close all conversation tabs except the main chat room
protected void closeAllTabs()
{
int index = 1;
while( index != tbChatWindows.getTabCount() )
{
tbChatWindows.removeTabAt( index );
messageWindows.removeElementAt( index );
}
tabToClient.clear();
tabMenu.setEnabled( false );
closeTabMenu.setEnabled( false );
closeAllTabsMenu.setEnabled( false );
}
//Show effects of disconnection on the interface
synchronized void notifyDisconnect()
{
connectFMenu.setEnabled( true );
disconnectFMenu.setEnabled( false );
tfMessage.setEnabled( false );
bSend.setEnabled( false );
closeAllTabs();
//lstClients.updateUI();
lstClients.setEnabled( false );
}
//If this client was in a conversation with the user then close
//tab and inform the user that his friend has left
void notifyUserLeft( String clientName )
{
int friendId = client.clientList.indexOf( clientName );
int index = tabToClient.indexOf( new Integer( friendId ) );
//If no conversation tab for the specified user
if( index == -1 )
return;
JOptionPane.showMessageDialog( client.window,clientName+" Has Logged Out",
"User Left",JOptionPane.INFORMATION_MESSAGE );
tbChatWindows.removeTabAt( index+1 );
messageWindows.removeElementAt( index+1 );
tabToClient.removeElementAt( index );
//If only the main room tab is left disable the tab menu
if( tbChatWindows.getTabCount() == 1 )
{
tabMenu.setEnabled( false );
closeTabMenu.setEnabled( false );
closeAllTabsMenu.setEnabled( false );
}
}
class OnExit extends WindowAdapter implements WindowListener
{
public void windowClosing( WindowEvent we )
{
client.shutDown();
}
//Make textField get the focus whenever frame is activated.
public void windowActivated(WindowEvent e)
{
tfMessage.requestFocus();
}
}
class CloseTabButton implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
int index = tbChatWindows.getSelectedIndex();
if( index !=0 )
{
tbChatWindows.removeTabAt( index );
messageWindows.removeElementAt( index );
tabToClient.removeElementAt( index-1 );
if( tbChatWindows.getTabCount() == 1 )
{
tabMenu.setEnabled( false );
closeTabMenu.setEnabled( false );
closeAllTabsMenu.setEnabled( false );
}
}
}
}
class CloseAllTabsMenu implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
closeAllTabs();
}
}
class ExitButton implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
client.shutDown();
}
}
class SendButton implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
sendMessage();
tfMessage.requestFocus();
}
}
class SendMessage implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
sendMessage();
}
}
class SelectClient extends MouseAdapter implements MouseListener
{
public void mouseClicked(MouseEvent e)
{
if( !lstClients.isSelectionEmpty() )
{
if ( e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1 )
{
openNewTab( lstClients.getSelectedIndex() );
client.sendChatRequest( lstClients.getSelectedIndex() );
}
}
}
}
class ConfigureFMenu implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
ConfigureServerInfo serverDialog = new ConfigureServerInfo();
}
}
class AboutHlpMenu implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
JOptionPane.showMessageDialog( client.window, "Fruit Cha(a)t Server"
+"\nVersion 0.7 \nThis software is distributed under the GPL Liscence",
"About Fruit Cha(a)t", JOptionPane.INFORMATION_MESSAGE );
}
}
class HelpHlpMenu implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
JOptionPane.showMessageDialog( client.window,
"1) To connect to server go to File|Connect\n\n"+
"2) To Configure go to File|Configure\n"+
" 2a)Enter the host name of computer,server is on,\n"+
" set to localhost if on same machine\n"+
" 2b)Don't change port unless you changed the port on server\n\n"+
"3)Enter you message in the text field at the bottom\n"+
" and press enter(return key) or the send button\n\n"+
"4)To start a private conversation, double click a name\n"+
" in the online users list",
"General Information",JOptionPane.INFORMATION_MESSAGE);
}
}
class WebHlpMenu implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
JOptionPane.showMessageDialog( client.window, "For free source code visist www.akbani.20m.com.", "Fruit Cha(a)t on the WEB", JOptionPane.INFORMATION_MESSAGE );
}
}
class ConnectFMenu implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
do
{
client.Name = JOptionPane.showInputDialog( client.window,"Enter Login Name ?");
}
while( (client.Name==null || client.Name.length()==0) );
if( client.connectToServer() )
{
client.window.setTitle( "Fruit Cha(a)t Plate <--> " + client.Name );
if( lstClients.getModel() != client.clientList )
{
lstClients.setModel( client.clientList );
}
connectFMenu.setEnabled( false );
disconnectFMenu.setEnabled( true );
tfMessage.setEnabled( true );
bSend.setEnabled( true );
lstClients.setEnabled( true );
((JTextArea)messageWindows.elementAt(0)).setText("");
tfMessage.requestFocus();
}
}
}
class DisconnectFMenu implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
client.disconnectFromServer( true );
notifyDisconnect();
}
}
/*
class FocusMessageField extends FocusAdapter implements FocusListener
{
public void focusLost( FocusEvent fe )
{
if(!( fe.getOppositeComponent() instanceof JMenuItem ))
{
tfMessage.requestFocus();
}
}
}
*/
//DISPLAYS AND SETS CONFIGURATION OPTIONS
class ConfigureServerInfo extends JDialog
{
JButton bSave = new JButton("Save");
JButton bCancel = new JButton("Cancel");
JLabel lbServer = new JLabel("Server Name : ");
JTextField tfServerName = new JTextField(10);
JLabel lbPort = new JLabel("Port No : ");
JTextField tfPortNo = new JTextField(6);
ConfigureServerInfo()
{
super(client.window,"Configure Connection",true);
Box buttonBox = Box.createHorizontalBox();
buttonBox.add( Box.createHorizontalStrut(50) );
buttonBox.add(bSave);
//buttonBox.add( Box.createHorizontalStrut(10) );
buttonBox.add(bCancel);
Container jcp = this.getContentPane();
jcp.setLayout( new FlowLayout(FlowLayout.LEFT) );
jcp.add(lbServer);
jcp.add(tfServerName);
jcp.add(lbPort);
jcp.add(tfPortNo);
//jcp.add( commandBox );
jcp.add( buttonBox );
bSave.addActionListener( new SaveButton() );
bCancel.addActionListener( new CancelButton() );
client.getConfiguration();
tfServerName.setText( client.serverAddress );
tfPortNo.setText( Integer.toString( client.serverSocketNumber ) );
this.setSize(230,115);
//Position the dialog in the center of the interface
Point position = client.window.getLocation();
position.x = position.x + (client.window.getWidth()/2) - (this.getWidth()/2);
position.y = position.y + (client.window.getHeight()/2) - (this.getHeight()/2);
this.setLocation( position );
this.setVisible(true);
this.setResizable( false );
}
class SaveButton implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
client.setConfiguration( tfServerName.getText(), Integer.parseInt(tfPortNo.getText()) );
dispose();
}
}
class CancelButton implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
dispose();
}
}
}
}
chatserver.java--chatserver
package chatserver;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import protocols.*;
//MAIN CLASS THAT HANDLES THE CONNECTION REQUESTS
public class ChatServer
{
int serverPort;
int serverLimit;
ServerSocket server;
int onlineUsers;
//List of all client hadling threads in the server.Synchronized
Vector handlers;
ServerInterface window;
//HANDLER FOR EACH INDIVIDUAL CLIENT
public class ChatHandler implements Runnable
{
protected ClientInfo clientInfo = new ClientInfo();
protected Socket socket;
protected ObjectInputStream in;
protected ObjectOutputStream out;
//Thread on which to run this handler
protected Thread listener;
public ChatHandler( int clientID, Socket socket )
{
clientInfo.clientId = clientID;
this.socket = socket;
//onlineUsers = 0;
}
//Set up parameters and required data with the client
protected boolean handShake()
{
try
{
clientInfo.clientName = (String)in.readObject();
if( window.clientList.size()>0 && window.clientList.indexOf( clientInfo.clientName ) != -1 )
{
try
{
ConnectionNotice status = new ConnectionNotice();
status.status = false;
out.writeObject( status );
out.flush();
socket.close();
return false;
}
catch( IOException w )
{}
}
try
{
ConnectionNotice status = new ConnectionNotice();
status.status = true;
out.writeObject( status );
}
catch( IOException w )
{}
//Add client to list and send it the complete
//client list
window.clientList.addElement( clientInfo.clientName );
out.writeObject( window.clientList );
//Tell all other clients about the new client
//Construct an protocol object and broadcast it
UpdateList newClient = new UpdateList();
newClient.requestType = true;
newClient.newClient = clientInfo.clientName;
broadcast( newClient );
onlineUsers++;
}
catch( Exception e )
{}
return true;
}
public synchronized void start()
{
if ( listener == null )
{
try
{
//The order in whick these streams are created
//is important. Reverse the order in client.
out = new ObjectOutputStream( socket.getOutputStream() );
in = new ObjectInputStream( socket.getInputStream() );
ConnectionNotice status = new ConnectionNotice();
if ( onlineUsers >= serverLimit )
{
//server.window.taMessages.append(onlineUsers+" " +
//ChatHandler client = (ChatHandler)handlers.elementAt( onlineUsers-1 );
try
{
status.status = false;
out.writeObject( status );
out.flush();
socket.close();
return;
}
catch( IOException w )
{}
}
try
{
status.status = true;
out.writeObject( status );
}
catch( IOException w )
{}
if( !handShake() )
return;
//Create a new thread and start listening to the client
listener = new Thread( this );
listener.start();
}
catch( IOException ignored )
{
}
}
}
public synchronized void stop()
{
if ( listener != null )
{
//if ( listener != Thread.currentThread() )
//{
try
{
listener.interrupt();
listener = null;
//Remove handler from list.Remove client from active list
//Notify all other users that this client has left.
handlers.removeElement( this );
window.clientList.removeElement( clientInfo.clientName );
UpdateList newClient = new UpdateList();
newClient.requestType = false;
newClient.newClient = clientInfo.clientName;
broadcast( newClient );
//Close the sockets and show message in server window
out.close();
socket.close();
window.taMessages.append( "Connection to client " + clientInfo.clientId + " closed...\n" );
}
catch( IOException io_ex )
{
JOptionPane.showMessageDialog( window, "Error closing connection to client", "Termination Error", JOptionPane.ERROR_MESSAGE );
}
//}
}
}
public void run()
{
try
{
handlers.addElement( this );
//Listen to input stream for messages from this client
while ( true )
{
try
{
Object clientMsg = in.readObject();
if( clientMsg instanceof Message )
{
//If public message then broadcast
if( ((Message)clientMsg).audience == true )
{
broadcast( clientMsg );
}
else //private message
{
//To Locate the intended reciever.
//1) Get the id of recipient (recieverId)
//2) Get the reference of handler
//3) send message on its output stream
((ChatHandler)(handlers.elementAt(((Message)clientMsg).recieverId))).out.writeObject(clientMsg);
}
}
else if( clientMsg instanceof ChatRequest )
{
//Tell the intended recipient that this
//client wants to start a private chat
//To Locate the intended reciever.
//1) Get the id of recipient (recieverId)
//2) Get the reference of handler
//3) send request on its output stream
((ChatHandler)(handlers.elementAt(((ChatRequest)clientMsg).recieverId))).out.writeObject(clientMsg);
}
else if( clientMsg instanceof LogOut )
{
onlineUsers--;
break;
}
else
{
//If an unknown object is recieved
System.out.println( clientMsg );
}
}
catch( ClassNotFoundException cnfe )
{
JOptionPane.showMessageDialog( window, "Class of a serialized object cannot be found.", "Termination Error", JOptionPane.ERROR_MESSAGE );
break;
}
catch( InvalidClassException ice )
{
JOptionPane.showMessageDialog( window, "Something is wrong with a class used by serialization.", "Termination Error", JOptionPane.ERROR_MESSAGE );
break;
}
catch( StreamCorruptedException sce )
{
JOptionPane.showMessageDialog( window, "Control information in the stream is inconsistent.", "Termination Error", JOptionPane.ERROR_MESSAGE );
break;
}
catch( OptionalDataException ode )
{
JOptionPane.showMessageDialog( window, "Primitive data was found in the stream instead of objects.", "Termination Error", JOptionPane.ERROR_MESSAGE );
break;
}
catch( IOException ioe)
{
//JOptionPane.showMessageDialog( null, "Any of the usual Input/Output related exceptions.", "Termination Error", JOptionPane.ERROR_MESSAGE );
break;
}
}
}
catch ( Exception ignored )
{
}
finally
{
stop();
}
}
//Broadcasts a message to all clients
protected void broadcast( Object clientMsg )
{
//Object streams have to be protected
synchronized ( handlers )
{
Enumeration enum = handlers.elements();
//Loop through all the clients
while ( enum.hasMoreElements() )
{
ChatHandler handler = ( ChatHandler ) enum.nextElement();
try
{
handler.out.writeObject( clientMsg );
out.flush();
}
catch ( IOException ex )
{
handler.stop();
}
}
}
}
}
//Listen to connection requests from clients
protected void listenForClients( ServerSocket server )
{
window.taMessages.append( "Listening For Connections...\n\n" );
int clientID = 0;
while ( true )
{
try
{
//Listen to socket. When request recieved start
//a handler and start listening again
Socket client = server.accept();
ChatHandler handler = new ChatHandler( ++clientID, client );
window.taMessages.append( "Connection accepted: "+ clientID + "\n" );
handler.start();
}
catch( IOException io_ex )
{
JOptionPane.showMessageDialog( window,"Cannot Setup Connection","Client Connection Error",JOptionPane.ERROR_MESSAGE );
}
}
}
protected void shutDown()
{
Enumeration enum = handlers.elements();
ServerShutDown shutdown = new ServerShutDown();
synchronized( handlers )
{
//Close connection to all clients.Stop all handlers
while ( enum.hasMoreElements() )
{
try
{
((ChatHandler)(handlers.firstElement())).out.writeObject(shutdown);
}
catch( Exception e )
{}
((ChatHandler)(handlers.firstElement())).stop();
}
}
System.exit(0);
}
//Save new configuration options to file
protected synchronized void setConfiguration( int newPort , int newLimit )
{
try
{
FileWriter configFile = new FileWriter("serverConfig.cfg");
//configFile.write( newPort );
configFile.write( newPort + ";"+ newLimit+";" );
//configFile.write( newLimit );
configFile.close();
serverLimit = newLimit;
}
catch( IOException io_e )
{
JOptionPane.showMessageDialog( window,"Cannot Save Configuration File","File Error",JOptionPane.ERROR_MESSAGE );
}
}
protected synchronized void getConfiguration()
{
try
{
char[] buffer = new char[15];
FileReader configFile = new FileReader("serverConfig.cfg");
configFile.read( buffer );
//String[] temp = ( String.copyValueOf( buffer ) ).split(";");
String value = String.copyValueOf( buffer );
String[] temp = value.split(";");
//system.out.println(temp[0]);
//system.out.println(temp[1]);
//serverPort = Integer.parseInt( temp[0] );
serverPort = Integer.parseInt( temp[0] );
//configFile.read( buffer );
serverLimit = Integer.parseInt( temp[1] );
configFile.close();
}
catch( FileNotFoundException fnf_e )
{
JOptionPane.showMessageDialog( null,"Configuration File Not Found, Using Defaults","Configuration File Missing",JOptionPane.ERROR_MESSAGE );
serverPort = 1665;
serverLimit = 20;
}
catch( IOException io_e )
{
JOptionPane.showMessageDialog( null,"Error Reading Configuration File, Using Defaults","Configuration Error",JOptionPane.ERROR_MESSAGE );
serverPort = 1665;
serverLimit = 20;
}
}
ChatServer()
{
getConfiguration();
onlineUsers=0;
try
{
//Bind server on socket,show interface and listen for
//client connection requests
server = new ServerSocket( serverPort );
handlers = new Vector();
window = new ServerInterface( this );
listenForClients( server );
}
catch( IOException io_e )
{
JOptionPane.showMessageDialog( null,"Cannot Start Server","ServerSocket Error",JOptionPane.ERROR_MESSAGE );
System.exit(0);
}
finally
{
try
{
if( server != null )
server.close();
}
catch( IOException e )
{}
}
}
public static void main( String[] args ) throws IOException
{
new ChatServer();
}
}
ServerInterface.java-chatserver
package chatserver;
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import protocols.*;
//MAIN INTERFACE CLASS
public class ServerInterface extends JFrame
{
protected JButton bExit;
protected JButton bKickOut;
protected JTextArea taMessages;
DefaultListModel clientList;
protected JList lstClients;
protected JToolBar tbServer;
protected JButton btbKickOut;
protected JButton btbExit;
protected JButton btbConfigure;
protected JButton btbHelp;
protected JMenuBar menuBar;
protected JMenu hlpMenu;
protected JMenu fileMenu;
protected JMenuItem exitFMenu;
protected JMenuItem webHlpMenu;
protected JMenuItem helpHlpMenu;
protected JMenuItem aboutHlpMenu;
protected JMenuItem configureFMenu;
protected JScrollPane scrlClients;
protected ChatServer server;
ServerInterface( ChatServer server )
{
super( "Fruit Cha(a)t Piyala" );
this.server = server;
setUpMenu();
setUpToolBar();
setUpMainInterface();
setVisible( true );
}
protected void setUpMenu()
{
exitFMenu = new JMenuItem("ShutDown",KeyEvent.VK_S);
webHlpMenu = new JMenuItem("Fruit Cha(a)t on the Web",KeyEvent.VK_W);
helpHlpMenu = new JMenuItem("Help",KeyEvent.VK_H);
aboutHlpMenu = new JMenuItem("About",KeyEvent.VK_A);
configureFMenu = new JMenuItem("Configure Server",KeyEvent.VK_C);
fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F);
fileMenu.add(configureFMenu);
fileMenu.add(exitFMenu);
hlpMenu = new JMenu("Help");
hlpMenu.setMnemonic(KeyEvent.VK_H);
hlpMenu.add(helpHlpMenu);
hlpMenu.addSeparator();
hlpMenu.add(webHlpMenu);
hlpMenu.add(aboutHlpMenu);
menuBar = new JMenuBar();
menuBar.add(fileMenu);
menuBar.add(hlpMenu);
setJMenuBar(menuBar);
}
protected void setUpToolBar()
{
tbServer = new JToolBar();
btbKickOut = new JButton(new ImageIcon("icons/link.gif") );
btbExit = new JButton(new ImageIcon("icons/logoff.gif") );
btbConfigure = new JButton( new ImageIcon("icons/log.gif") );
btbHelp = new JButton( new ImageIcon("icons/about.gif") );
btbExit.setToolTipText("Exit");
btbConfigure.setToolTipText("Configure");
btbHelp.setToolTipText("Help");
btbKickOut.setToolTipText("KickOut");
tbServer.add( btbConfigure );
tbServer.add( btbKickOut );
tbServer.add( btbExit );
//tbServer.addSeparator();
tbServer.setFloatable(false);
tbServer.setRollover(true);
tbServer.add( btbHelp );
}
protected void setUpListeners()
{
btbExit.addActionListener( new ExitButton() );
btbConfigure.addActionListener( new ConfigureFMenu() );
btbHelp.addActionListener( new HelpHlpMenu() );
btbKickOut.addActionListener( new KickOutButton() );
exitFMenu.addActionListener( new ExitButton() );
configureFMenu.addActionListener( new ConfigureFMenu() );
helpHlpMenu.addActionListener( new HelpHlpMenu() );
webHlpMenu.addActionListener( new WebHlpMenu() );
aboutHlpMenu.addActionListener( new AboutHlpMenu() );
bExit.addActionListener( new ExitButton() );
lstClients.addListSelectionListener( new clientSelected() );
bKickOut.addActionListener( new KickOutButton() );
addWindowListener( new OnExit() );
}
protected void setUpProperties()
{
setSize(570,465);
setResizable(false);
taMessages.setLineWrap(true);
taMessages.setEditable(false);
lstClients.setFixedCellWidth(100);
lstClients.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
bKickOut.setEnabled(false);
scrlClients = new JScrollPane( lstClients );
scrlClients.setColumnHeaderView( new JLabel(" Online Users" ) );
setUpListeners();
}
protected void setUpMainInterface()
{
bExit = new JButton( "Shut Down" );
bKickOut = new JButton( "Kick Out" );
taMessages = new JTextArea( 20,40 );
clientList = new DefaultListModel();
lstClients = new JList( clientList );
setUpProperties();
Box displayBox = Box.createHorizontalBox();
displayBox.add( new JScrollPane( taMessages ) );
displayBox.add( scrlClients );
JPanel buttonBox = new JPanel();
buttonBox.setLayout( new FlowLayout( FlowLayout.CENTER ) );
buttonBox.add( bKickOut );
buttonBox.add( bExit );
Container cp = this.getContentPane();
cp.setLayout( new BorderLayout() );
cp.add( tbServer,BorderLayout.NORTH );
cp.add( displayBox,BorderLayout.CENTER );
cp.add( buttonBox,BorderLayout.SOUTH );
/* Box toolbarBox = Box.createHorizontalBox();
toolbarBox.add( tbServer );
Box displayBox = Box.createHorizontalBox();
displayBox.add( new JScrollPane( taMessages ) );
displayBox.add( scrlClients );
Box buttonBox = Box.createHorizontalBox();
buttonBox.add( bKickOut );
buttonBox.add( Box.createHorizontalStrut(10) );
buttonBox.add( bExit );
Container cp = this.getContentPane();
cp.setLayout( new FlowLayout( FlowLayout.LEFT ) );
cp.add( tbServer );
cp.add( displayBox );
cp.add( buttonBox );*/
}
class OnExit extends WindowAdapter implements WindowListener
{
public void windowClosing( WindowEvent we )
{
server.shutDown();
}
}
class ExitButton implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
server.shutDown();
}
}
class KickOutButton implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
//Get index of the client that is to be kicked out
ChatServer.ChatHandler client = (ChatServer.ChatHandler)server.handlers.elementAt( lstClients.getSelectedIndex() );
try
{
//Notify the client
client.out.writeObject( new KickedOutNotice() );
}
catch( IOException w )
{}
//Stop the thread handling the client
client.stop();
bKickOut.setEnabled( false );
server.onlineUsers--;
}
}
class clientSelected implements ListSelectionListener
{
public void valueChanged( ListSelectionEvent e )
{
bKickOut.setEnabled(true);
}
}
class AboutHlpMenu implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
JOptionPane.showMessageDialog( server.window, "Fruit Cha(a)t Server"
+"\nVersion 0.7 \nThis software is distributed under the GPL Liscence",
"About Fruit Cha(a)t", JOptionPane.INFORMATION_MESSAGE );
}
}
class HelpHlpMenu implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
/* to implement some help for the user of the server */
}
}
class WebHlpMenu implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
JOptionPane.showMessageDialog( server.window, "For free source code visist http://akbani.20m.com.", "Fruit Cha(a)t on the WEB", JOptionPane.INFORMATION_MESSAGE );
}
}
class ConfigureFMenu implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
ConfigureServerInfo serverDialog = new ConfigureServerInfo();
}
}
//CREATES AND DISPLAYS THE CONFIGURE DIALOG
class ConfigureServerInfo extends JDialog
{
JButton bSave = new JButton("Save");
JButton bCancel = new JButton("Cancel");
JLabel lbPort = new JLabel("Port Number : ");
JLabel lbLimit = new JLabel("Client Limit : ");
JTextField tfLimit = new JTextField(6);
JTextField tfPortNo = new JTextField(6);
ConfigureServerInfo()
{
super(server.window,"Configure Server",true);
Box buttonBox = Box.createHorizontalBox();
buttonBox.add( Box.createHorizontalStrut(15) );
buttonBox.add(bSave);
buttonBox.add(bCancel);
Container jcp = this.getContentPane();
jcp.setLayout( new FlowLayout(FlowLayout.LEFT) );
jcp.add(lbPort);
jcp.add(tfPortNo);
jcp.add( lbLimit );
jcp.add( tfLimit );
jcp.add( buttonBox );
bSave.addActionListener( new SaveButton() );
bCancel.addActionListener( new CancelButton() );
server.getConfiguration();
tfPortNo.setText( Integer.toString( server.serverPort ) );
tfLimit.setText( Integer.toString( server.serverLimit ) );
this.setSize(180,115);
Point position = server.window.getLocation();
position.x = position.x + (server.window.getWidth()/2) - (this.getWidth()/2);
position.y = position.y + (server.window.getHeight()/2) - (this.getHeight()/2);
this.setLocation( position );
this.setVisible(true);
this.setResizable( false );
}
class SaveButton implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
server.setConfiguration( Integer.parseInt(tfPortNo.getText()) , I
nteger.parseInt(tfLimit.getText()) );
//setVisible(false);
dispose();
}
}
class CancelButton implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
dispose();
}
}
}
}
//chatrequest.java--protocols
package protocols;
import java.io.*;
public class ChatRequest implements Serializable
{
public int senderId;
public int recieverId;
}
//clientinfo.java--protocols
package protocols;
import java.io.*;
public class ClientInfo implements Serializable
{
public int clientId;
public String clientName;
}
//connectionnotice.java--protocols
package protocols;
import java.io.*;
public class ConnectionNotice implements Serializable
{
public boolean status; //false=reject, true=accept
}
//joinchatroom.java--protocols
package protocols;
import java.io.*;
public class JoinChatRoom implements Serializable
{
public boolean requestType;
public int roomNumber;
}
//kikedoutnotice--protocols
package protocols;
import java.io.*;
public class KickedOutNotice implements Serializable
{
public int roomNumber;
}
//logout.java--protocols
package protocols;
import java.io.*;
public class LogOut implements Serializable
{}
//messageserver.java-protocols
package protocols;
import java.io.*;
public class Message implements Serializable
{
public boolean audience; //room=true, private=false
public short roomNumber;
public int recieverId;
public int senderId;
public String message;
}
//servershutdown.java--protocols
package protocols;
import java.io.*;
public class ServerShutDown implements Serializable
{}
//updatelist.java--protocols
package protocols;
import java.io.*;
public class UpdateList implements Serializable
{
public boolean requestType;
public String newClient;
}
--How to run
Project Name : Fruit Cha(a)t
FIRST WAY
Compile the application first using Compile.bat. See how to compile for
details.
To start server run StartServer.bat
To start client run StartClient.bat
SECOND WAY
To start server double click on Server.jar
To start client double clieck on Client.jar
THIRD WAY
To start server run RunServerJar.bat
To start client run RunClientJar.bat
--projectDocumentation
Project Description
A chatting software based loosely on IRC system. There is a central server handling all communications to and from clients. Each user can run the client program and connect to server to start chatting. All clients and server will have list of online users. List is updated as soon as the status of some client changes. There is one main chat room in which all messages can be seen by all clients. Users can also choose to chat in private with any one on the list. Multiple chat rooms have not been implemented but provisions are provided in code for easy deployment.
Client – Server Communication
The server is bound to a fixed socket and listens for connection requests from clients. The clients try to connect to server on this port and predefined host. Once the communication channels are set up, both talk in terms of objects defined as protocols. Upon receiving these objects the program then extracts relevant information and takes appropriate actions. All communications are through server and may change the protocol parameters if required.
Protocols
Self designed protocols have been defined to enable communications between server amd clients. Protocols have primarily been defined as classed which have required parameters. The objects of these classes are then exchanged
Message Protocol
This defines how messages are to be handled between users and server. The user can send public and private message. For private message it is important to know the recipient and the sender of the message.
Fields
· Audience – public or private message
· RoomNumber – Currently of no use. In future can be used for multiple rooms
· RecieverId – Id of the recipient. Usefull only for private messages
· SenderId – Id of sender. Usefull only for private messages
· Message – Text that the user wants to send
Client Information Protocol
This is meant to exchange client information between user and server. When a new client connects to the server its relevant information is kept in an object of this class. Other users are notified of arrival of new client using information from this protocol.
Fields
· ClientId – Identification number of client within the server.
· ClientName – The login name provided by the user.
Chat Request Protocol
This protocol is used to notify a client that another client want to start a private chat with it. A message of this type must be sent before any private conversation can start. This message is sent when user chooses to start a private conversation. Upon receiving this request the recipient's client takes steps to receive private messages from the server by the specified sender.
Fields
· SenderId – The clientId of the client machine that initiated the request.
· RecieverId – The clientId of the client machine that is to be notified.
Update Client List Protocol
When a new user logs in to the server all clients have to be notified of this arrival. Also when a user logs out, all users must be notified. This protocol is used to simplify this process. A message of this type with the new clients name is broadcast to all client machines.
Fields
· Request Type – Indicates if the user has to be added or removed
· ClientName – The name of the client that the information is about
Log Out Protocol
When a user chooses to logout of the system the server and all other users must be notified. Upon users choice the local client machine sends a message of this type to the server. Upon receiving this message the server forwards it to all clients. Then breaks connection with the client.
There are no fields
Shut Down Protocol
If the server has to be shut down it must notify the clients. This message is broadcast to all clients that they must close their connections.
There are no fields
Join Chat Room Protocol
This protocol is reserved for when multiple char rooms will be implemented.
Fields
· Request Type -- Indicates if the user has to be added or removed
· Room Number – RoomId of the room that the user wants to join
Kicked Out Notice Protocol
If the administrator chooses to kick out a user the server must send this message to the kicked out client. The client is told out of which room the user has been kicked out of. If the user is kicked out of the main room it is equivalent of a forced log out.
Fields
· RoomNumber – Indicates which room the user has been kicked out of
Scope And Limitations
1. Multiple chat rooms.
2. Invite other users to a private chat.
3. Chat client available as applet
4. Cannot recover from certain errors
Server Interface
The interface has been developed in Swing. Interface has been kept separate from the network processes. The main components of the server interface are as follows
· Messages Area : Connection acceptance, rejection, login messages are shown here.
· List Of Online Users : On the right side of the message window is the list of users that are connected to the server currently. A user can be selected from this list by clicking on name.
· Configure Server Dialog : This dialog is shown when option is selected from the menu. This dialog will allow new values and saving to configuration file.
· Main Menu : The options available for the server. The options include configure server, shutdown server
Client Interface
The interface has been developed in Swing. Interface has been kept separate from the network processes. The main components of the client interface are as follows
· Message Tabs : These are the conversation tabs. All conversation windows are kept within these tabs.
· Message Entry Field : This is place at the bottom of the window. This is where the user enters whatever message he/she wants to send. Message is sent by either pressing enter or pressing the send button. Where the message is sent depends on which tab is open
· Online User List : This list shows all the users who are logged in at the server. Double clicking on a user will open a conversation window with him.
· Configure Dialog : This dialog is shown when option is selected from the menu. This dialog will allow new values and saving to configuration file. You can change server host name and port.
· Main Menu : The options available for the server. The options include connect, disconnect, configure, exit, close current tab, close all tabs, Help
Bibliography
? Thinking in Java 2nd Edition – BruceEckel – http://www.BruceEckel.com – Java Programming
? Java Network Programming 2nd Edition – Merlin Hughes,Michael Shoffner, Derek Hamner – http://nitric.com/jnp/ -- Network Specific Java Programming
? Java 2 Black Book – Steven Holzner – Swing
? Sun's Java Tutorial -- http://java.sun.com/docs/books/tutorial – Swing and Updated Methods
? Planet Source Code – http://www.planet-source-code.com -- Sample Codes
Appendix A : Error Messages
Server Error Messages
Message Reason Solution
Class of a serialized object cannot be found Error in communication between server and client Press OK. If keeps repeating shutdown
Something is wrong with a class used by serialization. Error in communication between server and client Press OK. If keeps repeating shutdown
Control information in the stream is inconsistent. Error in communication between server and client Press OK. If keeps repeating shutdown
Primitive data was found in the stream instead of objects. Error in communication between server and client Press OK. If keeps repeating shutdown
Cannot Setup Connection Error establishing connection with client Just Press OK. If keeps repeating shutdown
Cannot Save Configuration File Error saving configuration options to file Retry Configuring. If keeps repeating check if file is corrupted
Configuration File Not Found, Using Defaults Error finding and opening configuration file. Press OK. If keeps repeating check if file has been deleted.
Error Reading Configuration File, Using Defaults File found but cannot be read. File may be created Retry Configuring. If keeps repeating check if file is corrupted
Cannot Start Server Another program may be using the port on the machine Shutdown other program if possible. Else change port number in the configuration file
Error closing connection to client Error while trying to break connection with client Press OK.
Client Error Messages
Message Reason Solution
Server Has Been Shut Down Server Has Been Shut Down Press OK. Reconnect later
Server Kicked You Out Administrator kicked you out Press OK. Reconnect later
Class of a serialized object cannot be found Error in communication between server and client Press OK. Reconnect later
Something is wrong with a class used by serialization. Error in communication between server and client Press OK. Reconnect later
Control information in the stream is inconsistent. Error in communication between server and client Press OK. Reconnect later
Primitive data was found in the stream instead of objects. Error in communication between server and client Press OK. Reconnect later
Cannot Save Configuration File Error saving configuration options to file Retry Configuring. If keeps repeating check if file is corrupted
Configuration File Not Found, Using Defaults Error finding and opening configuration file. Press OK. If keeps repeating check if file has been deleted.
Error Reading Configuration File, Using Defaults File found but cannot be read. File may be created Retry Configuring. If keeps repeating check if file is corrupted
Host Not Found, Reconfigure Server host machine cannot be found. Check your configuration, change if neccessary
Server Not Found, Check If Server Exists No server could be found listening to the port on the specified machine Server may not have been started. Retry later.
Cannot Create Data Stream, Closing Client Connection Established but data stream cannot be resolved Recconnect later
Name Already In Use. Change Login Name Someone has already logged in with your chosen name Recconnect and choose a different name.
Maximum User Limit Reached. Server Rejected Connection Maximum number of users allowed have connected to server. Try connecting later
Appendix B:
Main Classes and their functionalities.
Chat Server:
This is the main class of the Fruit Cha(a)t Server. It provides the core functionality of the server and is responsible for handling clients and their connections. Information about all clients is kept in this class. Error handling has been done in this class. An object of chat handler is created fro each client.
Chat Handler:
This is an inner class in the chat server. This is basically responsible for handling each individual clients i.e. their sockets, the input and output stream. It runs as a separate thread for each client. Creation and deletion of the connection and broadcasting of message is done in this class.
Server Interface:
This is the class responsible for the GUI provided to the server administrator. The administrator is provided with an easy to use interface providing multiple paths to carry out a particular task. Menus have been incorporated and buttons are also placed on the screen to provide assistance to the user of the server. Error Messages from the chat server class are displayed in this class.
Chat Client:
This is the main class of the Fruit Cha(a)t Client. It provides the core functionality of the client and is responsible for making connection with the server and sending and receiving messages and classifying them according to the used protocols. Error handling has been done in this class.
Client Interface:
This class is responsible for the GUI of the client part of the application. Again a user friendly interface has been provided to the user for easy usage of the software. Multiple paths have been provided to carry out a particular task. User can view the messages sent in the main room as well switch to the different tabs provided to use the private chat option of the application. Errors captured in the chat client class are displayed in this class.
Input Listener:
This is an inner class in the chat client. This class is sub class of the thread class. This class listens to the incoming transmissions from the chat server. The objects are then classified according to the protocols and then the appropriate action is taken by the other classes.
-------------------END-------------------------
Best Projects
Bug Trackingsystem,Books online shopping,college management system,HR management system,Internet banking,Online chat room ,Online exam,Telephone billing system,Banking application,ATM database,airways reservation system,virtual network computing ,calculator,SMTP(simple mail transfer protocol)
Archives
-
▼
2008
(101)
-
▼
July
(67)
- Adapter_Demo__Mini
- Applet_Add__Mini
- Applet_Frame__Mini
- Applet_Window__Mini
- Banner__Mini
- Browser__Mini
- Choice_List__Mini
- Clint_Test__Mini
- Color_Demo__Mini
- Double_Buffer__Mini
- First_Applet__Mini
- Grid__Mini
- HServlet__Mini
- Image_Load__Mini
- Image_Swing__Mini
- Inetaddress_Demo1__Mini
- InnerClassdemo__Mini
- Java_Buttons__Mini
- Java_Label__Mini
- Jdbc_test1__Mini
- Jdbc update__Mini
- Jlabeldemo__Mini
- JScrollPaneDemo_Mini
- Key_Events_Mini
- Lawte_Mini
- List_Demo_Mini
- Logo_Mini
- Observed_ImageLoad_Mini
- Rectangles_Mini
- Resize_Me_Mini
- Sample_Applet_Mini
- Sb_Demo_Mini
- Server_Test_Mini
- Servlet_Database_Mini
- servlet_To_Applet_Mini
- Simple_Key_Mini
- Text_Demo_Mini
- Textarea_Demo_Mini
- UDP_Server_Mini
- UDPClient_Mini
- Window_Events_Mini
- Advertising Agency
- Books Online Shopping
- BugTracking System
- College Management Sysyetm
- Doctors
- Human Resource Management System
- Internet Banking
- Intranet Chatting
- Java_Mail_Filter
- MIS Coding Nokia Soft
- Online Cources
- Online Exam
- Power Point Sliding
- Practical_Aircraft_Position
- project planning management
- Puyo Puyo game
- Sliding Window Protocol
- Telephone Billing system
- Voice over internet protocol
- No title
- Banking Application
- ATM Database
- airways reservation system
- Chat Room Application
- Snake(applet)
- Poor Man's PaintShop
-
▼
July
(67)
1 comment:
Free Cisco eBooks – Download
http://career-assessments.blogspot.com/2008/01/cisco-certifications-aspirants.html
Looking for Cisco Certification
http://career-assessments.blogspot.com/2008/01/cisco-certifications-newbies.html
Important Networking Information
http://ccnahelpguides.blogspot.com
Post a Comment