一、登陸界面的實作
登陸界面主要使用了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");
}
}
}
}
代碼改進了一下,還有UI的代碼再下發👇
??Java實作模擬QQ(改進版)??
之后會豐富更多功能 敬請期待!
感謝您的觀看!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/303309.html
標籤:java
上一篇:Redis為什么這么快?
