Hi I've been working on a Server/Client Chat Program in which I need a GUI for the client . I've got the basic console Client/Server communicating correctly but I can't get the input/output of the client to display on the Client GUI can somebody please take a look and give me suggestions on as to how I can get the output of the Client to work on the ClientGUI using the text field as input and then broadcasting it to the text area? I've placed my code below.
DATA OBJECT
import java.io.*;
import java.net.*;
public class DataObject implements Serializable{
String message;
public DataObject(){}
public DataObject(String message){
setMessage(message);
}
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
return message;
}
}
ThreadedChatServer
import java.io.*;
import java.net.*;
import java.util.*;
public class ThreadedChatServer{
ThreadedChatClient tcg;
int port;
public ThreadedChatServer(int port){
this.port=port;
try{
ArrayList<ThreadedChatHandler> handlers = new ArrayList<ThreadedChatHandler>();
ServerSocket ss = new ServerSocket(port);
for(;;){
System.out.println("Waiting for clients on port " +port+"...");
System.out.println("If running client from console type 'java ThreadedChatClient [String Username] [String host] [int Port]'");
Socket s = ss.accept();
System.out.println("New user has entered.");
new ThreadedChatHandler(s, handlers).start();
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}
public static void main(String[] args){
ThreadedChatServer tcs= new ThreadedChatServer(1999);
}
}
class ThreadedChatHandler extends Thread{
ThreadedChatClient tcg;
public ThreadedChatHandler(Socket s, ArrayList<ThreadedChatHandler> list){
this.s = s;
this.list = list;
this.list.add(this);
}
public synchronized void broadcast(DataObject d) throws IOException{
for(ThreadedChatHandler handler: list){
handler.oos.writeObject(d);
}
}
public void run(){
try{
ois = new ObjectInputStream(s.getInputStream());
oos = new ObjectOutputStream(s.getOutputStream());
objIn= new DataObject( "User has entered.");
broadcast(objIn);
while(true){
obj = (DataObject)ois.readObject();
broadcast(obj);
}
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
try{
objOut= new DataObject("User has left.");
broadcast(objOut);
list.remove(this);
ois.close();
oos.close();
s.close();
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
}
}
DataObject obj,objIn,objOut;
Socket s;
ArrayList<ThreadedChatHandler> list;
ObjectInputStream ois;
ObjectOutputStream oos;
}
ThreadedChatClient
DataObject in, out;
ObjectOutputStream oos;
ObjectInputStream ois;
Scanner scan;
String username;
ChatClientGUI cg;
public ThreadedChatClient(String username,String host,int port){
this.username=username;
scan = new Scanner(System.in);
try{
s = new Socket(host,port);
oos = new ObjectOutputStream(s.getOutputStream());
}catch(Exception e){
System.out.println(e.getMessage());
}
this.start();
for(;;){
String temp = scan.nextLine();
out = new DataObject(temp);
try{
out.setMessage(username+": "+out.getMessage());
oos.writeObject(out);
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
public void run(){
try{
ois = new ObjectInputStream(s.getInputStream());
}catch(Exception e){
System.out.println(e.getMessage());
}
for(;;){
try{
in = (DataObject)ois.readObject();
}catch(Exception e){
System.out.println(e.getMessage());
}
System.out.println(in.getMessage());
}
}
public static void main(String[] args){
ThreadedChatClient c = new ThreadedChatClient(args[0],args[1],Integer.parseInt(args[2]));
}
}
ChatClientGUI
import java.awt.*;
import java.awt.event.*;
public class ChatClientGUI extends Frame implements ActionListener{
Canvas c;
TextField tfServer,tfPort,tfUsername,tf;
TextArea ta;
int defaultPort;
String defaultHost,defaultUsername;
Label label;
Button b,b2;
List lst;
ThreadedChatClient cc;
int finalY,finalX;
public ChatClientGUI(String username,String host,int port){
super("ChatClientGUI");
defaultPort = port;
defaultHost = host;
defaultUsername= username;
setSize(600,600);
addWindowListener(new WindowAdapter (){
public void windowClosing(WindowEvent we){
System.exit(0);
}
});
Panel nPanel = new Panel(new GridLayout(3,1));
Panel serverAndPort = new Panel(new GridLayout());
tfServer = new TextField(host);
tfServer.addActionListener(this);
tfPort = new TextField("" + port);
tfPort.addActionListener(this);
tfUsername= new TextField(defaultUsername);
tfUsername.addActionListener(this);
serverAndPort.add(new Label("Username:"));
serverAndPort.add(tfUsername);
serverAndPort.add(new Label("Server Address: "));
serverAndPort.add(tfServer);
serverAndPort.add(new Label("Port Number: "));
serverAndPort.add(tfPort);
nPanel.add(serverAndPort);
label = new Label("Enter your message below");
nPanel.add(label);
tf = new TextField();
tf.setBackground(Color.WHITE);
nPanel.add(tf);
add(nPanel, BorderLayout.NORTH);
////
Panel cPanel= new Panel(new GridLayout(2,1));
ta= new TextArea();
cPanel.add(ta);
ta.setEditable(false);
c=new Canvas();
c.setBackground(Color.BLACK);
c.setForeground(Color.WHITE);
c.setEnabled(true);
cPanel.add(c);
add(cPanel,BorderLayout.CENTER);
//////
Panel sPanel= new Panel(new GridLayout());
Panel inOutPanel= new Panel(new GridLayout());
b= new Button("Login");
b.addActionListener(this);
b.setBackground(Color.GREEN);
inOutPanel.add(b);
b2= new Button("Logout");
b2.addActionListener(this);
b2.setBackground(Color.RED);
b2.setEnabled(false);
inOutPanel.add(b2);
lst = new List(4,false);
lst.add("*List Of Users*");
inOutPanel.add(lst);
sPanel.add(inOutPanel);
add(sPanel,BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent e) {
Object o= e.getSource();
if(o==b){
int por=0;
por = Integer.parseInt(tfPort.getText());
ta.append(tfUsername.getText()+" has entered the chat.\n");
b.setEnabled(false);
b2.setEnabled(true);
tfUsername.setEditable(false);
tfServer.setEditable(false);
tfPort.setEditable(false);
lst.add(tfUsername.getText());
tf.setEditable(true);
tf.addActionListener(this);
cc= new ThreadedChatClient(tfUsername.getText(),tfServer.getText(),por);
}
if(o==b2){
ta.append(tfUsername.getText()+" has left the chat.\n");
b.setEnabled(true);
b2.setEnabled(false);
tf.setEditable(false);
tfUsername.setEditable(true);
tfServer.setEditable(true);
tfPort.setEditable(true);
tf.removeActionListener(this);
lst.remove(tfUsername.getText());
}
if(o==tf){
DataObject objt=new DataObject(tfUsername.getText()+": "+tf.getText()+"\n");
ta.append(tfUsername.getText()+": "+tf.getText()+"\n");
tf.setText("");
}
if(o==c){
c.setBackground(Color.BLUE);
}
}
public static void main(String [] args){
ChatClientGUI cc= new ChatClientGUI("unknown","localhost",1999);
cc.setVisible(true);
}
}
Thanks in advance for your help.
Related
I am using Java sockets to create a simple chat room and using AWT component for the GUI. I have all functions of the chat room working, it sends and recieves messages to/from all users, etc... One requirement was to make a list that updates as users enter and leave the chat. I have this function working and my solution was to have my server print the current names of the handlers to a file and then the client grabs the names from the file and adds it to the list. To do this, I made a method that I put in a for(;;) loop so the list continuously updates as users enter/ leave the chat. These requirements all work fine...
MY PROBLEM: The next requirement states: "A user should be able to select a single user from the user list. While a name is selected, all messages sent will be private - only sent to that user." I cannot figure out how to get the selected name back to the server so that someone can send messages only to the username that is selected. Is this even possible with the way I handled creating my list? If so do you have any ideas on how to make this possible? I've been stumped on this for a few days and I am almost thinking at this point that it is not possible and I should rethink my logic for the list. If it is not possible, do you have any ideas for a better solution for my list?
Thank you!
Client file:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
public class ClientFrame extends Frame{
public ClientFrame(){
setSize(500,500);
setTitle("Chat Client");
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent We){
System.exit(0);
}
});
add(new ClientPanel(new FrameContainer(this)), BorderLayout.CENTER);
setVisible(true);
}
public static void main(String[] args){
new ClientFrame();
}
} // end ClientFrame
class ClientPanel extends Panel implements ActionListener, Runnable, ItemListener{
TextField tf;
TextArea ta;
List list;
Button connect, disconnect;
Socket socketToServer;
PrintWriter pw;
BufferedReader br;
Thread t;
String userName;
FrameContainer fc;
public ClientPanel(FrameContainer fc){
setLayout(new BorderLayout());
tf = new TextField();
ta = new TextArea();
list = new List();
this.fc = fc;
connect = new Button("Connect");
disconnect = new Button("Disconnect");
Panel bPanel = new Panel();
bPanel.add(connect);
disconnect.setEnabled(false);
bPanel.add(disconnect);
tf.addActionListener(this);
connect.addActionListener(this);
disconnect.addActionListener(this);
list.addItemListener(this);
add(tf, BorderLayout.NORTH);
add(ta, BorderLayout.CENTER);
add(list, BorderLayout.EAST);
add(bPanel, BorderLayout.SOUTH);
} // end ClientPanel constructor
public void actionPerformed(ActionEvent ae){
if (ae.getSource() == tf){
String temp = tf.getText();
pw.println(userName+": "+temp);
tf.setText("");
} else if (ae.getSource() == connect){
if(tf.getText() == null || tf.getText().equals("")){
ta.append("Must enter a name to connect\n");
}else {
setUsername(tf.getText());
fc.getFrame().setTitle(userName);
connect.setEnabled(false);
disconnect.setEnabled(true);
tf.setText("");
try{
socketToServer = new Socket("127.0.0.1", 3000);
pw = new PrintWriter(new OutputStreamWriter
(socketToServer.getOutputStream()), true);
br = new BufferedReader(new InputStreamReader
(socketToServer.getInputStream()));
}catch(UnknownHostException uhe){
System.out.println(uhe.getMessage());
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
}
t = new Thread(this);
t.start();
pw.println(userName);
pw.println(userName +" has entered the chat.");
}else if (ae.getSource() == disconnect){
try{
pw.println(userName +" has left the chat.");
list.removeAll();
fc.getFrame().setTitle("Chat Client");
t.interrupt();
br.close();
pw.close();
socketToServer.close();
connect.setEnabled(true);
disconnect.setEnabled(false);
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
}
} // end actionPerformed
public void itemStateChanged(ItemEvent ie){
if(ie.getStateChange() == ItemEvent.SELECTED){
String user = list.getSelectedItem();
}else if(ie.getStateChange() == ItemEvent.DESELECTED){
break;
}
} // end itemStateChanged
public void run(){
try {
for (;;) {
if(socketToServer.isClosed() == true) {
break;
}
setList();
try {
String temp = br.readLine();
ta.append(temp + "\n");
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println("Disconnected.");
}
} // end run
public void setList(){
list.removeAll();
try{
BufferedReader br = new BufferedReader(
new FileReader("onlinelist.txt"));
String line;
while((line = br.readLine()) != null){
this.list.add(line);
}
br.close();
}catch(FileNotFoundException fnfe){
System.out.println(fnfe.getMessage());
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
} // end setList
public void setUsername(String userName){
this.userName = userName;
}
public String getUsername(){
return userName;
}
} // end ClientPanel
// Container class to change title of frame
class FrameContainer{
ClientFrame f;
public FrameContainer(ClientFrame f){
setFrame(f);
}
public ClientFrame getFrame(){
return f;
}
public void setFrame(ClientFrame f){
this.f = f;
}
}
Server file:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.awt.*;
public class ThreadedServerWithPresence{
public static void main(String[] args){
ArrayList<ThreadedHandlerWithPresence> handlers;
try{
handlers = new ArrayList<ThreadedHandlerWithPresence>();
ServerSocket s = new ServerSocket(3000);
for(;;){
Socket incoming = s.accept();
new ThreadedHandlerWithPresence(incoming,
handlers).start();
}
}catch (Exception e){
System.out.println(e);
}
}
}
class ThreadedHandlerWithPresence extends Thread{
Socket incoming;
ArrayList<ThreadedHandlerWithPresence> handlers;
PrintWriter pw;
BufferedReader br;
String userName;
ArrayList<String> list;
public ThreadedHandlerWithPresence(Socket i,
ArrayList<ThreadedHandlerWithPresence> handlers){
incoming = i;
this.handlers = handlers;
handlers.add(this);
list = new ArrayList<String>();
}
public void setUserName(String userName){
this.userName = userName;
}
public String getUserName(){
return userName;
}
public void run(){
try{
br = new BufferedReader(new InputStreamReader
(incoming.getInputStream()));
pw = new PrintWriter(new OutputStreamWriter
(incoming.getOutputStream()),true);
setUserName(br.readLine());
createList();
for(;;){
String temp = br.readLine();
if(temp == null)
break;
System.out.println("Message read: " + temp);
for(int i = 0; i < handlers.size(); i++){
handlers.get(i).pw.println(temp);
}
}
}catch (Exception e){
System.out.println(e);
}finally{
handlers.remove(this);
createList();
}
}
public void createList(){
try{
PrintWriter p = new PrintWriter(
new FileWriter("onlinelist.txt"));
for(int i = 0; i < handlers.size(); i++){
p.println(handlers.get(i).getUserName());
}
p.close();
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
}
}
so here is my code :
Server.java
import java.io.*;
import java.net.*;
import java.util.*;
class Server implements Runnable{
Socket connectionSocket;
public static Vector clients=new Vector();
public Server(Socket s){
try{
System.out.println("Client Got Connected " );
connectionSocket=s;
}catch(Exception e){e.printStackTrace();}
}
public void run(){
try{
BufferedReader reader =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
BufferedWriter writer=
new BufferedWriter(new OutputStreamWriter(connectionSocket.getOutputStream()));
clients.add(writer);
while(true){
String data1 = reader.readLine().trim();
System.out.println("Received : "+data1);
for (int i=0;i<clients.size();i++){
try{
BufferedWriter bw= (BufferedWriter)clients.get(i);
bw.write(data1);
bw.write("\r\n");
bw.flush();
}catch(Exception e){e.printStackTrace();}
}
}
}catch(Exception e){e.printStackTrace();}
}
public static void main(String argv[]) throws Exception{
System.out.println("Threaded Chat Server is Running " );
ServerSocket mysocket = new ServerSocket(5555);
while(true){
Socket sock = mysocket.accept();
Server server=new Server(sock);
Thread serverThread=new Thread(server);
serverThread.start();
}
}
}
mychat.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class mychat implements Runnable
{
public JTextField tx;
public JTextArea ta;
public String login="Imed";
BufferedWriter writer;
BufferedReader reader;
public mychat(String l)
{
login=l;
ClientName z = new ClientName();
JFrame f=new JFrame(z.getName()+"'s Chat");
f.setSize(400,400);
JPanel p1=new JPanel();
p1.setLayout(new BorderLayout());
JPanel p2=new JPanel();
p2.setLayout(new BorderLayout());
tx=new JTextField();
p1.add(tx, BorderLayout.CENTER);
JButton b1=new JButton("Send");
p1.add(b1, BorderLayout.EAST);
ta=new JTextArea();
p2.add(ta, BorderLayout.CENTER);
p2.add(p1, BorderLayout.SOUTH);
f.setContentPane(p2);
try
{
Socket socketClient= new Socket("localhost",5555);
writer= new BufferedWriter(new OutputStreamWriter(socketClient.getOutputStream()));
reader =new BufferedReader(new InputStreamReader(socketClient.getInputStream()));
}
catch(Exception e){e.printStackTrace();}
b1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ev)
{
String s=login+" : "+tx.getText();
tx.setText("");
try
{
writer.write(s);
writer.write("\r\n");
writer.flush();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
);
f.setVisible(true);
}
public void run()
{
try
{
String serverMsg="";
while((serverMsg = reader.readLine()) != null)
{
System.out.println("from server: " + serverMsg);
ta.append(serverMsg+"\n");
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
startclient.java
public class startclient
{
public static void main(String [] args)
{
try
{
ClientName n = new ClientName();
mychat c=new mychat(n.getName());
Thread t1=new Thread(c);
t1.start();
}
catch(Exception e){e.printStackTrace();}
}
}
And last ClientName.java
import java.util.*;
public class ClientName
{
String name;
public String getName()
{
Scanner sc = new Scanner(System.in);
System.out.print ("Enter your name : ");
name = sc.nextLine();
return name;
}
}
So basically, i want to limit how many client that could join my server(which maximum is 10 client). And if there is another client that want to join the server after it is full, that client will be rejected so it cannot joined.
I think that's it, though if there are any other improvement in other areas at my code it will also be appreciated. Sorry for my bad english
*Oh and sorry since I forget to include it, but somehow when I start the client, it ask the name twice
You can fix main method in your server and add sayGoodBye() as follows:
private static final int CONNECTION_LIMIT = 10;
public static void main(String argv[]) throws Exception {
System.out.println("Threaded Chat Server is Running ");
ServerSocket mysocket = new ServerSocket(5555);
int socketCount = 0;
while (true) {
Socket sock = mysocket.accept();
Server server = new Server(sock);
if (socketCount++ < CONNECTION_LIMIT) {
Thread serverThread = new Thread(server);
serverThread.start();
} else {
// without starting a thread and notifying only new client
server.sayGoodbye();
}
}
}
public void sayGoodbye() throws IOException {
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connectionSocket.getOutputStream()))) {
writer.write("Sorry, new client connections are not accepted, bye for now");
} catch (Exception e) {
e.printStackTrace();
}
connectionSocket.close();
}
I was writing a TCP chat program.
Here is my output.
As you can see only first message from each peer is reaching the other end.
Second message on wards are not displayed.
Here is my full code. You can run it. Where am I wrong?
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import javax.swing.*;
class chattcp extends JFrame {
public static void main(String args[]){
chattcp peer1=new chattcp("peer1",9999,9998);
chattcp peer2=new chattcp("peer2",9998,9999);
}
chattcp(String name,int lis,int snd){
this.setVisible(true);
this.setTitle(name);
this.setLayout(null);
this.setSize(500,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TextField tf=new TextField();
this.add(tf);
tf.setBounds(10,20,100,40);
TextArea ta=new TextArea();
this.add(ta);
ta.setBounds(10,80,400,400);
ta.setEditable(false);
ta.setFont(ta.getFont().deriveFont(20f));
Button b=new Button("send");
this.add(b);
b.setBounds(130,20,60,40);
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
try{
String s= tf.getText();
Socket skt=new Socket("localhost",snd);
DataOutputStream dos= new DataOutputStream(skt.getOutputStream());
dos.writeUTF(s);
ta.append("You :"+s+"\n");
tf.setText("");
}
catch(IOException e){
e.printStackTrace();
}
}
});
Thread receive=new Thread() {
public void run(){
try{
ServerSocket ser=new ServerSocket(lis);
Socket sktt=ser.accept();
DataInputStream dis= new DataInputStream(sktt.getInputStream());
while (true){
String s= dis.readUTF();
ta.append("Friend : "+s+"\n");
}
}catch(IOException e){e.printStackTrace();}
}
};
receive.start();
}
}
Everytime you click your send button you create a new socket and try to connect.
The problem is, once you send something, the socket is created, the serversocket accepts and starts the loop.
When you now write the second message, you are creating a new socket while the loop is still trying to read from the OutputStream from the old socket.
one solution to your problem is to close the serversocket after each read and create a new serversocket each iteration:
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import javax.swing.*;
public class chattcp extends JFrame {
public static void main(String args[]) {
chattcp peer1 = new chattcp("peer1", 9999, 9998);
chattcp peer2 = new chattcp("peer2", 9998, 9999);
}
chattcp(String name, int lis, int snd) {
this.setVisible(true);
this.setTitle(name);
this.setLayout(null);
this.setSize(500, 500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TextField tf = new TextField();
this.add(tf);
tf.setBounds(10, 20, 100, 40);
TextArea ta = new TextArea();
this.add(ta);
ta.setBounds(10, 80, 400, 400);
ta.setEditable(false);
ta.setFont(ta.getFont().deriveFont(20f));
Button b = new Button("send");
this.add(b);
b.setBounds(130, 20, 60, 40);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent a) {
try {
String s = tf.getText();
Socket skt = new Socket("localhost", snd);
DataOutputStream dos = new DataOutputStream(skt.getOutputStream());
dos.writeUTF(s);
ta.append("You :" + s + "\n");
tf.setText("");
} catch (IOException e) {
e.printStackTrace();
}
}
});
Thread receive = new Thread() {
public void run() {
try {
while (true) {
ServerSocket ser = new ServerSocket(lis);
Socket sktt = ser.accept();
DataInputStream dis = new DataInputStream(sktt.getInputStream());
String s = dis.readUTF();
ta.append("Friend : " + s + "\n");
ser.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
receive.start();
}
}
a better solution would be to not always create a new socket, when you send something, but i am lazy and this solution is easier to edit your code to, so i just used it.
You are creating a new connection every time that you click on the send button, but the Server only listen one time.
One simple answer is to save the Socket e reuse it.
class chattcp extends JFrame {
public static void main(String args[]){
chattcp peer1=new chattcp("peer1",9999,9998);
chattcp peer2=new chattcp("peer2",9998,9999);
}
Socket skt = null;
chattcp(String name,int lis,int snd){
this.setVisible(true);
this.setTitle(name);
this.setLayout(null);
this.setSize(500,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TextField tf=new TextField();
this.add(tf);
tf.setBounds(10,20,100,40);
TextArea ta=new TextArea();
this.add(ta);
ta.setBounds(10,80,400,400);
ta.setEditable(false);
ta.setFont(ta.getFont().deriveFont(20f));
Button b=new Button("send");
this.add(b);
b.setBounds(130,20,60,40);
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
try{
if (skt == null) {
skt = new Socket("localhost",snd);
}
DataOutputStream dos= new DataOutputStream(skt.getOutputStream());
String s= tf.getText();
dos.writeUTF(s);
ta.append("You :"+s+"\n");
tf.setText("");
}
catch(IOException e){
e.printStackTrace();
}
}
});
Thread receive=new Thread() {
public void run(){
try{
ServerSocket ser=new ServerSocket(lis);
Socket sktt=ser.accept();
DataInputStream dis= new DataInputStream(sktt.getInputStream());
while (true){
String s= dis.readUTF();
ta.append("Friend : "+s+"\n");
}
}catch(IOException e){e.printStackTrace();}
}
};
receive.start();
}
}
So my chat server that im making only connects to clients on port 5000. I can only broadcast info out to everyone at the same time.
Is there any way to send a message out to one person? Like a Server Message of the day (or is the way I coded it totally wrong and I have to do a major overhaul, if so could you please list out what I need to fix?)
This is my server Code:
public class ServerProgram
{
JTextArea incoming;
ArrayList clientOutputStreams;
JTextField outgoing;
public class ClientHandler implements Runnable {
BufferedReader reader;
Socket sock;
public ClientHandler(Socket clientSocket){
try{
sock = clientSocket;
InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(isReader);
} catch(Exception e) {e.printStackTrace();}
}
public void run(){
String message;
try{
while ((message=reader.readLine())!=null){
incoming.append("USER: "+message+"\n");
tellEveryone(message);
}
}catch(Exception e){e.printStackTrace();}
}
}
public static void main (String[] args){
new ServerProgram().go();
}
public void go(){
clientOutputStreams = new ArrayList();
JFrame frame = new JFrame("Simple Chat Server");
JPanel mainPanel = new JPanel();
incoming = new JTextArea(15,50);
incoming.setLineWrap(true);
incoming.setWrapStyleWord(true);
incoming.setEditable(false);
JScrollPane qScroller = new JScrollPane(incoming);
qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
outgoing = new JTextField(20);
JButton sendButton = new JButton ("Send");
sendButton.addActionListener(new SendButtonListener());
mainPanel.add(qScroller);
mainPanel.add(outgoing);
mainPanel.add(sendButton);
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
frame.setSize(600,500);
frame.setVisible(true);
try{
ServerSocket serverSock = new ServerSocket(5000);
while(true){
Socket clientSocket = serverSock.accept();
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
clientOutputStreams.add(writer);
Thread t = new Thread(new ClientHandler(clientSocket));
t.start();
incoming.append("got a connection at "+" \n");}
}catch (Exception e){e.printStackTrace();}
}
public void tellEveryone(String message){
Iterator it = clientOutputStreams.iterator();
while(it.hasNext()){
try{
PrintWriter writer = (PrintWriter) it.next();
writer.println(message);
writer.flush();
}catch(Exception e){e.printStackTrace();}
}
}
private class SendButtonListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
Iterator it = clientOutputStreams.iterator();
if(it.hasNext()==false){
incoming.append(outgoing.getText());
}
else{tellEveryone("!SERVER;!"+outgoing.getText());
incoming.append(outgoing.getText()+"\n");}
outgoing.setText("");
outgoing.requestFocus();
}
}
}
This is my client code:
public class ChatClient
{
JTextArea incoming;
JTextField outgoing;
BufferedReader reader;
PrintWriter writer;
Socket sock;
String UserName;
String ipAdd="127.0.0.1";
int FinishedNet=0;
JMenuBar menuBar;
JMenu menu, submenu;
JMenuItem menuItem;
JRadioButtonMenuItem rbMenuItem;
JCheckBoxMenuItem cbMenuItem;
public static void main(String[] args) throws Exception
{ChatClient chat = new ChatClient();
chat.go();}
public void go(){
menuBar = new JMenuBar();
JFrame frame = new JFrame("Simple Chat client");
JPanel mainPanel = new JPanel();
menu = new JMenu("Menu");
menu.getAccessibleContext().setAccessibleDescription(
"The only menu in this program that has menu items");
menuBar.add(menu);
cbMenuItem = new JCheckBoxMenuItem("Message AutoScroll");
cbMenuItem.addActionListener(new autoScrollListener());
menu.add(cbMenuItem);
frame.setJMenuBar(menuBar);
incoming = new JTextArea(15,50);
incoming.setLineWrap(true);
incoming.setWrapStyleWord(true);
incoming.setEditable(false);
JScrollPane qScroller = new JScrollPane(incoming);
qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
outgoing = new JTextField(20);
outgoing.addKeyListener(new EnterListener());
JButton sendButton = new JButton ("Send");
sendButton.addActionListener(new SendButtonListener());
mainPanel.add(qScroller);
mainPanel.add(outgoing);
mainPanel.add(sendButton);
setUpNetworking();
Thread readerThread = new Thread(new IncomingReader());
readerThread.start();
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
frame.setSize(600,500);
frame.setVisible(true);
incoming.setText("Type /Help to get the help Text \n");
}
private void setUpNetworking(){
try{
ipAdd = JOptionPane.showInputDialog("What is the IP you wish to connect to");
UserName = JOptionPane.showInputDialog("What is your UserName?");
sock = new Socket(ipAdd, 5000);
InputStreamReader streamReader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(streamReader);
writer = new PrintWriter(sock.getOutputStream());
incoming.append("Networking Finished");
} catch(IOException e){
e.printStackTrace();}
}
public void SendMessage(String message){
writer.println(UserName+": "+message);
writer.flush();
outgoing.setText("");
outgoing.requestFocus();
}
public void SendMessage(){
try{
incoming.setForeground(Color.RED);
String outText=outgoing.getText();
if(outText.length()>1 && outText.substring(0, 1).equals("/")){
String realOutText=outgoing.getText().substring(1);
if(realOutText.equals("help")){
incoming.append("\n help: Displays the help text \n reconnect: reconnects to any IP \n newUserName: Select a new username \n about: Displays the about text \n ipAddress: Displays your public IP Address to only you \n ipAdressAll: Sends your public IP Adress to everyone on the server \n");
}
else if(realOutText.equals("about")){
incoming.append("\n Coded by Dan Janes with the help of Ian Sacco \n Started on 5/27/2014 \n");
}
else if(realOutText.equals("newUserName")){
String old=UserName;
UserName = JOptionPane.showInputDialog("What is your NEW UserName?");
writer.println(old+" is now known as "+UserName);
writer.flush();
}
else if (realOutText.equals("reconnect")){
setUpNetworking();
}
else if (realOutText.equals("ipAddress")){
try{ URL whatismyip = new URL("http://bot.whatismyipaddress.com");
BufferedReader in = new BufferedReader(new InputStreamReader(
whatismyip.openStream()));
String ip = in.readLine();
incoming.append("Your IP address is "+ip+"\n");}
catch(Exception e){e.printStackTrace();
}
}
else if (realOutText.equals("ipAddressAll")){
try{URL whatismyip = new URL("http://bot.whatismyipaddress.com");
BufferedReader in = new BufferedReader(new InputStreamReader(
whatismyip.openStream()));
String ip = in.readLine();
SendMessage( UserName+"'s IP address is "+ip);}
catch(Exception e){e.printStackTrace();
}
}
else{
incoming.append("Sorry that is not a command, try /help \n");
}
}
else{
writer.println(UserName+": "+outText);
writer.flush();
}}catch(Exception e) {e.printStackTrace();}
outgoing.setText("");
outgoing.requestFocus();
}
private class SendButtonListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
SendMessage();
}
}
private class autoScrollListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
if(cbMenuItem.isSelected()==true){
incoming.setCaretPosition(incoming.getDocument().getLength());}
}
}
private class EnterListener implements KeyListener{
#Override
public void keyPressed(KeyEvent arg0) {
if(arg0.getKeyCode()==10){
SendMessage();
}
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}
public class IncomingReader implements Runnable{
public void run(){
String message;
try{
while ((message=reader.readLine())!=null){System.out.println("read "+message);
incoming.append(message+"\n");
if(cbMenuItem.isSelected()==true){
incoming.setCaretPosition(incoming.getDocument().getLength());}
}
}catch(Exception e){e.printStackTrace();}
}
}
}
I'm working on the client side application of the client/server chat I'm doing for learning experience. My problem is I can't seem to get the socket and swing,both to run at the same time.
What I want to is, when the user opens a JOpionsPane and enters the hostname and port number, clicks okay, then they are connected. When the socket information was hardcoded it worked fine, but now I'm trying to get the users input for it.
What's meant to happen is, action listener is supposed to create the new SocketManager object that handles communication. Event though it says it's connected, it doesn't run. When I create the new SocketManager object and run it on a new thread it connects and revives messages form the server, but then the swings freezes and I have to end the process to shut it down.
Should I start it on a new worker thread or something? Maybe it's just because I'm tired, but I'm out of ideas.
EDIT
I updated my ActLis.class and SocketManager.class with the suggestion of adding a new thread for my SocketManager object 'network'. When I try and use 'network' though it returns null for some reason.
ActLis.clss
package com.client.core;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class ActLis implements ActionListener {
private Main main = new Main();;
private JTextField ipadress = new JTextField(),
portnumber = new JTextField(),
actionField;
private String username;
final JComponent[] ipinp = new JComponent[]{new JLabel("Enter Hostname (IP Adress): "),
ipadress,
new JLabel("Enter Port number: "), portnumber};
private SocketManager network;
private Window win;
public ActLis(){
}
public ActLis(JTextField t, Window w){
actionField = t;
win = w;
}
#Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if(cmd == "Exit"){
System.exit(0);
} else if(cmd == "Connect to IP"){
try{
JOptionPane.showMessageDialog(null, ipinp, "Connect to IP", JOptionPane.PLAIN_MESSAGE);
if(network != null){
network.close();
}
network = new SocketManager(ipadress.getText(),Integer.parseInt(portnumber.getText()));
network.setGUI(win);
Thread t = new Thread(network);
t.start();
JOptionPane.showMessageDialog(null, "Connected to chat host successfully!","Connected", JOptionPane.INFORMATION_MESSAGE);
}catch(Exception ee){
JOptionPane.showMessageDialog(null, "Could not connect. Check IP adress or internet connection","Error - Could not connect", JOptionPane.ERROR_MESSAGE);
ee.printStackTrace();
}
} else if (cmd == "chatWriter"){
if( actionField.getText() != ""){
try{
network.send(actionField.getText());
win.updateChat(actionField.getText());
actionField.setText("");
actionField.requestFocus();
}catch(Exception ex){
JOptionPane.showMessageDialog(null, "You are not connected to a host. (File -> Connect to IP)","Error - Not Connected", JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
}
} else if (cmd == "setUsername"){
username = actionField.getText();
network.send("USERNAME:" + username);
}
}
}
Main.class
package com.client.core;
import javax.swing.JFrame;
public class Main extends JFrame{
private SocketManager network;
public static void main(String[] args){
Main main = new Main();
main.run();
}
private void run(){
Window win = new Window();
win.setVisible(true);
}
}
SocketManager.class
package com.client.core;
import java.io.*;
import java.net.*;
public class SocketManager implements Runnable {
private Socket sock;
private PrintWriter output;
private BufferedReader input;
private String hostname;
private int portnumber;
private String message;
private Window gui;
public SocketManager(String ip, int port){
try{
hostname = ip;
portnumber = port;
}catch(Exception e){
System.out.println("Client: Socket failed to connect.");
}
}
public synchronized void send(String data){
try{
//System.out.println("Attempting to send: " + data);
output.println(data);
output.flush();
//System.out.println("Message sent.");
}catch(Exception e){
System.out.println("Message could not send.");
}
}
public synchronized void setGUI(Window w){
gui = w;
}
public synchronized void connect(){
try{
sock = new Socket(hostname,portnumber);
}catch(Exception e){
}
}
public synchronized Socket getSocket(){
return sock;
}
public synchronized void setSocket(SocketManager s){
sock = s.getSocket();
}
public synchronized void close(){
try{
sock.close();
}catch(Exception e){
System.out.println("Could not close connection.");
}
output = null;
input = null;
System.gc();
}
public synchronized boolean isConnected(){
return (sock == null) ? false : (sock.isConnected() && !sock.isClosed());
}
public synchronized void listenStream(){
try {
while((message = input.readLine()) != null){
System.out.println("Server: " + message);
gui.updateChat(message);
}
} catch (Exception e) {
}
}
#Override
public void run() {
try {
sock = new Socket(hostname,portnumber);
output = new PrintWriter(sock.getOutputStream(),true);
input = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
while(true){
listenStream();
}
} catch (Exception e) {
System.out.println("Run method fail. -> SocketManager.run()");
}finally{
try {
sock.close();
} catch (Exception e) {
}
}
}
}
Window.class
package com.client.core;
import java.awt.*;
import javax.swing.*;
public class Window extends JFrame{
private int screenWidth = 800;
private int screenHeight = 600;
private SocketManager network;
private JPanel window = new JPanel(new BorderLayout()),
center = new JPanel(new BorderLayout()),
right = new JPanel(new BorderLayout()),
display = new JPanel( new BorderLayout()),
chat = new JPanel(),
users = new JPanel(new BorderLayout());
private JTextArea chatBox = new JTextArea("Welcome to the chat!", 7,50),
listOfUsers = new JTextArea("None Online");
private JTextField chatWrite = new JTextField(),
userSearch = new JTextField(10),
username = new JTextField();
private JScrollPane userList = new JScrollPane(listOfUsers),
currentChat = new JScrollPane(chatBox);
private JMenuBar menu = new JMenuBar();
private JMenu file = new JMenu("File");
private JMenuItem exit = new JMenuItem("Exit"),
ipconnect = new JMenuItem("Connect to IP");
private JComponent[] login = new JComponent[]{new JLabel("Username:"), username};
public Window(){
//Initial Setup
super("NAMEHERE - Chat Client Alpha v0.0.1");
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(screenWidth,screenHeight);
//Panels
listOfUsers.setLineWrap(true);
listOfUsers.setEditable(false);
display.setBackground(Color.black);
chat.setLayout(new BoxLayout(chat, BoxLayout.Y_AXIS));
chat.setBackground(Color.blue);
users.setBackground(Color.green);
//TextFields
addChatArea();
//Menu bar
addMenuBar();
//Adding the main panels.
addPanels();
//Listeners
addListeners();
for(int x = 0; x < 1; x++){
login();
}
}
private void login(){
JOptionPane.showMessageDialog(null, login, "Log in", JOptionPane.PLAIN_MESSAGE);
}
private void addChatArea(){
chatBox.setEditable(false);
userList.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
currentChat.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
users.add(userList);
users.add(userSearch, BorderLayout.NORTH);
chat.add(currentChat);
chat.add(chatWrite);
chat.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
}
private void addMenuBar(){
file.add(ipconnect);
file.add(exit);
menu.add(file);
}
private void addPanels(){
right.add(users);
center.add(display, BorderLayout.CENTER);
center.add(chat, BorderLayout.SOUTH);
window.add(center, BorderLayout.CENTER);
window.add(right, BorderLayout.EAST);
window.add(menu, BorderLayout.NORTH);
add(window);
}
private void addListeners(){
username.addActionListener(new ActLis(username, this));
chatWrite.addActionListener(new ActLis(chatWrite, this));
username.setActionCommand("setUsername");
chatWrite.setActionCommand("chatWriter");
ipconnect.addActionListener(new ActLis());
exit.addActionListener(new ActLis());
}
public void setNetwork(SocketManager n){
network = n;
}
public void updateChat(String s){
chatBox.setText(chatBox.getText() + "\n" + s);
}
}
Ok #Zexanima you have create a Socket class for socket manager. Something like this:
public class YouSocketClass {
static public Socket socket = null;
static public InputStream in = null;
static public OutputStream out = null;
public YouSocketClass() {
super();
}
public static final Socket getConnection(final String ip, final int port, final int timeout) {
try {
socket = new Socket(ip, port);
try {
socket.setSoTimeout(timeout);
} catch(SocketException se) {
log("Server Timeout");
}
in = socket.getInputStream();
out = socket.getOutputStream();
} catch(ConnectException e) {
log("Server name or server ip is failed. " + e.getMessage());
e.printStackTrace();
} catch(Exception e) {
log("ERROR Socket: " + e.getMessage() + " " + e.getCause());
e.printStackTrace();
}
return socket;
}
public static void closeConnection() {
try {
if(socket != null) {
if(in != null) {
if(out != null) {
socket.close();
in.close();
out.close();
}
}
}
} catch(Exception e2) {
e2.printStackTrace();
}
}
private static Object log(Object sms) {
System.out.println("Test Socket1.0: " + sms);
return sms;
}
}
I hope that serve. :)