记录一个咸鱼大学生三个月的奋进生活023
复习Java(仿QQ聊天系统01界面部分)
在我们学完多线程、I/O、网络编程等知识后应该做个项目来实践一下之前学的知识,我能想到的就是做一个简易的仿照QQ的聊天系统,我们可以通过 多线程实现一个又一个用户的登录,网络传输和I/O来配合实现发送和接收消息,Javaswing实现系统的可视化 等。
该项目分为client客户端代码和server服务器端代码并配合MVC分层设计模式,今天先从ui界面层开始一步一步复习。
每个代码的意思我也在备注里标注的很清楚了,再有不明白的或者改进意见的大家可以在评论区指出!
设置背景(ImgPanel)类
package com.test;
// 设置背景图片的panel类,比第一次项目改进了一下,这次重写了构造方法,可以直接在实例化时传入图片路径就可以把图片设置为panel背景
import java.awt.Graphics;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class ImgPanel extends JPanel {
private ImageIcon img = null;
// 获得当前项目的绝对路径
public String getSystempath() {
File f = new File("");
return f.getAbsolutePath();
}
public ImgPanel() {
// TODO Auto-generated constructor stub
}
// 重写构造方法传入图片路径再用ImageIcon实例化,然后再通过paintComponent实例化图片背景
public ImgPanel(String imgPath) {
this.img = new ImageIcon(this.getSystempath() + imgPath );
}
@Override
protected void paintComponent(Graphics g) {
// 画笔设置图片背景方法
g.drawImage(this.img.getImage(), 0, 0, this);
}
}
登录界面(LoginFrame)类
package com.test;
// 用户进行登录的页面
import java.awt.BorderLayout;
import java.awt.Font;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class LoginFrame extends JFrame{
private JPanel bodyPanel; // 所有界面panel,一个大body和中间的登录框centerPanel以及底部的按钮bottomPanel
private JPanel centerPanel;
private JPanel bottomPanel;
private JLabel accountLabel; // 用户名和密码的输入panel
private JTextField accountTextField;
private JLabel passowrdLabel;
private JPasswordField passwordField;
private JButton loginButton; // 登录和注册按钮
private JButton registerButton;
// 中间的操作panel
private void initCenter() {
this.centerPanel = new ImgPanel("./img/login.png"); // 实例化ImgPanel专门设背景的对象将登录页面的背景图片传入
this.accountLabel = new JLabel("用 户 名:");
this.accountTextField = new JTextField(16);
this.accountLabel.setFont(new Font("微软雅黑", Font.BOLD, 17)); // setFont(new Font("字体", Font.样式, 字体大小)) 设置字体样式的方法
this.passowrdLabel = new JLabel("密 码:");
this.passwordField = new JPasswordField(16);
this.passowrdLabel.setFont(new Font("微软雅黑", Font.BOLD, 18)); // setFont(new Font("字体", Font.样式, 字体大小)) 设置字体样式的方法
// 设置box布局管理器
Box box0 = Box.createVerticalBox();
Box box1 = Box.createHorizontalBox();
Box box2 = Box.createHorizontalBox();
box1.add(accountLabel);
box1.add(accountTextField);
box2.add(passowrdLabel);
box2.add(passwordField);
box0.add(Box.createVerticalStrut(90));
box0.add(box1);
box0.add(Box.createVerticalStrut(20));
box0.add(box2);
this.centerPanel.add(box0);
}
// 底部的按钮panel
private void initBottom() {
this.bottomPanel = new JPanel();
this.loginButton = new JButton("登 录");
this.bottomPanel.add(this.loginButton);
this.registerButton = new JButton("注 册");
this.bottomPanel.add(this.registerButton);
}
// 窗体代码
private void init() {
this.bodyPanel = (JPanel)this.getContentPane();
this.bodyPanel.setLayout(new BorderLayout());
this.initCenter();
this.bodyPanel.add(this.centerPanel, BorderLayout.CENTER);
this.initBottom();
this.bodyPanel.add(this.bottomPanel, BorderLayout.SOUTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("QQ登录页面");
}
// 重写构造方法
public LoginFrame() {
this.init();
}
// 主方法运行main方法
public static void main(String[] args) {
LoginFrame loginFrame1 = new LoginFrame();
loginFrame1.setBounds(680, 340, 500, 320);
loginFrame1.setVisible(true);
}
}
登录界面的效果:

注册界面(RegisterFrame)类
package com.test;
// 用户进行注册的页面
// 1.0是静态的注册页面代码
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class RegisterFrame extends JFrame {
private JPanel bodyPanel = null;
private JPanel centerPanel = null;
private JPanel bottomPanel = null;
private JLabel accountLabel = null;
private JLabel nameLabel = null;
private JLabel passwordLabel = null;
private JLabel repasswordLabel = null;
private JLabel imgLabel = null;
private JTextField accountTextField = null;
private JTextField nameTextField = null;
private JPasswordField passwordField = null;
private JPasswordField repasswordField = null;
private JComboBox imgComboBox = null;
private JButton registerButton = null;
private JButton cancelButton = null;
// 中间输入信息界面的代码
private void initCenter() {
// 通过ImgPanel的构造方法实例化panel背景
this.centerPanel = new ImgPanel("./img/register.png");
this.accountLabel = new JLabel("用 户 名 :", JLabel.RIGHT);
this.accountLabel.setPreferredSize(new Dimension(70, 24)); // .setPreferredSize(new Dimension(宽, 高)) 设置panel大小方法但是会随着界面大小变化而变化
this.nameLabel = new JLabel("昵 称:", JLabel.RIGHT);
this.nameLabel.setPreferredSize(new Dimension(70, 24));
this.passwordLabel = new JLabel("密 码:", JLabel.RIGHT);
this.passwordLabel.setPreferredSize(new Dimension(70, 24));
this.repasswordLabel = new JLabel("确认密码:", JLabel.RIGHT);
this.repasswordLabel.setPreferredSize(new Dimension(70, 24));
this.imgLabel = new JLabel("选择头像:", JLabel.RIGHT);
this.imgLabel.setPreferredSize(new Dimension(70, 24));
this.accountTextField = new JTextField();
this.accountTextField.setPreferredSize(new Dimension(160, 24));
this.nameTextField = new JTextField();
this.nameTextField.setPreferredSize(new Dimension(160, 24));
this.passwordField = new JPasswordField();
this.passwordField.setPreferredSize(new Dimension(160, 24));
this.repasswordField = new JPasswordField();
this.repasswordField.setPreferredSize(new Dimension(160, 24));
this.imgComboBox = new JComboBox();
// Box布局管理器,需要五个横着panel时需要声明一个大的竖着的box包裹住五个横着的box
Box box0 = Box.createVerticalBox(); // .createVerticalBox()创建竖着的box方法
Box box1 = Box.createHorizontalBox(); // .createHorizontalBox()创建横着的box方法
Box box2 = Box.createHorizontalBox();
Box box3 = Box.createHorizontalBox();
Box box4 = Box.createHorizontalBox();
Box box5 = Box.createHorizontalBox();
box1.add(this.accountLabel);
box1.add(this.accountTextField);
box2.add(this.nameLabel);
box2.add(this.nameTextField);
box3.add(this.passwordLabel);
box3.add(this.passwordField);
box4.add(this.repasswordLabel);
box4.add(this.repasswordField);
box5.add(this.imgLabel);
box5.add(this.imgComboBox);
box0.add(Box.createVerticalStrut(90)); // .createVerticalStrut(间距)设置每个box之间间距的方法
box0.add(box1);
box0.add(Box.createVerticalStrut(10));
box0.add(box2);
box0.add(Box.createVerticalStrut(10));
box0.add(box3);
box0.add(Box.createVerticalStrut(10));
box0.add(box4);
box0.add(Box.createVerticalStrut(10));
box0.add(box5);
this.centerPanel.add(box0);
}
// 下方按钮panel的代码
private void initBottom() {
this.bottomPanel = new JPanel();
this.registerButton = new JButton("注 册");
this.cancelButton = new JButton("重 置");
this.bottomPanel.add(this.registerButton);
this.bottomPanel.add(this.cancelButton);
}
// 生成窗体的方法
private void init() {
this.bodyPanel = (JPanel)this.getContentPane();
this.bodyPanel.setLayout(new BorderLayout());
this.initCenter();
this.bodyPanel.add(this.centerPanel, BorderLayout.CENTER);
this.initBottom();
this.bodyPanel.add(this.bottomPanel, BorderLayout.SOUTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("QQ注册页面");
}
// 重写构造方法,实例化时生成注册窗体并与服务器进行传输通讯连接
public RegisterFrame() {
this.init();
}
public static void main(String[] args) {
RegisterFrame registerFrame = new RegisterFrame();
registerFrame.setBounds(700, 320, 512, 390);
registerFrame.setVisible(true);
}
}
注册界面的效果:

好友列表界面(MainFrame)类
package com.test;
// 好友列表页面
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MainFrame extends JFrame {
private JLabel userLabel = null; // 该用户名的顶部panel
private JPanel bodyPanel = null;
// 重写构造方法
public MainFrame() {
// TODO Auto-generated constructor stub
this.init();
}
// init主页面方法
private void init() {
this.bodyPanel = (JPanel)this.getContentPane();
this.bodyPanel.setLayout(new BorderLayout());
this.userLabel = new JLabel("test的好友列表");
this.bodyPanel.add(this.userLabel, BorderLayout.NORTH);
this.setBounds(1625, 0, 300, 800);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("test的好友列表");
}
public static void main(String[] args) {
MainFrame MainFrame = new MainFrame();
MainFrame.setBounds(1625, 0, 300, 800);
MainFrame.setVisible(true);
}
}
好友列表界面的效果:

发送信息界面(SendFrame)类
package com.test;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class SendFrame extends JFrame {
private JPanel topPanel;
private JPanel bottomPanel;
private JLabel receiverLabel = null;
private JTextField receiverField = null;
private JLabel sendercontentLabel = null;
private JTextArea sendArea;
private JButton sendButton;
private JButton closeButton;
private void init() {
JPanel bodyPanel = (JPanel)this.getContentPane();
bodyPanel.setLayout(new BorderLayout());
this.topPanel = new JPanel();
this.bottomPanel = new JPanel();
bodyPanel.add(this.topPanel, BorderLayout.CENTER);
bodyPanel.add(this.bottomPanel, BorderLayout.SOUTH);
this.receiverLabel = new JLabel("接收者:");
this.receiverField = new JTextField();
this.receiverField.setPreferredSize(new Dimension(400, 25));
this.receiverField.setEditable(false);
this.receiverField.setText("test的接收者");
this.sendercontentLabel = new JLabel("发送内容:");
this.sendArea = new JTextArea();
this.sendArea.setPreferredSize(new Dimension(400, 130));
JScrollPane sendScrollPane = new JScrollPane(this.sendArea);
Box box = Box.createVerticalBox();
Box box1 = Box.createHorizontalBox();
Box box2 = Box.createHorizontalBox();
box1.add(this.receiverLabel);
box1.add(this.receiverField);
box2.add(this.sendercontentLabel);
box2.add(sendScrollPane);
box.add(Box.createVerticalStrut(10));
box.add(box1);
box.add(Box.createVerticalStrut(10));
box.add(box2);
this.topPanel.add(box);
this.bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 50, 10));
this.sendButton = new JButton("发送");
this.closeButton = new JButton("关闭");
this.bottomPanel.add(this.sendButton);
this.bottomPanel.add(this.closeButton);
this.setTitle("test的发送框");
this.setBounds(600, 370, 500, 280);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public SendFrame() {
// TODO Auto-generated constructor stub
this.init();
}
public static void main(String[] args) {
SendFrame SendFrame = new SendFrame();
SendFrame.setBounds(700, 360, 500, 280);
SendFrame.setVisible(true);
}
}
发送信息界面的效果:

接收信息界面(ReceiveFrame)类
package com.test;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ReceiveFrame extends JFrame {
private String message = null;
private JPanel topPanel;
private JPanel bottomPanel;
private JLabel fromLabel = null;
private JTextField fromField = null;
private JLabel contentLabel = null;
private JTextArea contentArea;
private JButton repeatButton;
private JButton closeButton;
private void init() {
JPanel bodyPanel = (JPanel)this.getContentPane();
bodyPanel.setLayout(new BorderLayout());
this.topPanel = new JPanel();
this.bottomPanel = new JPanel();
bodyPanel.add(this.topPanel, BorderLayout.CENTER);
bodyPanel.add(this.bottomPanel, BorderLayout.SOUTH);
this.fromLabel = new JLabel("来自于:");
this.fromField = new JTextField();
this.fromField.setPreferredSize(new Dimension(400, 25));
this.fromField.setEditable(false);
this.fromField.setText("test");
this.contentLabel = new JLabel("接收内容:");
this.contentArea = new JTextArea();
this.contentArea.setPreferredSize(new Dimension(400, 130));
this.contentArea.setText(this.message);
this.contentArea.setEditable(false);
JScrollPane contentScrollPane = new JScrollPane(this.contentArea);
Box box = Box.createVerticalBox();
Box box1 = Box.createHorizontalBox();
Box box2 = Box.createHorizontalBox();
box1.add(this.fromLabel);
box1.add(this.fromField);
box2.add(this.contentLabel);
box2.add(contentScrollPane);
box.add(Box.createVerticalStrut(10));
box.add(box1);
box.add(Box.createVerticalStrut(10));
box.add(box2);
this.topPanel.add(box);
this.bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 50, 10));
this.repeatButton = new JButton("回复");
this.closeButton = new JButton("关闭");
this.bottomPanel.add(this.repeatButton);
this.bottomPanel.add(this.closeButton);
this.setTitle("test的接收框");
this.setBounds(700, 360, 500, 280);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public ReceiveFrame() {
// TODO Auto-generated constructor stub
this.init();
}
public static void main(String[] args) {
ReceiveFrame ReceiveFrame = new ReceiveFrame();
ReceiveFrame.setBounds(700, 360, 500, 280);
ReceiveFrame.setVisible(true);
}
}
接收信息界面的效果:

学习Java面试题(Redis的过期策略和内存淘汰策略)



照片分享
