IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> ??Java实现模拟QQ(消息通信+登陆界面美化)?? -> 正文阅读

[Java知识库]??Java实现模拟QQ(消息通信+登陆界面美化)??

作者:token keyword

一、登陆界面的实现

登陆界面主要使用了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");

    }
}

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;
    static  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 static  void 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 {

    static  public JTextField jTextField;
    static  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 void MsgServerInit(){

    }
    public  static 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");
            }
        }
    }
}

之后会丰富更多功能 敬请期待!

感谢您的观看!!!

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-26 10:01:22  更:2021-09-26 10:02:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:20:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码