Чат на Java (Клиентская часть)
Всем доброго времени суток. На связи Алексей Гулынин. В данной статье я бы хотел написать клиентскую часть простого чата на Java. Все комментарии также будут даны в коде.
Скачать уже готовый проект полностью можно по ссылке.
Проект клиентской части будет состоять из 2 файлов:
- ClientWindow.java — класс, который описывает логику работы клиента.
- Main.java.
В классе Main будет просто создаваться экземпляр нашего клиентского приложения (формы):
package client; public class Main { public static void main(String[] args) { ClientWindow clientWindow = new ClientWindow(); } }
Класс ClientWindow:
package client; import javax.accessibility.AccessibleContext; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.Socket; import java.util.Scanner; public class ClientWindow extends JFrame { // адрес сервера private static final String SERVER_HOST = "localhost"; // порт private static final int SERVER_PORT = 3443; // клиентский сокет private Socket clientSocket; // входящее сообщение private Scanner inMessage; // исходящее сообщение private PrintWriter outMessage; // следующие поля отвечают за элементы формы private JTextField jtfMessage; private JTextField jtfName; private JTextArea jtaTextAreaMessage; // имя клиента private String clientName = ""; // получаем имя клиента public String getClientName() { return this.clientName; } // конструктор public ClientWindow() { try { // подключаемся к серверу clientSocket = new Socket(SERVER_HOST, SERVER_PORT); inMessage = new Scanner(clientSocket.getInputStream()); outMessage = new PrintWriter(clientSocket.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } // Задаём настройки элементов на форме setBounds(600, 300, 600, 500); setTitle("Client"); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jtaTextAreaMessage = new JTextArea(); jtaTextAreaMessage.setEditable(false); jtaTextAreaMessage.setLineWrap(true); JScrollPane jsp = new JScrollPane(jtaTextAreaMessage); add(jsp, BorderLayout.CENTER); // label, который будет отражать количество клиентов в чате JLabel jlNumberOfClients = new JLabel("Количество клиентов в чате: "); add(jlNumberOfClients, BorderLayout.NORTH); JPanel bottomPanel = new JPanel(new BorderLayout()); add(bottomPanel, BorderLayout.SOUTH); JButton jbSendMessage = new JButton("Отправить"); bottomPanel.add(jbSendMessage, BorderLayout.EAST); jtfMessage = new JTextField("Введите ваше сообщение: "); bottomPanel.add(jtfMessage, BorderLayout.CENTER); jtfName = new JTextField("Введите ваше имя: "); bottomPanel.add(jtfName, BorderLayout.WEST); // обработчик события нажатия кнопки отправки сообщения jbSendMessage.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // если имя клиента, и сообщение непустые, то отправляем сообщение if (!jtfMessage.getText().trim().isEmpty() && !jtfName.getText().trim().isEmpty()) { clientName = jtfName.getText(); sendMsg(); // фокус на текстовое поле с сообщением jtfMessage.grabFocus(); } } }); // при фокусе поле сообщения очищается jtfMessage.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { jtfMessage.setText(""); } }); // при фокусе поле имя очищается jtfName.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { jtfName.setText(""); } }); // в отдельном потоке начинаем работу с сервером new Thread(new Runnable() { @Override public void run() { try { // бесконечный цикл while (true) { // если есть входящее сообщение if (inMessage.hasNext()) { // считываем его String inMes = inMessage.nextLine(); String clientsInChat = "Клиентов в чате = "; if (inMes.indexOf(clientsInChat) == 0) { jlNumberOfClients.setText(inMes); } else { // выводим сообщение jtaTextAreaMessage.append(inMes); // добавляем строку перехода jtaTextAreaMessage.append("\n"); } } } } catch (Exception e) { } } }).start(); // добавляем обработчик события закрытия окна клиентского приложения addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { super.windowClosing(e); try { // здесь проверяем, что имя клиента непустое и не равно значению по умолчанию if (!clientName.isEmpty() && clientName != "Введите ваше имя: ") { outMessage.println(clientName + " вышел из чата!"); } else { outMessage.println("Участник вышел из чата, так и не представившись!"); } // отправляем служебное сообщение, которое является признаком того, что клиент вышел из чата outMessage.println("##session##end##"); outMessage.flush(); outMessage.close(); inMessage.close(); clientSocket.close(); } catch (IOException exc) { } } }); // отображаем форму setVisible(true); } // отправка сообщения public void sendMsg() { // формируем сообщение для отправки на сервер String messageStr = jtfName.getText() + ": " + jtfMessage.getText(); // отправляем сообщение outMessage.println(messageStr); outMessage.flush(); jtfMessage.setText(""); } }
Для проверки работоспособность программы сначала запускаем сервер. Далее можно запускать сколько угодно клиентских приложений. Результат работы программы при двух подключениях клиентов на скриншоте ниже:
В данной статье мы создали клиентскую часть простого чата на Java.
На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.