Java后端学习精华|??Java实现模拟QQ(消息通信+登陆界面美化)??
一、登陆界面的实现
登陆界面主要使用了JFrame,以及相关的一些组件,并且在界面中加上监听
登陆界面效果图
文章图片
登陆界面代码Login类
package com.lding.login;
import com.lding.ui.MsgUI;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.DelayQueue;
/**
* @program: Net
* @description: 登陆类
* @author: 王丁
* @date: 2021-09-25 14:47
**/
public class Login {private OutputStream outputStream;
private String port;
private InputStream inputStream;
private boolean flag=false;
private JTextField jTextField;
private JPasswordField jPasswordField;
public JTextField getjTextField() {return jTextField;
}public void setjTextField(JTextField jTextField) {this.jTextField = jTextField;
}public JPasswordField getjPasswordField() {return jPasswordField;
}public void setjPasswordField(JPasswordField jPasswordField) {this.jPasswordField = jPasswordField;
}public boolean isFlag() {return flag;
}public void setFlag(boolean flag) {this.flag = flag;
}public Login(String port){this.port=port;
}
public Login(InputStream inputStream,OutputStream outputStream, String port) {this.outputStream = outputStream;
this.port = port;
this.inputStream=inputStream;
}public OutputStream getOutputStream() {return outputStream;
}public void setOutputStream(OutputStream outputStream) {this.outputStream = outputStream;
}public String getPort() {return port;
}public void setPort(String port) {this.port = port;
}public InputStream getInputStream() {return inputStream;
}public void setInputStream(InputStream inputStream) {this.inputStream = inputStream;
}public void showUI(Login login){JFrame jf=new JFrame();
jf.setTitle("??DDqq登陆界面??");
jf.setSize(500,400);
//只对顶级容器有效
jf.setDefaultCloseOperation(3);
//窗体关闭时结束程序
jf.setLocationRelativeTo(null);
//居中
jf.setResizable(false);
//选择布局类型,定义流式布局对对象,并且设置每个组件之间相隔5
FlowLayout fl=new FlowLayout(FlowLayout.CENTER,5,5);
jf.setLayout(fl);
//设置顶级容器的布局为流式布局
//设置不同组件的格式大小
Dimension dim1=new Dimension(500,200);
//图片大小
Dimension dim2=new Dimension(100,50);
//标签大小
Dimension dim3=new Dimension(300,30);
//输入框大小
Dimension dim4=new Dimension(100,40);
//按钮大小
//添加组件
//添加图片,先把图片加载到内存中,利用ImageIcon类把图片加载到内存
ImageIcon icon=new ImageIcon("source/Login1.jpg");
JLabel labimg=new JLabel(icon);
//不可以直接把图片加到顶级容器中,需要先将其设置为表桥
labimg.setPreferredSize(dim1);
jf.add(labimg);
//再将标签加到顶级容器中//添加账号标签
JLabel labuser=new JLabel();
labuser.setText("user:");
labuser.setPreferredSize(dim2);
jf.add(labuser);
//添加账号输入框
JTextField textuser=new JTextField();
textuser.setPreferredSize(dim3);
jf.add(textuser);
//添加密码标签
JLabel labpassword=new JLabel();
labpassword.setText("password:");
labpassword.setPreferredSize(dim2);
jf.add(labpassword);
//添加密码输入框
JPasswordField textPassword=new JPasswordField();
textPassword.setPreferredSize(dim3);
jf.add(textPassword);
//添加一个button按钮
JButton button=new JButton();
button.setBorder(BorderFactory.createRaisedBevelBorder());
button.setText("login");
button.setPreferredSize(dim4);
jf.add(button);
jf.setVisible(true);
//首先实例化登陆按钮监听类的对象,并把登陆界面中的账号和密码输入框的对象传给它
LoginListener ll=new LoginListener(jf,textuser,textPassword,login);
//对当前窗体添加监听方法
button.addActionListener(ll);
//监控按钮
while (true){//for(int i=0;
i<10000000;
i++){//for(int j=0;
j<1000000;
j++){//
//}
//}
//起到延时的作用,
System.out.println(1);
//如果登陆完毕咋可以跳出这个循环
this.flag=ll.isFlag();
if(this.flag)
break;
}
this.jTextField=ll.getjTextField();
this.jPasswordField=ll.getjPasswordField();
System.out.println("ok");
}
}
【Java后端学习精华|??Java实现模拟QQ(消息通信+登陆界面美化)??】login的监听类 LoginListener
package com.lding.login;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
/**
* @program: Net
* @description:
* @author: 王丁
* @date: 2021-09-25 16:17
**/
public class LoginListener implements ActionListener {private JTextField jTextField;
private JPasswordField jPasswordField;
private JFrame login;
private Login loginnew;
private boolean flag=false;
public JTextField getjTextField() {return jTextField;
}public void setjTextField(JTextField jTextField) {this.jTextField = jTextField;
}public JPasswordField getjPasswordField() {return jPasswordField;
}public void setjPasswordField(JPasswordField jPasswordField) {this.jPasswordField = jPasswordField;
}public boolean isFlag() {return flag;
}public void setFlag(boolean flag) {this.flag = flag;
}public LoginListener(JFrame login, JTextField jTextField, JPasswordField jPasswordField, Login loginnew) {this.jTextField = jTextField;
this.jPasswordField = jPasswordField;
this.login = login;
this.loginnew=loginnew;
}@Override
public void actionPerformed(ActionEvent e) {//输入框需要getText()才能得到字符串
if(jTextField.getText().equals("lding")&&String.valueOf(jPasswordField.getPassword()).equals("123456")){this.flag=true;
//关闭这个登陆页面,登陆完毕
login.dispose();
}else if(jTextField.getText().equals("Alice")&&String.valueOf(jPasswordField.getPassword()).equals("123456")){System.out.println(2);
this.flag=true;
login.dispose();
}}
}
在登陆完毕后,需要跳转到聊天界面,这里采用的方法是通过一个flag标志来判断是否登陆完毕,当登陆完毕后,会创建新的聊天界面,并且登陆页面会被关闭
依然是双端通信,假定一端为客户端,一端为服务端,其实两端都可为用户。
聊天界面运行图
先登陆Alice的账号 密码为123456
文章图片
登陆成功后显示ok,并等待连接
文章图片
再登陆冷丁的账号,密码为123456
文章图片
当lding账号登陆成功后完成连接,这时候会弹出两个新的JFram窗口,为聊天见面
文章图片
随后可以发送消息,消息可以实时显示时间,并显示用户名
一方发送的消息会在另一方的窗口上实时显示出来
文章图片
MsgClient类代码
package com.lding.net;
import com.lding.login.Login;
import com.lding.ui.MsgUI;
import javax.swing.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @program: Net
* @description: 聊天室客户端
* @author: 王丁
* @date: 2021-09-25 10:42
**/
public class MsgClient {static public JTextField jTextField;
staticprivate JPasswordField jPasswordField;
public JTextField getjTextField() {return jTextField;
}public void setjTextField(JTextField jTextField) {this.jTextField = jTextField;
}public JPasswordField getjPasswordField() {return jPasswordField;
}public void setjPasswordField(JPasswordField jPasswordField) {this.jPasswordField = jPasswordField;
}public staticvoid main(String[] args) throws IOException {//调用登陆界面
String port="客户端";
Login login=new Login(port);
login.showUI(login);
//为了防止客户端还没登陆就弹出聊天界面
//通过判断flag,当客户端完成登陆后
//在login的监听器中将其flag变为true,从而一层层的把客户端中的flag变为true
if(login.isFlag()){//客户端读取登陆用户的名字,也是通过一层层读取
jTextField=login.getjTextField();
String name=jTextField.getText();
System.out.println(login.isFlag());
//创建一个Socket连接
Socket socket=new Socket("127.0.0.1",8888);
//输入 输出流对象
InputStream inputStream=socket.getInputStream();
OutputStream outputStream=socket.getOutputStream();
//创建聊天页面
MsgUI msgUI=new MsgUI(outputStream,name);
JTextPane showmsgpane=msgUI.initUI(name);
//这里用count来判断是用户名输入还是内容输入
//由于消息是两部分拼接的,在消息监听器中先后发送了两部分消息
//第一部分是发送者的名字,第二部分是消息内容
//在输出两种消息的时候采用两种不同的格式,所以对count进行判断
int count=1;
while(true){int msglenth=inputStream.read();
System.out.println("消息长度:"+msglenth);
byte[] msgbytes=new byte[msglenth];
//将接下来的数据读入字节数组中
inputStream.read(msgbytes);
count++;
if(count%2==0){SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//设置日期格式
String date = df.format(new Date());
// new Date()为获取当前系统时间,也可使用当前时间戳
String getmsg=new String(msgbytes);
String msg=showmsgpane.getText();
showmsgpane.setText(msg+date+"["+getmsg+"]"+"说:"+"\n");
}else{String getmsg=new String(msgbytes);
String msg=showmsgpane.getText();
showmsgpane.setText(msg+getmsg+"\n");
}
}
}
}
}
MsgServer代码
package com.lding.net;
import com.lding.login.Login;
import com.lding.ui.MsgUI;
import javax.swing.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @program: Net
* @description: 聊天室服务端
* @author: 王丁
* @date: 2021-09-25 10:42
**/
public class MsgServer {staticpublic JTextField jTextField;
staticprivate JPasswordField jPasswordField;
public JTextField getjTextField() {return jTextField;
}public void setjTextField(JTextField jTextField) {this.jTextField = jTextField;
}public JPasswordField getjPasswordField() {return jPasswordField;
}public void setjPasswordField(JPasswordField jPasswordField) {this.jPasswordField = jPasswordField;
}public void MsgServerInit(){}
publicstatic void main(String[] args) throws IOException {//调用登陆页面
String port="服务端";
Login login=new Login(port);
login.showUI(login);
/*********************************************/
ServerSocket serverSocket=new ServerSocket(8888);
System.out.println("等待连接!!");
Socket clientsocket=serverSocket.accept();
//监听连接
System.out.println("连接成功!!");
jTextField=login.getjTextField();
String name=jTextField.getText();
InputStream inputStream=clientsocket.getInputStream();
OutputStream outputStream=clientsocket.getOutputStream();
MsgUI msgUI=new MsgUI(outputStream,name);
JTextPane showmsgpane=msgUI.initUI(name);
//这里用num来判断是用户名输入还是内容输入
//由于消息是两部分拼接的,在消息监听器中先后发送了两部分消息
//第一部分是发送者的名字,第二部分是消息内容
//在输出两种消息的时候采用两种不同的格式,所以对count进行判断
int num=1;
while(true){//根据传入的字符数构造字节数组对象
int msglenth=inputStream.read();
System.out.println("消息长度是:"+msglenth);
byte[] msgbytes=new byte[msglenth];
//将接下来的数据读入字节数组中
inputStream.read(msgbytes);
num++;
if(num%2==0){SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//设置日期格式
String date = df.format(new Date());
// new Date()为获取当前系统时间,也可使用当前时间戳
String getmsg=new String(msgbytes);
String msg=showmsgpane.getText();
showmsgpane.setText(msg+date+"["+getmsg+"]"+"说:"+"\n");
}else{String getmsg=new String(msgbytes);
String msg=showmsgpane.getText();
showmsgpane.setText(msg+getmsg+"\n");
}
}
}
}
代码改进了一下,还有UI的代码再下发 ??Java实现模拟QQ(改进版)?? 之后会丰富更多功能 敬请期待!
感谢您的观看!!!
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 由浅入深理解AOP
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 继续努力,自主学习家庭Day135(20181015)
- python学习之|python学习之 实现QQ自动发送消息
- 事件代理
- 一起来学习C语言的字符串转换函数
- Java|Java OpenCV图像处理之SIFT角点检测详解
- django-前后端交互
- 定制一套英文学习方案