Hello! I have attempted to write a very basic IM program that requires a server and a client program. The problem I have run in to is that the client CAN connect to the server, but until the session is ended, the client is not able to see any of the information in the chat window (JTextArea) coming from the Server. After the connection is ended, all of that information appears and is added to the chat log. I have found only one way to remedy the problem, but it does not allow for the functionality that I want. Here is the code and then I will explain how I have been able to fix the problem:
//SERVER PROGRAM import javax.swing.*; import java.util.*; import java.io.*; import java.awt.*; import java.awt.event.*; import java.net.*; import java.text.*; public class IM { //OBJECTS //GUI JFrame window = new JFrame("Rohan's IM Program - SERVER"); JTextArea chatWindow = new JTextArea(20, 40); JScrollPane scrollPane = new JScrollPane(chatWindow); JLabel label1 = new JLabel("Start chatting (type \"END\" to end session): "); JTextField userText = new JTextField(35); JButton send = new JButton("Send"); //I/O ServerSocket serverSocket; Socket connection; ObjectOutputStream output; ObjectInputStream input; //OTHER String message; File f = new File("chat_log.txt"); BufferedWriter write; StringBuilder sb = new StringBuilder(); //MAIN PROGRAM //Main Method public void initialize() { //Window settings window.setSize(550, 550); window.setLayout(new FlowLayout(FlowLayout.LEADING, 30, 10)); //Text area settings chatWindow.setEditable(false); //Text field settings userText.setEditable(false); //Send Button send.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { try { sendMessage(userText.getText()); } catch (IOException e1) { e1.printStackTrace(); } } }); //Window settings cont. window.add(scrollPane, BorderLayout.NORTH); window.add(label1, BorderLayout.SOUTH); window.add(userText); window.add(send); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setVisible(true); try { startServer(); } catch (IOException e2){ e2.printStackTrace(); } } //START THE SERVER public void startServer() throws IOException { try{ serverSocket = new ServerSocket(6789, 10); while (true) { try { waitForConnection(); setupIO(); whileChatting(); } catch (IOException e1) { showMessage("\nConnection has ended!"); }finally { closeEverything(); chatLog(); } } } catch (IOException e){ e.printStackTrace(); } } //MAIN CHAT METHODS //waitForConnection method private void waitForConnection() throws IOException { showMessage("\nWaiting for a connection..."); connection = serverSocket.accept(); showMessage("\nConnected to " + connection.getInetAddress().getHostAddress() + " ! \nSetting up streams..."); } //setupIO method private void setupIO() throws IOException { output = new ObjectOutputStream(connection.getOutputStream()); output.flush(); input = new ObjectInputStream(connection.getInputStream()); showMessage("\nStreams set up!\n"); } //whileChatting method private void whileChatting() throws IOException { userText.setEditable(true); do { try { message = (String) input.readObject(); showMessage("\nCLIENT - " + message); } catch (ClassNotFoundException e) { showMessage("\n <ERROR: Unknown message from client>"); } }while(!message.equals("END")); } //OTHER METHODS //sendMessage public void sendMessage(String x) throws IOException { output.writeObject(x); output.flush(); showMessage("\nSERVER - " + x); if (userText.getText().equals("END")){ connection.close(); userText.setText(""); userText.updateUI(); } else { userText.setText(""); userText.updateUI(); } } //showMessage public void showMessage(String x) throws IOException { chatWindow.append(x); chatWindow.updateUI(); sb.append(x); sb.append(System.getProperty("line.separator")); } //chatLog public void chatLog() { try { write = new BufferedWriter(new FileWriter(f, true)); String chat = sb.toString(); write.write(chat); write.newLine(); write.write("-------------------------------------------------------------------------------------"); write.newLine(); sb.delete(0, sb.length()); write.close(); } catch (IOException e) { e.printStackTrace(); } } //closeEverything private void closeEverything() throws IOException { userText.setEditable(false); showMessage("\nClosing connections..."); output.close(); input.close(); connection.close(); showMessage("\nSession terminated.\n"); } }
//CLIENT PROGRAM import javax.swing.*; import java.util.*; import java.io.*; import java.awt.*; import java.awt.event.*; import java.net.*; public class IM { //OBJECTS //GUI JFrame window = new JFrame("Rohan's IM Program - CLIENT"); JTextArea chatWindow = new JTextArea(20, 40); JScrollPane scrollPane = new JScrollPane(chatWindow); JLabel label1 = new JLabel("Start chatting (type \"END\" to end session): "); JTextField userText = new JTextField(35); JButton send = new JButton("Send"); JButton connect = new JButton("Connect"); //I/O Socket connection; ObjectOutputStream output; ObjectInputStream input; //OTHER StringBuilder sb = new StringBuilder(); String message; static String ip = "nothin"; File f = new File("chat_log.txt"); BufferedWriter write; //MAIN PROGRAM //Main Method public void initialize() { //Window settings window.setSize(550, 550); window.setLayout(new FlowLayout(FlowLayout.LEADING, 30, 10)); //Text area settings chatWindow.setEditable(false); //Text field settings userText.setEditable(false); //Send Button send.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { try { sendMessage(userText.getText()); } catch (IOException e1) { e1.printStackTrace(); } } }); //Connect Button connect.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e1) { ip = JOptionPane.showInputDialog("Enter server IP address."); startIM(); } }); //Window settings cont. window.add(connect); window.add(scrollPane, BorderLayout.NORTH); window.add(label1, BorderLayout.SOUTH); window.add(userText); window.add(send); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setVisible(true); } //START THE SESSION public void startIM() { try { connectToServer(); setupIO(); whileChatting(); }catch (IOException e) { chatLog(); JOptionPane.showMessageDialog(null,"Invalid IP address or server closed."); initialize(); } } //MAIN CHAT METHODS //connectToServer method private void connectToServer() throws IOException { showMessage("\nTrying to connect to server at " + ip + " ..."); connection = new Socket(InetAddress.getByName(ip), 6789); showMessage("\nConnected to " + connection.getInetAddress().getHostAddress() + " !"); } //setupIO method private void setupIO() throws IOException { output = new ObjectOutputStream(connection.getOutputStream()); output.flush(); input = new ObjectInputStream(connection.getInputStream()); showMessage("\nStreams set up!\n"); } //whileChatting method private void whileChatting() throws IOException { userText.setEditable(true); do { try { message = (String) input.readObject(); showMessage("\nSERVER - " + message); } catch (ClassNotFoundException e) { showMessage("\n <ERROR: Unknown message from client>"); } }while(!message.equals("END")); chatLog(); JOptionPane.showMessageDialog(null,"Server has ended the session."); initialize(); } //OTHER METHODS //sendMessage public void sendMessage(String x) throws IOException { output.writeObject(x); output.flush(); showMessage("\nCLIENT - " + x); userText.setText(""); userText.updateUI(); } //showMessage public void showMessage(String x) { chatWindow.append(x); chatWindow.updateUI(); sb.append(x); sb.append(System.getProperty("line.separator")); } //chatLog public void chatLog() { try { write = new BufferedWriter(new FileWriter(f, true)); String chat = sb.toString(); write.write(chat); write.newLine(); write.write("-------------------------------------------------------------------------------------"); write.newLine(); sb.delete(0, sb.length()); write.close(); } catch (IOException e) { e.printStackTrace(); } } }
The only fix I have found is to take away the "Connect" button functionality, have the user input the ip right from the start of the initialize() method, and then call startIM() at the end of initialize(). Any attempts at getting the button to work result in the same problem of not being able to chat and not receiving any information in the chat window. Everything else works fine, including the chat log.
I have even tried creating a boolean that is set to true when "Connect" is pressed that will do essentially the same thing as the solution I mentioned. I wrapped the prompt for the ip and the call for startIM() in "if" statements that are only fired when the boolean is set to true, making it so that when "Connect" is pressed initialize() will re-run and the user will be prompted for the ip and startIM() will run at the end. So, my only hypothesis is that something about the button is causing an issue, but I haven't been able to figure how this can be. Thank you for any help in advance!