package muti_user_chat;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* A simple Swing-based client for the chat server. Graphically
* it is a frame with a text field for entering messages and a
* textarea to see the whole dialog.
*
* The client follows the Chat Protocol which is as follows.
* When the server sends "SUBMITNAME" the client replies with the
* desired screen name. The server will keep sending "SUBMITNAME"
* requests as long as the client submits screen names that are
* already in use. When the server sends a line beginning
* with "NAMEACCEPTED" the client is now allowed to start
* sending the server arbitrary strings to be broadcast to all
* chatters connected to the server. When the server sends a
* line beginning with "MESSAGE " then all characters following
* this string should be displayed in its message area.
*/
public class ChatClient1 {
BufferedReader in;
PrintWriter out;
String MyName = null;
JFrame frame = new JFrame("Chat Box");
JTextField textField = new JTextField(40);
JTextArea messageArea = new JTextArea(8, 40);
JTextArea ClientsAvailable = new JTextArea(9, 10);
JButton sendButton = new JButton("Send");
JButton SignoutButton = new JButton("Sign Out");
JTextField statusColor = new JTextField(1);
JLabel statusField = new JLabel();
JPanel Pane = new JPanel(new BorderLayout()); //Im main panel.
JPanel DisplayBar = new JPanel(new BorderLayout()); //I hold text areas
JPanel InputBar = new JPanel(new BorderLayout());
//I hold input box and button
JPanel statusBar = new JPanel(new BorderLayout()); //I hold Status details
/**
* Constructs the client by laying out the GUI and registering a
* listener with the textfield so that pressing Return in the
* listener sends the textfield contents to the server. Note
* however that the textfield is initially NOT editable, and
* only becomes editable AFTER the client receives the NAMEACCEPTED
* message from the server.
*/
public ChatClient1() {
// Layout GUI.
// Set some defaults.
textField.setEditable(false);
messageArea.setEditable(false);
ClientsAvailable.setEditable(false);
statusColor.setBackground(Color.red);
statusField.setText("Not Yet Connected");
sendButton.setSize(10,10);
//SignoutButton.setSize(10, 10);
//add respective components to their panels.
DisplayBar.add(new JScrollPane(messageArea), BorderLayout.WEST);
DisplayBar.add(new JScrollPane(ClientsAvailable), BorderLayout.EAST);
InputBar.add(textField, BorderLayout.WEST);
InputBar.add(sendButton, BorderLayout.CENTER);
statusBar.add(statusColor, BorderLayout.WEST);
statusBar.add(statusField, BorderLayout.CENTER);
//statusBar.add(SignoutButton, BorderLayout.EAST);
//add panels to main panel.
Pane.add(DisplayBar, BorderLayout.NORTH);
Pane.add(InputBar,BorderLayout.CENTER);
Pane.add(statusBar, BorderLayout.SOUTH);
//add main panel to frame.
frame.setContentPane(Pane);
//pack the frame for display.
frame.pack();
frame.setLocation(200, 200);
// Add Listeners
textField.addActionListener(new ActionListener() {
/**
* Responds to pressing the enter key in the textfield by sending
* the contents of the text field to the server. Then clear
* the text area in preparation for the next message.
*/
public void actionPerformed(ActionEvent e) {
System.out.println(textField.getText());
out.println(textField.getText());
textField.setText("");
}
});
sendButton.addActionListener(new ActionListener() {
/**
* Responds to clicking the button by sending
* the contents of the text field to the server. Then clear
* the text area in preparation for the next message.
*/
public void actionPerformed(ActionEvent e) {
System.out.println(textField.getText());
out.println(textField.getText());
textField.setText("");
}
});
}
/**
* Prompt for and return the address of the server.
*/
private String getServerAddress() {
return JOptionPane.showInputDialog(
frame,
"Enter IP Address of the Server:",
"Welcome to the Chat Box",
JOptionPane.QUESTION_MESSAGE);
}
/**
* Prompt for and return the desired screen name.
*/
private String getName() {
return JOptionPane.showInputDialog(
frame,
"Choose a screen name:",
"Screen name selection",
JOptionPane.PLAIN_MESSAGE);
}
/**
* Connects to the server then enters the processing loop.
*/
private void run() throws IOException {
// Make connection and initialize streams
String serverAddress = getServerAddress();
Socket socket = new Socket(serverAddress, 9001);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// Process all messages from server, according to the protocol.
while (true) {
String line = in.readLine();
if (line.startsWith("SUBMITNAME"))
{
//this takes the input name and sends it to server.
MyName = getName();
out.println(MyName);
} else if (line.startsWith("NAMEACCEPTED"))
{
// this sets input text area edit_able and also changes the status to ready.
textField.setEditable(true);
frame.setTitle(MyName + "'s Chat Box");
statusColor.setBackground(Color.green);
statusField.setText("Hi "+MyName+"..! U R Connected to Server");
} else if (line.startsWith("MESSAGE")) {
//this adds the broad casted message to top left text area.
messageArea.append(line.substring(8) + "\n");
}else if (line.startsWith("USERS"))
{
// This part of the code adds the new user list along with my self to top right text area.
line = line.substring(7);
line = line.replace("]", "");
ClientsAvailable.setText("");
String[] Users = line.split(",");
for (String user : Users)
{
ClientsAvailable.append(user + "\n");
}
}
}
}
/**
* Runs the client as an application with a closeable frame.
*/
public static void main(String[] args) throws Exception {
ChatClient1 client = new ChatClient1();
client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.frame.setVisible(true);
client.run();
}
}
References:
- V Karthik`s explination of socket programming!
- Loyola Marymount University.