import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; import java.net.*; /** A GUI client for the chat server. */ public class ChatClientGUI { /** * Displays a GUI that both displays message from the chat room and allows * new messages to be sent to the room. */ public static void main(String[] args) { JTextArea messageArea = new JTextArea(); // shows messages from the room JTextField newMessage = new JTextField(30); // new message from user JButton sendButton = new JButton("Send"); // click to send new message // When the user hits Send, send the new message to the server. It will // then show up in the message area when the server passes it back. sendButton.addActionListener(e -> { speak(newMessage.getText()); newMessage.setText(""); }); // Display the UI with the parts above. showChatUI(messageArea, newMessage, sendButton); // Create a thread to listen for new messages in the room and display them. new ChatListenerThread(messageArea).start(); } /** * Displays a text area in the center of a window with a text field and * button along the bottom. */ private static void showChatUI( JTextArea messageArea, JTextField messageField, JButton messageButton) { JFrame frame = new JFrame("Chat Client"); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); messageArea.setColumns(40); messageArea.setRows(15); JScrollPane messageScroll = new JScrollPane(messageArea); frame.add(messageScroll, BorderLayout.CENTER); JPanel panel = new JPanel(); panel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); panel.add(messageField); panel.add(messageButton); frame.add(panel, BorderLayout.SOUTH); frame.pack(); frame.setVisible(true); } /** Sends the given message to the chat room. */ private static void speak(String msg) { try { Socket socket = new Socket(ChatClient.HOST, ChatServer.PORT); Writer writer = new OutputStreamWriter(socket.getOutputStream()); writer.write("speak " + msg + "\n"); writer.flush(); socket.close(); } catch (IOException ex) { ex.printStackTrace(System.err); // Keep running in this case. Maybe it will get better? } } /** Listens for messages and display them in this text area. */ private static class ChatListenerThread extends Thread { /** The text area in which room messages are displayed. */ private JTextArea messageArea; /** Creates a thread to show new chat message in the given area. */ public ChatListenerThread(JTextArea messageArea) { this.messageArea = messageArea; } /** Listens for new messages in an infinite loop. */ public void run() { try { Socket socket = new Socket(ChatClient.HOST, ChatServer.PORT); Writer writer = new OutputStreamWriter(socket.getOutputStream()); writer.write("listen\n"); writer.flush(); BufferedReader reader = new BufferedReader( new InputStreamReader(socket.getInputStream())); String msg; while ((msg = reader.readLine()) != null) { // Most UI APIs cannot be called from outside the UI thread. // invokeLater will call us back on the UI thread. final String newLine = msg + "\n"; SwingUtilities.invokeLater(() -> messageArea.append(newLine)); } } catch (IOException ex) { ex.printStackTrace(System.err); System.exit(1); } } } }