Java模拟qq软件的详细过程

作者:冷丁_ 时间:2022-01-27 15:06:19 

目录
  • 登陆界面的实现

    • 登陆界面代码Login类

    • login的监听类 LoginListener

  • 聊天界面运行图

    • Client类代码

    • Server代码

    • 登陆界面代码

**之前在封装代码后出现了问题,按照最初的写法,在登陆完毕后弹出聊天界面后会卡死,原因是当时登陆界面和聊天界面都是使用的主线程,我的代码没有写其他线程,无法多线程运行,因此在弹出聊天界面时线程不够用了,就卡在了监听线程里,因为在监听线程中再有新的监听就会被卡住
在宇哥的指点下,将启动服务器和客户端的部分改为线程,就解决了此问题。改善后的代码简练和清晰了很多,更方便大家参考,代码如下:
**

登陆界面的实现

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

Java模拟qq软件的详细过程

登陆界面代码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);

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

Java模拟qq软件的详细过程

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

Java模拟qq软件的详细过程

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

Java模拟qq软件的详细过程

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

Java模拟qq软件的详细过程

随后可以发送消息,消息可以实时显示时间,并显示用户名
一方发送的消息会在另一方的窗口上实时显示出来

Java模拟qq软件的详细过程

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

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

来源:https://blog.csdn.net/qq_41359998/article/details/120482564

标签:Java,模拟,qq,界面
0
投稿

猜你喜欢

  • Java 8 lambda表达式引入详解及实例

    2022-10-25 22:41:37
  • Java(TM) Platform SE binary 打开jar文件的操作

    2021-10-02 00:08:12
  • IDEA快速搭建spring boot项目教程(Spring initializr)

    2023-08-17 21:11:16
  • 详解JAVA 线程-线程的状态有哪些?它是如何工作的?

    2023-11-27 03:33:09
  • Java设计模式之状态模式

    2022-05-08 07:24:25
  • Java分页工具类及其使用(示例分享)

    2021-12-13 10:25:12
  • 使用springboot aop来实现读写分离和事物配置

    2022-10-29 11:43:07
  • 分享两种实现Winform程序的多语言支持的多种解决方案

    2023-10-17 21:24:17
  • Java DWR内存泄漏问题解决方案

    2022-02-28 02:35:07
  • java使用集合实现通讯录功能

    2023-01-30 21:27:15
  • Java 中的 clone( ) 和 new哪个效率更高

    2023-11-09 05:27:44
  • java设计模式之浅谈适配器模式

    2023-11-19 14:46:26
  • 一文搞懂c# await,async执行流

    2023-07-14 01:22:35
  • Java设计模式之Strategy模式

    2023-11-21 03:58:22
  • IDEA(jetbrain通用)使用教程图解

    2023-04-15 04:05:49
  • 详解java并发之重入锁-ReentrantLock

    2021-08-03 03:58:08
  • Java聊天室之实现接收和发送Socket

    2021-06-24 23:30:39
  • Java自动添加重写的toString方法详解

    2021-11-05 14:29:13
  • Spring自动配置之condition条件判断上篇

    2022-07-01 17:34:51
  • 使用@pathvariable与@requestparam碰到的一些问题及解决

    2023-11-27 16:30:34
  • asp之家 软件编程 m.aspxhome.com