Java模拟qq软件的详细过程

目录

  • 登陆界面的实现
    • 登陆界面代码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; }}

【Java模拟qq软件的详细过程】
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; }@Overridepublic 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 extendsThread{String name; public Client(String name) {this.name=name; }public static void main(String[] args) {String port="客户端"; Login login=new Login(); login.showUI(port); }@Overridepublic 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 extendsThread{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); }@Overridepublic 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; publicMsgListener(JTextPane jtp,OutputStream outputStream,String name){this.jtp=jtp; this.outputStream=outputStream; this.name=name; }@Overridepublic 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); }}

之后会丰富更多功能 敬请期待! 感谢您的观看!!!
到此这篇关于Java模拟qq软件的详细过程的文章就介绍到这了,更多相关Java 模拟 qq内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读