Java網絡編程:登錄界面 登錄驗證 以及登錄成功的好友界面


引言

   

這部分我們就開始設計這個山寨版的qq了,首先最開始的就是需要一個登錄界面,當輸入的用戶名密碼正確之后,就跳轉到登錄成功的界面,我們這里登錄成功之后設計的是顯示該用戶好友界面,這一串我認為是一個整體,所以就放在了一起來寫,可能會造成本文比較長。

 

首先我們來看一下登錄界面

 

登錄界面

   

我們設計的登錄界面如圖所示

   

   

分析界面

   

這個界面可以分為三個大的部分,北部的一張圖片,qq2003全新體驗Q人類,中部的QQ號碼,手機號碼和Email登錄部分,以及下面的三個按鈕,中間的QQ號碼Label,號碼輸入框,清除號碼按鈕,QQ密碼Label,密碼輸入框,忘記密碼Label,以及隱身登錄,記住密碼Checkbox,加上申請密碼保護按鈕,這九個可以用一個3×3的網絡布局來做

   

QQ號碼,手機號碼和Email登錄這三個可以切換的Label可以用JTabbedPane

   

界面編程

   

首先北部組件的那張圖片可以是一個JLabel,然后把圖片作為參數傳入即可

   

jLabel = new JLabel(new ImageIcon("image/tou.gif"));

   

然后將其加入到JFrame的北部

   

this.add(jLabel, "North");

   

然后南部組件的三個按鈕可以是將三個JButton放在一個JPanel

   

jPanel = new JPanel();

jPanelButton1 = new JButton(new ImageIcon("image/denglu.gif"));

jPanelButton1.addActionListener(this);

jPanelButton2 = new JButton(new ImageIcon("image/quxiao.gif"));

jPanelButton3 = new JButton(new ImageIcon("image/xiangdao.gif"));

jPanel.add(jPanelButton1);

jPanel.add(jPanelButton2);

jPanel.add(jPanelButton3);

this.add(jPanel, "South");

   

中部的組件比較復雜,主要要實現可以切換標簽頁

   

首先我們把3×3網格里的東西做出來

   

jPanel1 = new JPanel(new GridLayout(3, 3));

jPanel1_JLabel1 = new JLabel("QQ號碼", JLabel.CENTER);

jPanel1_JLabel2 = new JLabel("QQ密碼", JLabel.CENTER);

jPanel1_JLabel3 = new JLabel("忘記密碼");

jPanel1_JLabel4 = new JLabel("申請密碼保護");

jPanel1_JButton = new JButton(new ImageIcon("image/clear.gif"));

jPanel1_UserNameField = new JTextField();

jPanel1_PasswordField = new JPasswordField();

jPanel1_CheckBox1 = new JCheckBox("隱身登錄");

jPanel1_CheckBox2 = new JCheckBox("記住密碼");

jPanel1.add(jPanel1_JLabel1);

jPanel1.add(jPanel1_UserNameField);

jPanel1.add(jPanel1_JButton);

jPanel1.add(jPanel1_JLabel2);

jPanel1.add(jPanel1_PasswordField);

jPanel1.add(jPanel1_JLabel3);

jPanel1.add(jPanel1_CheckBox1);

jPanel1.add(jPanel1_CheckBox2);

jPanel1.add(jPanel1_JLabel4);

   

然后我們除了QQ號碼這個標簽頁已經做好了之外(jPanel1),我們把后面兩個標簽頁(手機號碼和Email相應的標簽頁也做好)

   

jPanel2 = new JPanel();

jPanel3 = new JPanel();

   

最后我們創建一個JTabbedPane把這三個JPanel放進去即可

   

jTabbedPane = new JTabbedPane();

jTabbedPane.add("QQ號碼", jPanel1);

jTabbedPane.add("手機號碼", jPanel2);

jTabbedPane.add("Email", jPanel3);

this.add(jTabbedPane, "Center");

   

至此登錄界面就做好了,接下來就是QQ好友界面

   

QQ好友界面

   

我們設計的QQ好友界面如下圖所示

   

   

分析界面

   

這個界面大概可以分為三個部分,最上面的我的好友,可以是一個Button,連着中間的好友列表,好友列表要實現向下拉的功能,可以用一個JScrollPane實現,最下面是兩個Button,可以放在一個2×1的網格布局里

   

//用於放我的好友這個界面的東西,布局為BorderLayout

friendPanel1=new JPanel(new BorderLayout());

//用於顯示好友列表

friendPanel2=new JPanel(new GridLayout(50, 1, 4, 4));

//用於放陌生人、黑名單按鈕

friendPanel3=new JPanel(new GridLayout(2,1));

   

//將我的好友按鈕放入friendPanel1

friendPanel_Button1=new JButton("我的好友");

friendPanel1.add(friendPanel_Button1,"North");

   

//將好友列表放入friendPanel1

//給好友列表初始化,用一個JLabel數組放好友列表,每一個好友是一個JLabel

JLabel[] friendsList;

friendsList=new JLabel[50];

for (int i = 0; i < friendsList.length; i++) {

friendsList[i]=new JLabel(i+1+"",new ImageIcon("image/mm.jpg"),JLabel.LEFT);

//將每個JLabel放入friendPanel2

friendPanel2.add(friendsList[i]);

}

//將friendPanel2放入JScrollPane

friendPanel_jScrollPane=new JScrollPane(friendPanel2);

//將好友列表也就是JScrollPane放入friendPanel1

friendPanel1.add(friendPanel_jScrollPane,"Center");

   

//將南部的兩個按鈕放入friendPanel1

friendPanel_Button2=new JButton("陌生人");

friendPanel_Button3=new JButton("黑名單");

friendPanel3.add(friendPanel_Button2);

friendPanel3.add(friendPanel_Button3);

friendPanel1.add(friendPanel3,"South");

   

陌生人界面

   

另外我們想實現的是當點擊陌生人按鈕時能切換到陌生人界面

   

   

如何才能實現呢,一個簡單的方式就是我們仿照好友界面也要定義這么多的組件

   

//用於放陌生人這個界面的東西,布局為BorderLayout

   

msrPanel1=new JPanel(new BorderLayout());

   

首先北部現在變為了兩個按鈕的網格部分的Panel

   

msrPanel3=new JPanel(new GridLayout(2,1));

   

//將這個Panel放入msrPanel1

msrPanel_Button1=new JButton("我的好友");

msrPanel_Button2=new JButton("陌生人");

msrPanel3.add(msrPanel_Button1);

msrPanel3.add(msrPanel_Button2);

msrPanel1.add(msrPanel3,"North");

   

中部依舊是一個JScrollPane用於顯示陌生人列表

   

msrPanel2=new JPanel(new GridLayout(20, 1, 4, 4));

JLabel[] msrList=new JLabel[20];

for (int i = 0; i < msrList.length; i++) {

msrList[i]=new JLabel(i+1+"",new ImageIcon("image/mm.jpg"),JLabel.LEFT);

msrPanel2.add(msrList[i]);

}

msrPanel_jScrollPane=new JScrollPane(msrPanel2);

msrPanel1.add(msrPanel_jScrollPane,"Center");

   

最后是南部的一個黑名單按鈕

   

msrPanel_Button3=new JButton("黑名單");

msrPanel1.add(msrPanel_Button3,"South");

   

到這里為止我們遇到了一個困難,就是如何在這兩個界面中來回切換呢

   

這里我們要將JFrame本身的布局設置為CardLayout

   

cl=new CardLayout();

this.setLayout(cl);

   

然后將我的好友,陌生人加入到這個卡片布局中

   

this.add(friendPanel1,"1");

this.add(msrPanel1,"2");

   

然后我們要在我的好友界面監聽陌生人這個按鈕,當按下的時候我們切換到陌生人界面

也要在陌生人界面中監聽我的好友這個按鈕,當按下時我們切換到我的好友界面

   

if (e.getSource()==friendPanel_Button2) {

cl.show(this.getContentPane(), "2");

}

if (e.getSource()==msrPanel_Button1) {

cl.show(this.getContentPane(), "1");

}

   

實現鼠標放在好友上面異色顯示

   

也是用到鼠標的監聽事件,Entered事件Exited事件

   

public void mouseEntered(MouseEvent e) {

// TODO Auto-generated method stub

JLabel jLabel=(JLabel) e.getSource();

jLabel.setForeground(Color.red);

}

public void mouseExited(MouseEvent e) {

// TODO Auto-generated method stub

JLabel jLabel=(JLabel) e.getSource();

jLabel.setForeground(Color.black);

}

   

登錄驗證

   

接下來我們要實現登錄界面輸入用戶名和密碼,通過驗證用戶名和密碼來達到用戶登錄驗證的功能,所以我們需要一個服務器端來做這件事情。

   

首先是服務器的界面,服務器端的界面設計如下,我們僅僅需要通過GUI開啟和關閉服務器即可

   

服務器界面

   

   

分析界面

   

界面的設計代碼也很簡單,就是用一個JPanel把兩個button給裝起來即可,然后再構造函數中去初始化這些組件

   

JPanel jPanel;

JButton jButton1, jButton2;

public MyServerFrame() {

jPanel = new JPanel();

jButton1 = new JButton("啟動服務器");

jButton1.addActionListener(this);

jButton2 = new JButton("關閉服務器");

jPanel.add(jButton1);

jPanel.add(jButton2);

this.add(jPanel);

this.setSize(300, 200);

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.setVisible(true);

}

   

服務器GUI中的button添加監聽事件

   

jButton1.addActionListener(this);

   

public void actionPerformed(ActionEvent e) {

if (e.getSource()==jButton1) {

new MyQQServer();

}

}

   

服務器的GUI設計好了,那么接下來我們真正的來編寫服務器端的代碼,客戶端要向服務器端發送用戶名和密碼信息,這里服務器和客戶端的通信通過對象流的方式傳遞對象信息,所以首先我們得有對象流傳送對象信息的先備知識,這里穿插一下這個知識的講解

   

對象流

   

服務器端接收

public class MyServer {

public MyServer()

{

System.out.println("3456端口監聽,,");

ServerSocket ss=new ServerSocket(3456);

Socket s=ss.accept();

//以對象流的形式讀取

ObjectInputStream ois=new ObjectInputStream(s.getInputStream());

User u=(User)ois.readObject();

//輸出

System.out.println(u.getName()+u.getPass());

}

}

客戶端發送

public class MyClient {

public MyClient()

{

Socket s=new Socket("127.0.0.1",3456);

//通過ObjectOutputStream給服務器傳送對象

ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());

User u=new User();

u.setName("桑陽");

u.setPass("123");

oos.writeObject(u);

}

}

其中User類我們在服務器和客戶端中都要建立,那么我們選擇建立在一個名叫common的包中,該類要實現序列化接口

   

User類

   

public class User implements java.io.Serializable{

private String name;

private String pass;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getPass() {

return pass;

}

public void setPass(String pass) {

this.pass = pass;

}

}

   

有了對象流的概念之后,我們就可以真正的來編寫用戶驗證的代碼了

   

登錄驗證

   

用戶驗證的邏輯就是在登錄界面點擊了登錄按鈕,要將用戶名框中的信息和密碼框中的信息組成一個User類,用對象流的方法傳遞到服務器端,進行驗證。所以首先需要響應按鈕的點擊事件

   

響應登錄點擊事件

   

響應登錄點擊事件的邏輯就是,點擊了登錄按鈕,會去新建一個QQClientUser類,該類中有一個驗證用戶的方法,而該方法實際上會去調用QQClientConServer類中的sendLoginInfoToServer

   

public class QqClientUser {

   

public boolean checkUser(User u)

{

return new QqClientConServer().sendLoginInfoToServer(u);

}

}

   

QQClientConServer中我們建立與服務器的連接,在我們把用戶對象發送到服務器之后,就開始等待服務器端發回來的結果,結果由信息類型表示,當信息類型為1的時候,表示驗證通過,這里我們需要定義一個信息類型類MessageType.class,由於這個也是客戶端和服務器端要公用的,所以也放在common包下,注意這個是個接口

   

public interface MessageType {

public String message_success="1";

public String message_failure="2";

public String message_common_message="3";

public String message_require_friendOnline="4";

public String message_return_friendOnline="5";

}

   

然后需要建立message類,用於創建服務器和客戶端之間傳送的對象

   

public class Message implements Serializable {

private String mesType;

private String sender;

private String getter;

private String content;

private String sentTime;

//一大堆setget方法

}

   

   

於是在服務端驗證,如果用戶密碼正確,就返回messageType1

   

if (user.getPasswdString().equals("123456")) {

message.setMesType("1");

oosStream.writeObject(message);

   

//單開一個線程,讓該線程與一個客戶端保持通信

ServerToClientThread serverToClientThread=new ServerToClientThread(socket);

ManageClientThread.addClientThread(user.getUserID(), serverToClientThread);

serverToClientThread.start();

//並通知所有的其他用戶

serverToClientThread.notifyOther(user.getUserID());

}else {

message.setMesType("2");

oosStream.writeObject(message);

socket.close();

}

   

   

public class QqClientConServer {

//發送第一次請求

public boolean sendLoginInfoToServer(Object o)

{

boolean b=false;

Socket s=new Socket("127.0.0.1", 9999);

ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());

oos.writeObject(o);

   

ObjectInputStream ois=new ObjectInputStream(s.getInputStream());

   

Message ms=(Message)ois.readObject();

if(ms.getMesType().equals("1"))

{

b=true;

}

return b;

}

}

   

public void actionPerformed(ActionEvent arg0) {

//如果用戶點擊登錄

if(arg0.getSource()==jp1_jb1)

{

QqClientUser qqClientUser=new QqClientUser();

User u=new User();

u.setUserId(jp2_jtf.getText().trim()); //trim是出去開始或結尾的空格

u.setPasswd(new String(jp2_jpf.getPassword()));

if(qqClientUser.checkUser(u))

{

new QqFriendList();

//關閉掉登錄界面

this.dispose();

}else{

JOptionPane.showMessageDialog(this, "用戶名密碼錯誤");

}

}

}

   

   

服務器端

   

public class MyQQServer {

public MyQQServer(){

ServerSocket ss=new ServerSocket(9999);

while (true) {

Socket socket=ss.accept();

//接收客戶端發來的信息

ObjectInputStream oiStream=new ObjectInputStream(socket.getInputStream());

User user=(User) oiStream.readObject();

System.out.println("接收到用戶名:"+user.getUserID()+"密碼:"+user.getPasswdString());

Message message=new Message();

ObjectOutputStream oosStream=new ObjectOutputStream(socket.getOutputStream());

if (user.getPasswdString().equals("123456")) {

message.setMesType("1");

oosStream.writeObject(message);

//單開一個線程,讓該線程與一個客戶端保持通信

ServerToClientThread serverToClientThread=new ServerToClientThread(socket);

ManageClientThread.addClientThread(user.getUserID(), serverToClientThread);

serverToClientThread.start();

//並通知所有的其他用戶

serverToClientThread.notifyOther(user.getUserID());

}else {

message.setMesType("2");

oosStream.writeObject(message);

socket.close();

}

System.out.println("服務器啟動完畢");

}

}

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM