用Tcp实现一对多聊天

1 篇文章 0 订阅
1 篇文章 0 订阅

首先,我们先在idea中用GUI Form设计一个聊天框,swing本人也不是很会,但查看一下GUI Form然后用它来做个界面问题不大。

用idea创建java项目就不写了

在设置和新项目设置中配置和引入依赖

<dependency>
    <groupId>com.intellij</groupId>
    <artifactId>forms_rt</artifactId>
    <version>7.0.3</version>
</dependency>

创建GUI窗体

通过拖动组件实现如下效果

 改变一下拖入的组件字体大小和名字

改变一下textField和两个button的高度,和给这个三个组件添加侦听器

组件中的内容在这里修改

 

 给textArea设置不可编辑

窗口界面就设计结束了,查看代码,可以看到对于的组件和监听方法已加入

alt + insert 在类中生成窗体main方法

修改下代码,实现我们想要的聊天框效果并运行main方法,代码简单就不描述,疑惑的有注释。

package lcj.example;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ChatServerGUI {
    private JTextArea textArea;
    private JPanel panel;
    private JTextField textField;
    private JButton sendButton;
    private JButton clearButton;

    public ChatServerGUI() {
        textField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textArea.append(textField.getText() + "\n");
                textField.setText("");
            }
        });
        sendButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textArea.append(textField.getText() + "\n");
                textField.setText("");
            }
        });
        clearButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textField.setText("");
            }
        });
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("ChatServerGUI");
        frame.setContentPane(new ChatServerGUI().panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(960, 660);
        frame.setVisible(true);
    }
}

可以看到自动在类中为我们自动生成了窗口设计的代码 

窗体效果

下面开始用tcp实现一对多聊天并通过他来为我们提供界面操作

修改ChatServerGUI类的代码

package lcj.example;

import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import lombok.extern.log4j.Log4j2;

import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import javax.swing.text.StyleContext;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Locale;

@Log4j2
public class ChatServerGUI {
    private JTextArea textArea;
    private JPanel panel;
    private JTextField textField;
    private JButton sendButton;
    private JButton clearButton;

    public ChatServerGUI(int port) {
        JFrame frame = new JFrame("聊天服务器");
        frame.setContentPane(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(960, 660);
        frame.setVisible(true);
        textField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String input = textField.getText();
                textField.setText("");
                textArea.append("服务器:" + input + "\n");
                BufferedWriter bw;
                try {
                    for (Socket socket : clientSocketlist) {
                        bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                        bw.write("服务器:" + input + "\n");
                        bw.flush();
                    }
                } catch (IOException ex) {
                    log.error("", ex);
                }
            }
        });
        sendButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String input = textField.getText();
                textField.setText("");
                textArea.append("服务器:" + input + "\n");
                BufferedWriter bw;
                try {
                    for (Socket socket : clientSocketlist) {
                        bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                        bw.write("服务器:" + input + "\n");
                        bw.flush();
                    }
                } catch (IOException ex) {
                    log.error("", ex);
                }
            }
        });
        clearButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textField.setText("");
            }
        });
        newServerSocket(port);
    }

    private Socket clientSocket;
    private ArrayList<Socket> clientSocketlist = new ArrayList<>();

    public void newServerSocket(int port) {
        try {
            ServerSocket serverSocket = new ServerSocket(port);
            while (true) {
                clientSocket = serverSocket.accept();
                clientSocketlist.add(clientSocket);
                new Thread(new ClientThread(clientSocket)).start();
            }
        } catch (IOException e) {
            log.error("建立服务器套接字异常:" + e);
        }
    }

    class ClientThread implements Runnable {
        private Socket clientSocket;
        private BufferedReader br;
        String msg;

        ClientThread(Socket socket) {
            this.clientSocket = socket;
            try {
                br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            } catch (IOException e) {
                log.error("", e);
            }
        }

        @Override
        public void run() {
            try {
                while (true) {
                    msg = br.readLine();
                    textArea.append(msg + "\n");
                    for (Socket socket : clientSocketlist) {
                        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                        bw.write(msg + "\n");
                        bw.flush();
                    }
                }
            } catch (Exception e) {
                log.error("", e);
            }
        }
    }

    public static void main(String[] args) {
        new ChatServerGUI(8083);
    }

    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        panel = new JPanel();
        panel.setLayout(new GridLayoutManager(2, 3, new Insets(0, 0, 0, 0), -1, -1));
        textArea = new JTextArea();
        textArea.setEditable(false);
        Font textAreaFont = this.$$$getFont$$$(null, -1, 22, textArea.getFont());
        if (textAreaFont != null) textArea.setFont(textAreaFont);
        panel.add(textArea, new GridConstraints(0, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, new Dimension(150, 50), null, 0, false));
        textField = new JTextField();
        Font textFieldFont = this.$$$getFont$$$(null, -1, 22, textField.getFont());
        if (textFieldFont != null) textField.setFont(textFieldFont);
        panel.add(textField, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, 50), null, 0, false));
        sendButton = new JButton();
        Font sendButtonFont = this.$$$getFont$$$(null, -1, 22, sendButton.getFont());
        if (sendButtonFont != null) sendButton.setFont(sendButtonFont);
        sendButton.setText("发送");
        panel.add(sendButton, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 50), null, 0, false));
        clearButton = new JButton();
        Font clearButtonFont = this.$$$getFont$$$(null, -1, 22, clearButton.getFont());
        if (clearButtonFont != null) clearButton.setFont(clearButtonFont);
        clearButton.setText("清空");
        panel.add(clearButton, new GridConstraints(1, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 50), null, 0, false));
    }

    /**
     * @noinspection ALL
     */
    private Font $$$getFont$$$(String fontName, int style, int size, Font currentFont) {
        if (currentFont == null) return null;
        String resultName;
        if (fontName == null) {
            resultName = currentFont.getName();
        } else {
            Font testFont = new Font(fontName, Font.PLAIN, 10);
            if (testFont.canDisplay('a') && testFont.canDisplay('1')) {
                resultName = fontName;
            } else {
                resultName = currentFont.getName();
            }
        }
        Font font = new Font(resultName, style >= 0 ? style : currentFont.getStyle(), size >= 0 ? size : currentFont.getSize());
        boolean isMac = System.getProperty("os.name", "").toLowerCase(Locale.ENGLISH).startsWith("mac");
        Font fontWithFallback = isMac ? new Font(font.getFamily(), font.getStyle(), font.getSize()) : new StyleContext().getFont(font.getFamily(), font.getStyle(), font.getSize());
        return fontWithFallback instanceof FontUIResource ? fontWithFallback : new FontUIResource(fontWithFallback);
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return panel;
    }

}
package lcj.example;

import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import lombok.extern.log4j.Log4j2;

import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import javax.swing.text.StyleContext;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;
import java.util.Locale;

@Log4j2
public class ChatClientGUI {
    private JTextArea textArea;
    private JPanel panel;
    private JTextField textField;
    private JButton sendButton;
    private JButton clearButton;

    private String ip;
    private int port;
    private String userName;

    public ChatClientGUI(String ip, int port, String userName) {
        this.ip = ip;
        this.port = port;
        this.userName = userName;
        createChatGUI();
        newClientSocket();
    }

    public void createChatGUI() {
        JFrame frame = new JFrame(userName);
        frame.setContentPane(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(960, 660);
        frame.setVisible(true);
        textField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String input = textField.getText();
                textField.setText("");
                try {
                    bw.write(userName + ":" + input + "\n");
                    bw.flush();
                } catch (IOException ex) {
                    log.error("", ex);
                }
            }
        });
        sendButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String input = textField.getText();
                textField.setText("");
                try {
                    bw.write(userName + ":" + input + "\n");
                    bw.flush();
                } catch (IOException ex) {
                    log.error("", ex);
                }
            }
        });
        clearButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textField.setText("");
            }
        });
    }

    private BufferedWriter bw;

    public void newClientSocket() {
        try {
            Socket clientSocket = new Socket(ip, port);
            bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            new Thread(new ServerThread(clientSocket)).start();
        } catch (IOException e) {
            log.error("建立套接字连接异常:" + e);
        }
    }

    class ServerThread implements Runnable {
        private Socket clientSocket;
        private BufferedReader br;
        String msg;

        ServerThread(Socket socket) {
            this.clientSocket = socket;
            try {
                br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            } catch (IOException e) {
                log.error("", e);
            }
        }

        @Override
        public void run() {
            try {
                while (true) {
                    msg = br.readLine();
                    textArea.append(msg + "\n");
                }
            } catch (IOException e) {
                log.error("", e);
            }
        }
    }

    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        panel = new JPanel();
        panel.setLayout(new GridLayoutManager(2, 3, new Insets(0, 0, 0, 0), -1, -1));
        textArea = new JTextArea();
        textArea.setEditable(false);
        Font textAreaFont = this.$$$getFont$$$(null, -1, 22, textArea.getFont());
        if (textAreaFont != null) textArea.setFont(textAreaFont);
        panel.add(textArea, new GridConstraints(0, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, new Dimension(150, 50), null, 0, false));
        textField = new JTextField();
        Font textFieldFont = this.$$$getFont$$$(null, -1, 22, textField.getFont());
        if (textFieldFont != null) textField.setFont(textFieldFont);
        panel.add(textField, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, 50), null, 0, false));
        sendButton = new JButton();
        Font sendButtonFont = this.$$$getFont$$$(null, -1, 22, sendButton.getFont());
        if (sendButtonFont != null) sendButton.setFont(sendButtonFont);
        sendButton.setText("发送");
        panel.add(sendButton, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 50), null, 0, false));
        clearButton = new JButton();
        Font clearButtonFont = this.$$$getFont$$$(null, -1, 22, clearButton.getFont());
        if (clearButtonFont != null) clearButton.setFont(clearButtonFont);
        clearButton.setText("清空");
        panel.add(clearButton, new GridConstraints(1, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 50), null, 0, false));
    }

    /**
     * @noinspection ALL
     */
    private Font $$$getFont$$$(String fontName, int style, int size, Font currentFont) {
        if (currentFont == null) return null;
        String resultName;
        if (fontName == null) {
            resultName = currentFont.getName();
        } else {
            Font testFont = new Font(fontName, Font.PLAIN, 10);
            if (testFont.canDisplay('a') && testFont.canDisplay('1')) {
                resultName = fontName;
            } else {
                resultName = currentFont.getName();
            }
        }
        Font font = new Font(resultName, style >= 0 ? style : currentFont.getStyle(), size >= 0 ? size : currentFont.getSize());
        boolean isMac = System.getProperty("os.name", "").toLowerCase(Locale.ENGLISH).startsWith("mac");
        Font fontWithFallback = isMac ? new Font(font.getFamily(), font.getStyle(), font.getSize()) : new StyleContext().getFont(font.getFamily(), font.getStyle(), font.getSize());
        return fontWithFallback instanceof FontUIResource ? fontWithFallback : new FontUIResource(fontWithFallback);
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return panel;
    }
}
package lcj.example;

public class UserA {

    public static void main(String[] args) {
        new ChatClientGUI(("127.0.0.1"), 8083, "用户A");
    }
}

package lcj.example;

public class UserB {

    public static void main(String[] args) {
        new ChatClientGUI(("127.0.0.1"), 8083, "用户B");
    }
}

pom.xml 

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>lcj.example</groupId>
    <artifactId>tcpchat1-n</artifactId>
    <version>1.0</version>

    <name>tcpchat1-n</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.intellij</groupId>
            <artifactId>forms_rt</artifactId>
            <version>7.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.17.2</version>
        </dependency>
    </dependencies>
</project>

src/main/resources/log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="INFO">
    <appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <RollingFile name="RollingFile" fileName="logs/app.log"
                     filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
            <SizeBasedTriggeringPolicy size="5 MB"/>
        </RollingFile>

        <RollingFile name="SUCCESS_FILE" fileName="logs/success.log"
                     filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
            <SizeBasedTriggeringPolicy size="5 MB"/>
        </RollingFile>
    </appenders>
    <loggers>
        <root level="DEBUG">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFile"/>
        </root>

        <logger name="success" additivity="false">
            <appender-ref ref="SUCCESS_FILE"/>
        </logger>
    </loggers>
</configuration>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值