google-site-verification: google61fe8ba583a51912.html
Simple Chat Application in Java

Console-Based Chat Application

Basic Console Chat

import java.io.*; import java.net.*; import java.util.*; import java.util.concurrent.*; public class SimpleConsoleChat { private static final int PORT = 8080; private static Set<PrintWriter> clientWriters = new CopyOnWriteArraySet<>(); private static Set<String> clientNames = new ConcurrentHashMap().newKeySet(); public static void main(String[] args) { System.out.println("Simple Chat Application"); System.out.println("1. Start Server"); System.out.println("2. Start Client"); System.out.print("Choose option: "); Scanner scanner = new Scanner(System.in); String choice = scanner.nextLine(); if (choice.equals("1")) { startServer(); } else if (choice.equals("2")) { startClient(); } else { System.out.println("Invalid option"); } } // Server Implementation public static void startServer() { System.out.println("Starting Chat Server on port " + PORT); try (ServerSocket serverSocket = new ServerSocket(PORT)) { while (true) { new ClientHandler(serverSocket.accept()).start(); } } catch (IOException e) { System.err.println("Server error: " + e.getMessage()); } } // Client Implementation public static void startClient() { System.out.print("Enter your username: "); Scanner scanner = new Scanner(System.in); String username = scanner.nextLine(); try (Socket socket = new Socket("localhost", PORT); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) { // Send username to server out.println(username); // Start thread for reading messages from server Thread readerThread = new Thread(() -> { try { String serverMessage; while ((serverMessage = in.readLine()) != null) { System.out.println(serverMessage); } } catch (IOException e) { System.out.println("Disconnected from server"); } }); readerThread.start(); // Read user input and send to server String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); if ("/quit".equalsIgnoreCase(userInput)) { break; } } } catch (UnknownHostException e) { System.err.println("Unknown host: localhost"); } catch (IOException e) { System.err.println("Couldn't connect to server: " + e.getMessage()); } } // Client Handler for Server private static class ClientHandler extends Thread { private Socket socket; private PrintWriter out; private BufferedReader in; private String clientName; public ClientHandler(Socket socket) { this.socket = socket; } public void run() { try { in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); // Get client name clientName = in.readLine(); if (clientName == null) return; clientNames.add(clientName); clientWriters.add(out); System.out.println(clientName + " joined the chat"); broadcastMessage("SERVER: " + clientName + " joined the chat", null); String message; while ((message = in.readLine()) != null) { if ("/quit".equalsIgnoreCase(message)) { break; } else if ("/users".equalsIgnoreCase(message)) { out.println("Online users: " + String.join(", ", clientNames)); } else if (message.startsWith("/whisper ")) { handleWhisper(message); } else { broadcastMessage(clientName + ": " + message, out); } } } catch (IOException e) { System.out.println("Client disconnected: " + e.getMessage()); } finally { cleanup(); } } private void handleWhisper(String message) { try { String[] parts = message.split(" ", 3); if (parts.length >= 3) { String targetUser = parts[1]; String whisperMessage = parts[2]; // Find target user and send whisper for (PrintWriter writer : clientWriters) { if (writer != out) { // Don't send to self // In a real implementation, you'd need to track which writer belongs to which user writer.println("[WHISPER from " + clientName + "]: " + whisperMessage); } } } } catch (Exception e) { out.println("Invalid whisper format. Use: /whisper username message"); } } private void cleanup() { if (clientName != null) { clientNames.remove(clientName); System.out.println(clientName + " left the chat"); broadcastMessage("SERVER: " + clientName + " left the chat", null); } if (out != null) { clientWriters.remove(out); } try { socket.close(); } catch (IOException e) { // Ignore } } } private static void broadcastMessage(String message, PrintWriter excludeWriter) { for (PrintWriter writer : clientWriters) { if (writer != excludeWriter) { writer.println(message); } } } }

GUI Chat Application with Swing

Chat Client GUI

import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.concurrent.*; public class ChatClientGUI { private JFrame frame; private JTextArea chatArea; private JTextField messageField; private JButton sendButton; private JList<String> userList; private DefaultListModel<String> userListModel; private PrintWriter out; private BufferedReader in; private String username; private Socket socket; public static void main(String[] args) { SwingUtilities.invokeLater(() -> { new ChatClientGUI().createAndShowGUI(); }); } public void createAndShowGUI() { // Login dialog username = JOptionPane.showInputDialog(frame, "Enter your username:", "Chat Login", JOptionPane.PLAIN_MESSAGE); if (username == null || username.trim().isEmpty()) { System.exit(0); } username = username.trim(); // Create main frame frame = new JFrame("Chat Client - " + username); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); // Chat area chatArea = new JTextArea(20, 40); chatArea.setEditable(false); chatArea.setLineWrap(true); chatArea.setWrapStyleWord(true); JScrollPane chatScrollPane = new JScrollPane(chatArea); frame.add(chatScrollPane, BorderLayout.CENTER); // User list userListModel = new DefaultListModel<>(); userList = new JList<>(userListModel); userList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane userScrollPane = new JScrollPane(userList); userScrollPane.setPreferredSize(new Dimension(150, 0)); frame.add(userScrollPane, BorderLayout.EAST); // Input panel JPanel inputPanel = new JPanel(new BorderLayout()); messageField = new JTextField(); sendButton = new JButton("Send"); inputPanel.add(messageField, BorderLayout.CENTER); inputPanel.add(sendButton, BorderLayout.EAST); frame.add(inputPanel, BorderLayout.SOUTH); // Event handlers sendButton.addActionListener(e -> sendMessage()); messageField.addActionListener(e -> sendMessage()); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { disconnect(); } }); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); // Connect to server connectToServer(); } private void connectToServer() { try { socket = new Socket("localhost", 8080); out = new PrintWriter(socket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // Send username to server out.println(username); // Start thread to read messages from server new Thread(this::readMessages).start(); appendToChat("Connected to chat server as " + username); } catch (IOException e) { JOptionPane.showMessageDialog(frame, "Could not connect to server: " + e.getMessage(), "Connection Error", JOptionPane.ERROR_MESSAGE); System.exit(1); } } private void readMessages() { try { String message; while ((message = in.readLine()) != null) { if (message.startsWith("USERLIST:")) { updateUserList(message.substring(9)); } else { appendToChat(message); } } } catch (IOException e) { appendToChat("Disconnected from server"); } } private void sendMessage() { String message = messageField.getText().trim(); if (!message.isEmpty()) { out.println(message); messageField.setText(""); if ("/quit".equalsIgnoreCase(message)) { disconnect(); } } } private void appendToChat(String message) { SwingUtilities.invokeLater(() -> { chatArea.append(message + "\n"); chatArea.setCaretPosition(chatArea.getDocument().getLength()); }); } private void updateUserList(String userListString) { SwingUtilities.invokeLater(() -> { userListModel.clear(); String[] users = userListString.split(","); for (String user : users) { if (!user.trim().isEmpty()) { userListModel.addElement(user.trim()); } } }); } private void disconnect() { try { if (out != null) { out.println("/quit"); } if (socket != null) { socket.close(); } } catch (IOException e) { // Ignore } System.exit(0); } }

Enhanced Chat Server

import java.io.*; import java.net.*; import java.util.*; import java.util.concurrent.*; public class EnhancedChatServer { private static final int PORT = 8080; private static Set<ClientHandler> clients = ConcurrentHashMap.newKeySet(); private static Map<String, ClientHandler> clientMap = new ConcurrentHashMap<>(); public static void main(String[] args) { System.out.println("Enhanced Chat Server starting on port " + PORT); try (ServerSocket serverSocket = new ServerSocket(PORT)) { while (true) { new ClientHandler(serverSocket.accept()).start(); } } catch (IOException e) { System.err.println("Server error: " + e.getMessage()); } } public static void broadcastMessage(String message, ClientHandler excludeClient) { for (ClientHandler client : clients) { if (client != excludeClient) { client.sendMessage(message); } } } public static void updateUserList() { String userList = "USERLIST:" + String.join(",", clientMap.keySet()); for (ClientHandler client : clients) { client.sendMessage(userList); } } public static void sendPrivateMessage(String fromUser, String toUser, String message) { ClientHandler targetClient = clientMap.get(toUser); if (targetClient != null) { targetClient.sendMessage("[Private from " + fromUser + "]: " + message); } else { ClientHandler senderClient = clientMap.get(fromUser); if (senderClient != null) { senderClient.sendMessage("User " + toUser + " is not online"); } } } // Client Handler class private static class ClientHandler extends Thread { private Socket socket; private PrintWriter out; private BufferedReader in; private String username; public ClientHandler(Socket socket) { this.socket = socket; } public void run() { try { in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); // Authentication username = in.readLine(); if (username == null || username.trim().isEmpty() || clientMap.containsKey(username)) { out.println("ERROR: Invalid username or username already taken"); return; } username = username.trim(); // Register client clients.add(this); clientMap.put(username, this); System.out.println(username + " connected from " + socket.getInetAddress()); broadcastMessage("SERVER: " + username + " joined the chat", this); updateUserList(); // Handle messages String message; while ((message = in.readLine()) != null) { if ("/quit".equalsIgnoreCase(message)) { break; } else if (message.startsWith("/whisper ")) { handleWhisper(message); } else if (message.startsWith("/msg ")) { handlePrivateMessage(message); } else if ("/users".equalsIgnoreCase(message)) { sendMessage("Online users: " + String.join(", ", clientMap.keySet())); } else if (message.startsWith("/kick ") && username.equals("admin")) { handleKickCommand(message); } else { broadcastMessage(username + ": " + message, this); } } } catch (IOException e) { System.out.println("Client error: " + e.getMessage()); } finally { disconnect(); } } private void handleWhisper(String message) { try { String[] parts = message.split(" ", 3); if (parts.length >= 3) { String targetUser = parts[1]; String whisperMessage = parts[2]; sendPrivateMessage(username, targetUser, whisperMessage); } } catch (Exception e) { sendMessage("Invalid whisper format. Use: /whisper username message"); } } private void handlePrivateMessage(String message) { try { String[] parts = message.split(" ", 3); if (parts.length >= 3) { String targetUser = parts[1]; String privateMessage = parts[2]; sendPrivateMessage(username, targetUser, privateMessage); sendMessage("[Private to " + targetUser + "]: " + privateMessage); } } catch (Exception e) { sendMessage("Invalid private message format. Use: /msg username message"); } } private void handleKickCommand(String message) { try { String[] parts = message.split(" "); if (parts.length >= 2) { String targetUser = parts[1]; ClientHandler targetClient = clientMap.get(targetUser); if (targetClient != null) { targetClient.sendMessage("You have been kicked by admin"); targetClient.disconnect(); broadcastMessage("SERVER: " + targetUser + " was kicked by admin", null); } } } catch (Exception e) { sendMessage("Invalid kick command format. Use: /kick username"); } } public void sendMessage(String message) { out.println(message); } private void disconnect() { if (username != null) { clients.remove(this); clientMap.remove(username); System.out.println(username + " disconnected"); broadcastMessage("SERVER: " + username + " left the chat", null); updateUserList(); } try { socket.close(); } catch (IOException e) { // Ignore } } } }

WebSocket Chat Application

WebSocket Server (Using Java-WebSocket library)

First, add this dependency to your pom.xml:

<dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>1.5.3</version> </dependency>
import org.java_websocket.WebSocket; import org.java_websocket.handshake.ClientHandshake; import org.java_websocket.server.WebSocketServer; import java.net.InetSocketAddress; import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class WebSocketChatServer extends WebSocketServer { private Map<WebSocket, String> clientUsernames = new ConcurrentHashMap<>(); private Set<WebSocket> clients = ConcurrentHashMap.newKeySet(); public WebSocketChatServer(int port) { super(new InetSocketAddress(port)); } @Override public void onStart() { System.out.println("WebSocket Chat Server started on port: " + getPort()); } @Override public void onOpen(WebSocket conn, ClientHandshake handshake) { clients.add(conn); System.out.println("New connection from: " + conn.getRemoteSocketAddress()); conn.send("Welcome to WebSocket Chat! Please send your username."); } @Override public void onClose(WebSocket conn, int code, String reason, boolean remote) { String username = clientUsernames.get(conn); clients.remove(conn); clientUsernames.remove(conn); if (username != null) { broadcast("SERVER: " + username + " left the chat", conn); System.out.println(username + " disconnected"); } } @Override public void onMessage(WebSocket conn, String message) { String username = clientUsernames.get(conn); if (username == null) { // First message is username if (isValidUsername(message)) { clientUsernames.put(conn, message); conn.send("Username set to: " + message); broadcast("SERVER: " + message + " joined the chat", conn); System.out.println("User registered: " + message); } else { conn.send("Invalid username. Please choose another one."); } } else { // Regular chat message if (message.startsWith("/")) { handleCommand(conn, message); } else { broadcast(username + ": " + message, conn); } } } @Override public void onError(WebSocket conn, Exception ex) { System.err.println("WebSocket error: " + ex.getMessage()); if (conn != null) { clients.remove(conn); clientUsernames.remove(conn); } } private boolean isValidUsername(String username) { return username != null && !username.trim().isEmpty() && !clientUsernames.containsValue(username) && username.length() <= 20; } private void handleCommand(WebSocket conn, String message) { String username = clientUsernames.get(conn); if (message.equals("/users")) { String userList = "Online users: " + String.join(", ", clientUsernames.values()); conn.send(userList); } else if (message.startsWith("/whisper ")) { String[] parts = message.split(" ", 3); if (parts.length == 3) { String targetUser = parts[1]; String whisperMessage = parts[2]; for (Map.Entry<WebSocket, String> entry : clientUsernames.entrySet()) { if (entry.getValue().equals(targetUser)) { entry.getKey().send("[Whisper from " + username + "]: " + whisperMessage); conn.send("[Whisper to " + targetUser + "]: " + whisperMessage); return; } } conn.send("User " + targetUser + " not found"); } } else { conn.send("Unknown command: " + message); } } private void broadcast(String message, WebSocket exclude) { for (WebSocket client : clients) { if (client != exclude && client.isOpen()) { client.send(message); } } } public static void main(String[] args) { int port = 8887; WebSocketChatServer server = new WebSocketChatServer(port); server.start(); System.out.println("WebSocket Chat Server running on ws://localhost:" + port); } }

Simple Chat Features

Chat Room Manager

import java.util.*; import java.util.concurrent.*; public class ChatRoomManager { private Map<String, ChatRoom> chatRooms = new ConcurrentHashMap<>(); public ChatRoomManager() { // Create default room createRoom("general"); } public ChatRoom createRoom(String roomName) { ChatRoom room = new ChatRoom(roomName); chatRooms.put(roomName, room); return room; } public ChatRoom getRoom(String roomName) { return chatRooms.get(roomName); } public List<String> getRoomList() { return new ArrayList<>(chatRooms.keySet()); } public boolean joinRoom(String roomName, ChatClient client) { ChatRoom room = chatRooms.get(roomName); if (room != null) { room.addClient(client); return true; } return false; } public void leaveRoom(String roomName, ChatClient client) { ChatRoom room = chatRooms.get(roomName); if (room != null) { room.removeClient(client); } } } class ChatRoom { private String name; private Set<ChatClient> clients = ConcurrentHashMap.newKeySet(); public ChatRoom(String name) { this.name = name; } public void addClient(ChatClient client) { clients.add(client); broadcast("SERVER: " + client.getUsername() + " joined " + name, null); } public void removeClient(ChatClient client) { clients.remove(client); broadcast("SERVER: " + client.getUsername() + " left " + name, null); } public void broadcast(String message, ChatClient exclude) { for (ChatClient client : clients) { if (client != exclude) { client.sendMessage(message); } } } public String getName() { return name; } public Set<ChatClient> getClients() { return clients; } } interface ChatClient { String getUsername(); void sendMessage(String message); }

Message Format and History

import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; public class ChatMessage { private String username; private String message; private LocalDateTime timestamp; private MessageType type; public enum MessageType { TEXT, JOIN, LEAVE, WHISPER, SYSTEM } public ChatMessage(String username, String message, MessageType type) { this.username = username; this.message = message; this.type = type; this.timestamp = LocalDateTime.now(); } public String toFormattedString() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); String time = timestamp.format(formatter); switch (type) { case JOIN: return "[" + time + "] " + username + " joined the chat"; case LEAVE: return "[" + time + "] " + username + " left the chat"; case WHISPER: return "[" + time + "] [Whisper] " + username + ": " + message; case SYSTEM: return "[" + time + "] [System] " + message; default: return "[" + time + "] " + username + ": " + message; } } // Getters public String getUsername() { return username; } public String getMessage() { return message; } public LocalDateTime getTimestamp() { return timestamp; } public MessageType getType() { return type; } } class MessageHistory { private List<ChatMessage> messages = Collections.synchronizedList(new ArrayList<>()); private static final int MAX_HISTORY = 1000; public void addMessage(ChatMessage message) { messages.add(message); // Keep only recent messages if (messages.size() > MAX_HISTORY) { messages.remove(0); } } public List<ChatMessage> getRecentMessages(int count) { int start = Math.max(0, messages.size() - count); return new ArrayList<>(messages.subList(start, messages.size())); } public void clear() { messages.clear(); } }

Running the Chat Application

How to Run:

  1. Console Version:
  • Compile all Java files
  • Run java SimpleConsoleChat
  • Choose option 1 to start server
  • Open new terminals and choose option 2 to start clients
  1. GUI Version:
  • Start the EnhancedChatServer first
  • Run ChatClientGUI for each client
  • Enter username when prompted
  1. WebSocket Version:
  • Add the Java-WebSocket dependency
  • Run WebSocketChatServer
  • Use a WebSocket client or browser to connect

Features Included:

  • Multiple clients can connect simultaneously
  • Real-time messaging between clients
  • User list showing online users
  • Private messaging (/whisper command)
  • User commands (/users, /quit)
  • Basic admin features (kick users)
  • GUI interface with Swing
  • WebSocket support for web clients

This simple chat application demonstrates core networking concepts in Java and can be extended with features like user authentication, message persistence, file sharing, or voice/video chat.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper