Чат на 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.
На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.




