Java homework four --- write a chat program with a graphical interface

Requirements: Write a chat program with a graphical interface, so that the client can continuously send messages to the server, and the server can also instantly see the messages sent by the client and reply to the client. The program running interface is as follows:

 Server

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;


public class Server implements ActionListener {
    JTextArea textArea;
    JTextField textField;
    JButton sendButton;
    ServerSocket serverSocket;
    List<ClientThread> clients;

    public static void main(String[] args) {
        new Server().start();
    }

    public Server() {
        JFrame frame = new JFrame("服务器");

        JPanel panel = new JPanel(new BorderLayout());
        textArea = new JTextArea(20, 60);
        textArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(textArea);
        panel.add(BorderLayout.CENTER, scrollPane);

        // 添加输入框和发送按钮
        JPanel bottomPanel = new JPanel(new BorderLayout());
        textField = new JTextField(40);
        bottomPanel.add(BorderLayout.CENTER, textField);
        sendButton = new JButton("发送");
        sendButton.addActionListener(this);
        bottomPanel.add(BorderLayout.EAST, sendButton);
        panel.add(BorderLayout.SOUTH, bottomPanel);

        frame.setContentPane(panel);
        frame.setSize(400,300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public void start() {
        try {
            serverSocket = new ServerSocket(8000);
            clients = new ArrayList<ClientThread>();
            while (true) {
                Socket socket = serverSocket.accept();
                ClientThread clientThread = new ClientThread(socket,textArea);
                clients.add(clientThread);
                clientThread.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public synchronized void removeFromClients(ClientThread clientThread) {
        clients.remove(clientThread);
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        String message = textField.getText();
        if (!message.equals("")) {
            // 发送消息给所有客户端
            for (ClientThread client : clients) {
                client.sendToClient("服务器说: " + message);
            }
            textField.setText("");
        }
    }

    class ClientThread extends Thread {
        Socket socket;
        DataInputStream dis;
        DataOutputStream dos;
        JTextArea textArea;

        public ClientThread(Socket socket, JTextArea textArea) {
            this.socket = socket;
            this.textArea = textArea;
            try {
                dis = new DataInputStream(socket.getInputStream());
                dos = new DataOutputStream(socket.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void close() {
            try {
                dos.writeUTF("exit");
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void sendToClient(String message) {
            try {
                synchronized (this) {
                    dos.writeUTF(message);
                    textArea.append(message + "\n"); // 在客户端窗口中显示消息记录
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            try {
                String name = dis.readUTF();
                textArea.append(name + "连接成功!\n"); // 添加消息提示
                while (true) {
                    String message = dis.readUTF();
                    if (message.equals("exit")) {
                        break;
                    }
                    textArea.append("客户端" + "说: " + message + "\n"); // 在服务器窗口中显示消息记录
                }
                textArea.append(name + "离开了!\n");
                removeFromClients(this);
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void sendToAllClients(String message) {
            for (ClientThread client : clients) {
                try {
                    synchronized (client) {
                        if (!this.equals(client)) { // 不要发送给自己
                            client.sendToClient(message);
                        }
                        client.dos.writeUTF(message);
                        client.textArea.append(message + "\n"); // 在客户端窗口中显示消息
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
Client


import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;


public class Client {
	JTextArea textArea;
	JTextField textField;
	Socket socket;
	DataInputStream dis;
	DataOutputStream dos;

	public static void main(String[] args){
		new Client().start();
	}

	public Client() {
		JFrame frame = new JFrame("客户端");
		JPanel panel = new JPanel(new BorderLayout());
		textArea = new JTextArea(20, 60);
		textArea.setEditable(false);
		JScrollPane scrollPane = new JScrollPane(textArea);
		panel.add(BorderLayout.CENTER, scrollPane);

		// 添加输入框和发送按钮
		JPanel bottomPanel = new JPanel(new BorderLayout());
		textField = new JTextField(40);
		bottomPanel.add(BorderLayout.CENTER, textField);
		JButton sendButton = new JButton("发送");
		sendButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				sendMessage();
			}
		});

		bottomPanel.add(BorderLayout.EAST, sendButton);
		panel.add(BorderLayout.SOUTH, bottomPanel);


		frame.setContentPane(panel);
		frame.setSize(400,300);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);

	}

	public void start() {
		try {
			socket = new Socket("127.0.0.1", 8000);
			dis = new DataInputStream(socket.getInputStream());
			dos = new DataOutputStream(socket.getOutputStream());
			String name = JOptionPane.showInputDialog("请输入你的姓名:");
			dos.writeUTF(name);
			Thread listenThread = new ListenThread();
			listenThread.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void sendMessage() {
		try {
			String message = textField.getText();
			if (!message.equals("")) {
				dos.writeUTF(message);
				// 在聊天记录中显示客户端说的话
				textArea.append("客户端说: " + message + "\n");
			}
			textField.setText("");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class ListenThread extends Thread {
		@Override
		public void run() {
			try {
				while (!socket.isClosed()) {
					String message = dis.readUTF();
					textArea.append(message + "\n");
				}
			} catch (IOException e) {
				e.printStackTrace();

			} finally {
				try {
					if (dis != null) dis.close();
					if (dos != null) dos.close();
					if (socket != null) socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

 

Guess you like

Origin blog.csdn.net/m0_59054762/article/details/130440997