Trying to get better at Java, I'm attempting to create a mutlithreaded Client & Server messenger, in which a Client sends a message to the Server, and the Server then redirects & sends the message to the user the first client wanted to send it to. I've also been researching a lot about concurrency and multithreading and such. My current problem, which I've concluded, is that my BufferedReader/InputStream from my Client isn't "ready" when I start my run thread, and it thus returns a nullPointerException. A few other questions:
- Should I do my drawGUI() method in a
SwingUtilities.invokeLater()
statement or does it not matter since I'm not really interacting with the GUI in that method - Wondering if the HashMap
usersIP
would work well for key-value pair, to pair clients to their IP. There's also one of these in the Server class - Was gonna ask another question, but forgot what it was. Will edit in later if I remember
Client code(cut down to the useful stuff)
public class Client extends Thread {
public static Socket socket;
public static PrintStream os;
public static BufferedReader is;
public static StringBuffer toAppend = new StringBuffer("");
public static StringBuffer toSend = new StringBuffer("");
//Some variables for use with the JMenuBarItems
public static Map<String, String> usersIP = new HashMap<String, String>();
public static String[] friends;
//Swing variables
public static void drawGUI() {
//JMenuBar set up
//Some JMenuItem stuff and adding their action listeners
//Adding the JMenuBarItems to the JMenuBar
//Main GUI Window set up
//Initializing the JTextArea and setting some properties
chatField = new JTextField();
chatField.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
String s = chatField.getText();
if(!s.equals("")) {
appendToChatBox(s);
//textArea.append(username + "> " + s);
chatField.setText("");
sendString(s);
System.out.println("In Chat Field: To Send: " + toSend.toString());
}
}
});
//Adding some panels to the JFrame
//Setting some stuff for the JFrame
}
//Some of these methods below may be unneeded, but I left them there just in case
public static void appendToChatBox(String s) {
synchronized(toAppend) {
toAppend.append(s);
}
}
public static void appendToChatBox(String username, String s) {
synchronized(toAppend) {
toAppend.append(username + "> " + s);
}
}
public static void sendString(String s) {
synchronized(toAppend) {
toAppend.append(s);
}
}
public static void cleanUp() {
try {
if(socket != null) {
socket.close();
socket = null;
}
} catch(IOException e) {
socket = null;
}
try {
if(is != null) {
is.close();
is = null;
}
} catch(IOException e) {
is = null;
}
if(os != null) {
os.close();
os = null;
}
}
public static void connect() {
try {
System.out.println("In connect method"); //Debug
socket = new Socket(host, port);
os = new PrintStream(socket.getOutputStream());
is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
appendToChatBox("Successfully Connected");
System.out.println("ToAppend in connect method: " + toAppend.toString()); //Debug
System.out.println("Successfully Connected");
} catch(UnknownHostException e) {
System.err.println("Don't know about host: " + host);
} catch(IOException e) {
System.err.println("Couldn't get I/O for the connection to the host " + host);
}
if(socket != null && os != null && is != null) {
try {
while(!closed) {
if(toSend.length() != 0) {
System.out.println("In connect()> ToSend.length isn't = to 0"); //Debug
os.println(toSend);
os.flush();
toSend.setLength(0);
}
}
} catch(Exception e) {
System.err.println("Error in sending a message to the Server " + e);
cleanUp();
}
}
}
public static void reconnect() {
cleanUp();
connect();
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Thread(new Runnable() {
@Override
public void run() {
drawGUI();
}
}));
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Attempting to connect to server..."); //Debug
connect();
}
}).start();
new Client().start();
}
@Override
public void run() {
String servermessage;
System.out.println("Client.run() invoked"); //Debug
try {
System.out.println("In try-catch statement in Client.run()"); //Debug
while(is.ready()) {
System.out.println("Input Stream isn't null & is ready in Client.run()"); //Debug
servermessage = is.readLine().trim();
if(servermessage != null && servermessage.length() != 0) {
if(servermessage.equalsIgnoreCase("client_disconnect")) {
break;
} else if(servermessage.equals(Integer.toString(USERNAME_REQUEST))) {
} else {
appendToChatBox("Server" + servermessage);
System.out.println("Server> " + servermessage);
}
}
if(toSend.length() > 0) { //Debug
System.out.println("ToSend in Client.run's while loop: " + toSend.toString());
} else { //Debug
System.out.println("ToSend is empty");
}
}
} catch(Exception e) {
e.printStackTrace();
}
if(toAppend.length() != 0) {
appendToChatBox("From Client.run() " + toAppend.toString());
} else { //Debug
System.out.println("ToAppend is empty");
}
}