欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java模擬qq軟件的詳細(xì)過(guò)程

 更新時(shí)間:2021年09月28日 15:19:01   作者:冷丁_  
這篇文章主要為大家詳細(xì)介紹了用Java實(shí)現(xiàn)模擬QQ,實(shí)現(xiàn)了消息通信+登陸界面美化,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

**之前在封裝代碼后出現(xiàn)了問(wèn)題,按照最初的寫法,在登陸完畢后彈出聊天界面后會(huì)卡死,原因是當(dāng)時(shí)登陸界面和聊天界面都是使用的主線程,我的代碼沒(méi)有寫其他線程,無(wú)法多線程運(yùn)行,因此在彈出聊天界面時(shí)線程不夠用了,就卡在了監(jiān)聽(tīng)線程里,因?yàn)樵诒O(jiān)聽(tīng)線程中再有新的監(jiān)聽(tīng)就會(huì)被卡住
在宇哥的指點(diǎn)下,將啟動(dòng)服務(wù)器和客戶端的部分改為線程,就解決了此問(wèn)題。改善后的代碼簡(jiǎn)練和清晰了很多,更方便大家參考,代碼如下:
**

登陸界面的實(shí)現(xiàn)

登陸界面主要使用了JFrame,以及相關(guān)的一些組件,并且在界面中加上監(jiān)聽(tīng)
登陸界面效果圖

在這里插入圖片描述

登陸界面代碼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);//標(biāo)簽大小
        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的監(jiān)聽(tīng)類 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 ("服務(wù)端登錄??!");
            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();
        }


    }
}

在登陸完畢后,需要跳轉(zhuǎn)到聊天界面,這里采用的方法是通過(guò)一個(gè)flag標(biāo)志來(lái)判斷是否登陸完畢,當(dāng)?shù)顷懲戤吅?,?huì)創(chuàng)建新的聊天界面,并且登陸頁(yè)面會(huì)被關(guān)閉
依然是雙端通信,假定一端為客戶端,一端為服務(wù)端,其實(shí)兩端都可為用戶。

聊天界面運(yùn)行圖

先登陸Alice的賬號(hào) 密碼為123456

在這里插入圖片描述

登陸成功后顯示ok,并等待連接

在這里插入圖片描述

再登陸冷丁的賬號(hào),密碼為123456

在這里插入圖片描述

當(dāng)lding賬號(hào)登陸成功后完成連接,這時(shí)候會(huì)彈出兩個(gè)新的JFram窗口,為聊天見(jiàn)面

在這里插入圖片描述

隨后可以發(fā)送消息,消息可以實(shí)時(shí)顯示時(shí)間,并顯示用戶名
一方發(fā)送的消息會(huì)在另一方的窗口上實(shí)時(shí)顯示出來(lái)

在這里插入圖片描述

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);
        //輸入 輸出流對(duì)象
        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("消息長(zhǎng)度:"+msglenth);
            byte[] msgbytes=new byte[msglenth];
            //將接下來(lái)的數(shù)據(jù)讀入字節(jié)數(shù)組中
            inputStream.read(msgbytes);

            count++;
            if(count%2==0){
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設(shè)置日期格式
                String date = df.format(new Date());// new Date()為獲取當(dāng)前系統(tǒng)時(shí)間,也可使用當(dāng)前時(shí)間戳
                String getmsg=new String(msgbytes);
                String msg=showmsgpane.getText();
                showmsgpane.setText(msg+date+"  ["+getmsg+"]"+"說(shuō):"+"\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="服務(wù)端";
        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();//監(jiān)聽(tīng)連接
        System.out.println("連接成功?。?);
        InputStream inputStream=clientsocket.getInputStream();
        OutputStream outputStream=clientsocket.getOutputStream();

        MsgUI msgUI=new MsgUI(outputStream,name);
        JTextPane showmsgpane=msgUI.initUI("服務(wù)端");
        //outputStream.flush();
        int count=1;
        while(true){
            int msglenth=inputStream.read();
            System.out.println("消息長(zhǎng)度是:"+msglenth);
            byte[] msgbytes=new byte[msglenth];
            //將接下來(lái)的數(shù)據(jù)讀入字節(jié)數(shù)組中
            inputStream.read(msgbytes);
            count++;
            if(count%2==0){
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設(shè)置日期格式
                String date = df.format(new Date());// new Date()為獲取當(dāng)前系統(tǒng)時(shí)間,也可使用當(dāng)前時(shí)間戳
                String getmsg=new String(msgbytes);
                String msg=showmsgpane.getText();
                showmsgpane.setText(msg+date+"  ["+getmsg+"]"+"說(shuō):"+"\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);//按鈕大小



        //發(fā)送框
        JTextPane jtp1=new JTextPane();
        jtp1.setPreferredSize(new Dimension(750,200));
        JScrollPane jsp1=new JScrollPane(jtp1);

        JButton btn=new JButton("發(fā)送");
        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);
    }
}


之后會(huì)豐富更多功能 敬請(qǐng)期待! 感謝您的觀看?。?!

到此這篇關(guān)于Java模擬qq軟件的詳細(xì)過(guò)程的文章就介紹到這了,更多相關(guān)Java 模擬 qq內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

  • SpringBoot中接收POST參數(shù)的幾種方式詳解

    SpringBoot中接收POST參數(shù)的幾種方式詳解

    這篇文章主要介紹了SpringBoot中接收POST參數(shù)的幾種方式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • Java集合中的Iterator迭代器接口詳解

    Java集合中的Iterator迭代器接口詳解

    這篇文章主要介紹了Java集合中的Iterator迭代器接口詳解,Iterator,被稱為迭代器接口,本身并不提供存儲(chǔ)對(duì)象的能力,主要用于遍歷Collection中的元素,需要的朋友可以參考下
    2023-11-11
  • SpringBoot時(shí)間格式化的方法小結(jié)

    SpringBoot時(shí)間格式化的方法小結(jié)

    SpringBoot中的時(shí)間格式化通常指的是將Java中的日期時(shí)間類型轉(zhuǎn)換為指定格式的字符串,或者將字符串類型的時(shí)間解析為Java中的日期時(shí)間類型,本文小編將給大家詳細(xì)總結(jié)了SpringBoot時(shí)間格式化的方法,剛興趣的小伙伴跟著小編一起來(lái)看看吧
    2023-10-10
  • 解決mybatis plus字段為null或空字符串無(wú)法保存到數(shù)據(jù)庫(kù)的問(wèn)題

    解決mybatis plus字段為null或空字符串無(wú)法保存到數(shù)據(jù)庫(kù)的問(wèn)題

    這篇文章主要介紹了解決mybatis plus字段為null或空字符串無(wú)法保存到數(shù)據(jù)庫(kù)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • 如何解決@PutMapping或@PostMapping接收String類型參數(shù)多兩個(gè)“引號(hào)問(wèn)題

    如何解決@PutMapping或@PostMapping接收String類型參數(shù)多兩個(gè)“引號(hào)問(wèn)題

    這篇文章主要介紹了如何解決@PutMapping或@PostMapping接收String類型參數(shù)多兩個(gè)“引號(hào)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • java 四舍五入保留小數(shù)的實(shí)現(xiàn)方法

    java 四舍五入保留小數(shù)的實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇java 四舍五入保留小數(shù)的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-09-09
  • 簡(jiǎn)單聊聊Java中驗(yàn)證碼功能的實(shí)現(xiàn)

    簡(jiǎn)單聊聊Java中驗(yàn)證碼功能的實(shí)現(xiàn)

    相信大家都經(jīng)常接觸到驗(yàn)證碼的,畢竟平時(shí)上網(wǎng)也能遇到各種驗(yàn)證碼,需要我們輸入驗(yàn)證碼進(jìn)行驗(yàn)證我們是人類,本篇文章就從這幾個(gè)方面出發(fā)說(shuō)說(shuō)驗(yàn)證碼,廢話不多說(shuō),下面開(kāi)始正文
    2023-06-06
  • java調(diào)用opencv身份證號(hào)識(shí)別詳解

    java調(diào)用opencv身份證號(hào)識(shí)別詳解

    這篇文章主要為大家詳細(xì)介紹了java如何調(diào)用opencv實(shí)現(xiàn)身份證號(hào)的識(shí)別,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • Java中ThreadLocal的用法及原理詳解

    Java中ThreadLocal的用法及原理詳解

    這篇文章主要介紹了Java中ThreadLocal的用法及原理詳解,在并發(fā)編程中,如果一個(gè)類變量被多個(gè)線程操作,會(huì)造成線程安全問(wèn)題,使用ThreadLocal可以讓每個(gè)線程擁有線程內(nèi)部的變量,防止多個(gè)線程操作一個(gè)類變量造成的線程安全問(wèn)題,需要的朋友可以參考下
    2023-09-09
  • 最新評(píng)論