首先,我们先在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>