Java模拟qq软件的详细过程

网友投稿 239 2022-09-24


Java模拟qq软件的详细过程

目录登陆界面的实现登陆界面代码Login类login的监听类 LoginListener聊天界面运行图Client类代码Server代码登陆界面代码

**之前在封装代码后出现了问题,按照最初的写法,在登陆完毕后弹出聊天界面后会卡死,原因是当时登陆界面和聊天界面都是使用的主线程,我的代码没有写其他线程,无法多线程运行,因此在弹出聊天界面时线程不够用了,就卡在了监听线程里,因为在监听线程中再有新的监听就会被卡住

在宇哥的指点下,将启动服务器和客户端的部分改为线程,就解决了此问题。改善后的代码简练和清晰了很多,更方便大家参考,代码如下:

**

登陆界面的实现

登陆界面主要使用了JFrame,以及相关的一些组件,并且在界面中加上监听

登陆界面效果图

登陆界面代码Login类

package com.lding.net;

import javax.swing.*;

import java.awt.*;

/**

* @program: Chat

* @description:

* @author: 王丁

* @date: 2021-09-26 08:58

**/

public class Login{

JTextField jTextField;

public static void main(String[] args){

Login login = new Login ();

login.showUI ("kk");

}

public void showUI(String str){

JFrame jf = new JFrame ();

jf.setTitle ("❤️DDqq登陆界面❤️");

jf.setSize (500, 400);

jf.setDefaultCloseOperation (3);

jf.setLocationRelativeTo (null);

jf.setResizable (false);

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 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)WlYAtpOJ;

JLabel labpassword = new JLabel ();

labpassword.setText ("password:");

labpassword.setPreferredSize (dim2);

jf.add (labpassword);

JPasswordField textPassword = new JPasswordField ();

textPassword.setPreferredSize (dim3);

jf.add (textPassword);

JButton button = new JButton ();

button.setBorder (BorderFactory.createRaisedBevelBorder ());

button.setText ("login");

button.setPreferredSize (dim4);

jf.add (button);

jf.setVisible (true);

LoginListener ll = new LoginListener(textuser,textPassword, jf);

button.addActionListener (ll);

this.jTextField=ll.jTextField;

}

}

login的监听类 LoginListener

package com.lding.net;

import javax.swing.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

/**

* @program: Chat

* @description:

* @author: 王丁

* @date: 2021-09-26 08:59

**/

public class LoginListener implements ActionListener {

JTextField jTextField;

JPasswordField jPasswordField;

JFrame jf ;

LoginListener( JTextField jTextField,JPasswordField jPasswordField,JFrame jf){

this.jf=jf;

this.jTextField = jTextField;

this.jPasswordField = jPasswordField;

}

@Override

public void actionPerformed(ActionEvent e){

if(jTextField.getText().equals("Alice")&&String.valueOf(jPasswordField.getPassword()).equals("1234")){

System.out.println ("服务端登录!!");

String name =jTextField.getText();

new Server(name).start();

jf.dispose();

}else if(jTextField.getText().equals("Lding")&&String.valueOf(jPasswordField.getPassword()).equals("1234")){

String name =jTextField.getText();

System.out.println ("客户端登录!!");

new Client(name).start();

jf.dispose();

}

}

}

在登陆完毕后,需要跳转到聊天界面,这里采用的方法是通过一个flag标志来判断是否登陆完毕,当登陆完毕后,会创建新的聊天界面,并且登陆页面会被关闭

依然是双端通信,假定一端为客户端,一端为服务端,其实两端都可为用户。

聊天界面运行图

先登陆Alice的账号 密码为123456

登陆成功后显示ok,并等待连接

再登陆冷丁的账号,密码为123456

当lding账号登陆成功后完成连接,这时候会弹出两个新的JFram窗口,为聊天见面

随后可以发送消息,消息可以实时显示时间,并显示用户名

一方发送的消息会在另一方的窗口上实时显示出来

Client类代码

package com.lding.net;

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: Chat

* @description: 客户端

* @author: 王丁

* @date: 2021-09-26 08:58

**/

public class Client extends Thread{

String name;

public Client(String name) {

this.name=name;

}

public static void main(String[] args) {

String port="客户端";

Login login=new Login();

login.showUI(port);

}

@Override

public void run(){

try {

startClient();

} catch (IOException e) {

e.printStackTrace ();

}

}

void startClient() throws IOException{

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("客户端");

outputStream.flush();

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");

}

}

}

}

Server代码

package com.lding.net;

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: Chat

* @description:

* @author: 王丁

* @date: 2021-09-26 08:58

**/

public class Server extends Thread{

JTextField jTextField;

String name;

public Server(String name){

this.name=name;

}

public static void main(String[] args) {

String port="服务端";

Login login=new Login();

login.showUI(port);

}

@Override

public void run(){

try {

startServer();

} catch (IOException e) {

e.printStackTrace ();

}

}

void startServer() throws IOException{

ServerSocket serverSocket=new ServerSocket(8888);

System.out.println("等待连接!!");

Socket clientsocket=serverSocket.accept();//监听连接

System.out.println("连接成功!!");

InputStream inputStream=clientsocket.getInputStream();

OutputStream outputStream=clientsocket.getOutputStream();

MsgUI msgUI=new MsgUI(outputStream,name);

JTextPane showmsgpane=msgUI.initUI("服务端");

//outputStream.flush();

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");

}

}

}

}

登陆界面代码

MsgUI

package com.lding.ui;

import javax.swing.*;

import java.awt.*;

import java.io.OutputStream;

/**

* @program: Chat

* @description:

* @author: 王丁

* @date: 2021-09-26 08:59

**/

public class MsgUI extends JFrame {

OutputStream outputStream;

String name;

public MsgUI(OutputStream outputStream,String name){

this.outputStream=outputStream;

this.name=name;

}

public JTextPane initUI(String title){

setTitle(title);

setSize(800,800);

setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

setLocationRelativeTo(null);

setLayout(new FlowLayout());

//接收显示框

JTextPane jtp=new JTextPane();

jtp.setPreferredSize(new Dimension(750,400));

jscrollPane jsp=new JScrollPane(jtp);

jtp.getText();

Dimension dim=new Dimension(750,400);//按钮大小

//发送框

JTextPane jtp1=new JTextPane();

jtp1.setPreferredSize(new Dimension(750,200));

JScrollPane jsp1=new JScrollPane(jtp1);

JButton btn=new JButton("发送");

add(jsp);

add(jsp1);

add(btn);

setVisible(true);

MsgListener msgl=new MsgListener(jtp1,this.outputStream,name);

btn.addActionListener(msgl);

return jtp;

}

}

MsgUIListener

package com.lding.ui;

import javax.swing.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.IOException;

import java.io.OutputStream;

/**

* @program: Chat

* @description:

* @author: 王丁

* @date: 2021-09-26 09:00

**/

public class MsgListener implements ActionListener {

JTextPane jtp;

OutputStream outputStream;

String name;

public MsgListener(JTextPane jtp,OutputStream outputStream,String name){

this.jtp=jtp;

this.outputStream=outputStream;

this.name=name;

}

@Override

public void actionPerformed(ActionEvent e) {

byte[] names=this.name.getBytes();

try {

outputStream.write(names.length);

outputStream.write(names);

outputStream.flush();

} catch (IOException ex) {

ex.printStackTrace();

}

String msg=jtp.getText();

byte[] msgs=msg.getBytes();

try {

outputStream.write(msgs.length);

outputStream.write(msgs);

outputStream.flush();

} catch (IOException ex) {

ex.printStackTrace();

}

jtp.setText(null);

}

}

之后会丰富更多功能 敬请期待! 感谢您的观看!!!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:H3C交换设备的IRF(智能弹性架构)工作原理及配置(h3c交换机关闭irf)
下一篇:18、OSPF学习心得6(ospf实训总结)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~