java語言實踐課內容:聊天室小程序或QQ
功能要求:
聊天室:使用圖形用戶界面,能實現一個聊天室中多人聊天,可以兩人私聊。
QQ:實現類似QQ登錄、聊天等功能。
注意:有一定等級。完全照搬別人的代碼,不超過70分。
提示:使用socket通信
前面是逐步講解,要是想看最終代碼,請直接找到該文章的最下面
//
準備工作
建立包,類,文件
插入圖片要創建一個文件夾,文件夾里保存的就是所需要的圖片啦,比如我創建的文件夾為image;
兩個設備上進行通信,要用到socket通信協議,即客戶端的內容先傳到服務器,在服務器上處理,傳回客戶端
image素材文件里存放的圖片
鏈接:https://pan.baidu.com/s/1zns86NC6Qm80xKZHMIRSbA
提取碼:3f6w
//
1.首先我們先建一個qq登陸界面
成品圖如下:
詳細代碼及注釋如下
package com
.qq
.client
.view
;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;public class QqClientlLogin extends JFrame
{ JLabel jup
; JPanel jmid
;JLabel jmid_num1
,jmid_key1
;JTextField jmid_num2
; JPasswordField jmid_key2
; JCheckBox jmid_rember
,jmid_automatic
; JPanel jdown
; JButton jdown_1
,jdown_2
; public QqClientlLogin() {jup
=new JLabel(new ImageIcon("image/up3.png"));jmid
=new JPanel(new GridLayout(3,3));Font font
= new Font("宋體", Font
.PLAIN
, 25); jmid_num1
=new JLabel("QQ號碼:",JLabel
.CENTER
); jmid_key1
=new JLabel("QQ密碼:",JLabel
.CENTER
);jmid_num1
.setFont(font
); jmid_key1
.setFont(font
); jmid_num2
= new JTextField() ; jmid_key2
=new JPasswordField();jmid_rember
=new JCheckBox("自動登錄");jmid_automatic
=new JCheckBox("記住密碼");jmid_rember
.setFont(font
); jmid_automatic
.setFont(font
); jmid_rember
.setForeground(Color
.blue
); jmid_automatic
.setForeground(Color
.blue
);jmid
.add(jmid_num1
);jmid
.add(jmid_num2
);jmid
.add(jmid_key1
);jmid
.add(jmid_key2
);jmid
.add(jmid_rember
);jmid
.add(jmid_automatic
);jdown
=new JPanel(new FlowLayout()); jdown_1
=new JButton(new ImageIcon("image/denglu.png"));jdown_2
=new JButton(new ImageIcon("image/tuichu.png"));jdown
.add(jdown_1
);jdown
.add(jdown_2
);setLocation(300,300); add(jup
,"North"); add(jmid
,"Center"); add(jdown
,"South"); setSize(700,540); setDefaultCloseOperation(JFrame
.EXIT_ON_CLOSE
); setVisible(true); }public static void main(String
[] args
){QqClientlLogin qqClientlLogin
=new QqClientlLogin();}
}
//
2.好友列表界面
成品圖如下:
要建立兩個卡片的轉換,即點擊卡片一的"黑名單"轉到第二個卡片界面,點擊第二個卡片的"我的好友",轉到第一個界面上
此時,就需要創建監聽器的類,用到ActionListener接口
除此之外,我還建立了鼠標監聽MouseListener接口,當鼠標停留在好友是,好友編號變紅,離開時變回黑色,雙擊好友時,可得到該好友的編號(并進入與該好友的聊天界面)
詳細代碼及注釋如下
package com
.qq
.client
.view
;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;public class QqFriendList extends JFrame implements ActionListener
,MouseListener
{ JPanel jup1
,jmid1
,jdown1
; JButton jup1_1
,jdown1_1
;JScrollPane jmid1_1
; JPanel jup2
,jup2_button
,jmid2
;JButton jup2_1
,jup2_2
;JScrollPane jmid2_1
; CardLayout cl
;public QqFriendList (){ Font font
= new Font("宋體", Font
.PLAIN
, 35);
jup1
=new JPanel(new BorderLayout()); jup1_1
=new JButton("我的好友");jup1_1
.setFont(font
); jmid1
=new JPanel(new GridLayout(50,1,4,4)); JLabel
[]jlist1
=new JLabel
[50]; for ( int i
=0; i
<jlist1
.length
; i
++ ){jlist1
[i
]=new JLabel(i
+1+" ",new ImageIcon("image/touxiang.png"),JLabel
.LEFT
);jlist1
[i
].addMouseListener(this);jmid1
.add(jlist1
[i
]); }jmid1_1
=new JScrollPane(jmid1
);jdown1_1
=new JButton("黑名單");jdown1_1
.addActionListener(this); jdown1_1
.setFont(font
); jdown1
=new JPanel(new GridLayout(1,1));jdown1
.add(jdown1_1
); jup1
.add(jup1_1
,"North");jup1
.add(jmid1_1
,"Center");jup1
.add(jdown1
,"South");jup2
=new JPanel(new BorderLayout()); jup2_1
=new JButton("我的好友");jup2_1
.addActionListener(this); jup2_2
=new JButton("黑名單");jup2_1
.setFont(font
); jup2_2
.setFont(font
);jup2_button
=new JPanel(new GridLayout(2,1));jup2_button
.add(jup2_1
);jup2_button
.add(jup2_2
);jmid2
=new JPanel(new GridLayout(20,1,4,4)); JLabel
[]jlist2
=new JLabel
[20]; for ( int i
=0; i
<jlist2
.length
; i
++ ){jlist2
[i
]=new JLabel(i
+1+" ",new ImageIcon("image/heitou.png"),JLabel
.LEFT
);jmid2
.add(jlist2
[i
]);}jmid2_1
=new JScrollPane(jmid2
);jup2
.add(jup2_button
,"North");jup2
.add(jmid2_1
);
cl
=new CardLayout();setLayout(cl
);add(jup1
,"1"); add(jup2
,"2"); setLocation(300,300); setSize(440,800);setVisible(true); }public static void main(String
[] args
) {QqFriendList qqFriendList
=new QqFriendList();}public void actionPerformed(ActionEvent arg0
){ if(arg0
.getSource()==jdown1_1
){cl
.show(this.getContentPane(), "2"); }elseif(arg0
.getSource()==jup2_1
){cl
.show(this.getContentPane(), "1");}}public void mouseEntered(MouseEvent arg0
) { JLabel jl
=(JLabel
)arg0
.getSource(); jl
.setForeground(Color
.red
); }public void mouseExited(MouseEvent arg0
) { JLabel jl
=(JLabel
)arg0
.getSource(); jl
.setForeground(Color
.black
);}public void mouseClicked(MouseEvent arg0
) { if(arg0
.getClickCount()==2) {String friendNum
=((JLabel
)arg0
.getSource()).getText();}}public void mousePressed(MouseEvent arg0
) { }public void mouseReleased(MouseEvent arg0
) { }}
3.聊天界面,用服務器判斷登錄qq,對象流
這部分的代碼成果圖:
注:正常是要有數據庫來存qq賬號密碼信息的,秉著由簡至難的原則,此處先不設計數據庫,直接用服務器判斷
有了上訴兩個界面的設置,相信設置聊天界面應該很好模擬退出
聊天界面初步成果:
package com
.qq
.client
.view
;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class QqChat extends JFrame
{Font font
= new Font("宋體", Font
.PLAIN
, 20); JTextArea jta
; JTextField jtf
; JButton jb
;JPanel jp
;String ownerId
;String friendId
;public QqChat(String owner
,String
friend){jta
=new JTextArea();jtf
=new JTextField(25); jb
=new JButton("發送");jb
.setFont(font
);jp
=new JPanel();jp
.add(jtf
);jp
.add(jb
); add(jta
,"Center");add(jp
,"South");setTitle(owner
+"正在和 "+friend+" 聊天"); setIconImage((new ImageIcon("image/qq.png").getImage())); setLocation(800,400); setSize(600, 500);setVisible(true);}public static void main(String
[] args
) {QqChat qqChat
=new QqChat("1"); }
思考一下,如果是要與其余好友聊天應該如何表示呢?
在 QqFriendList中,我們雙擊得到好友的編號,只需把編號傳到QqChat中即可
現在來實現登錄操作:當用戶點擊登錄后,把qq號碼和密碼發送給QqServer(服務器)去驗證,如果該用戶合法,返回true,否則返回false;
以對象流的方式讀取客戶端發來的賬號和密碼,在網絡間傳遞對象流,
避免直接讀入由特殊符號,空格,換行等干擾
對象流是一種高級流,可以方便我們將java中的任何對象進行讀寫操作。
java.io.objectoutputstream對象輸出流,可以將對象轉換為一組字節寫出。
java.io.objectinputstream對象輸入流,可以讀取一組字節轉換為原對象,
還原為原對象的條件是讀取這個字節應該是對象輸出流將一個對象轉換的字節。一個對象要想序列化,該類必須實現java.io.Serializable 接口
Serializable 是一個標記接口,不實現此接口的類將不會使任何狀態序列化或反序列化,會拋出NotSerializableException 。
使用ObjectOutputStream對象中的方法writeObject,把對象寫入到文件中
在這里,我們還要用到socket socket是兩臺主機之間的一個連接
網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。
建立網絡通信連接需要一對socket,兩個socket之間形成一個管道(通道),進行信息流的傳輸(聯想IO流中文件和程序之間讀寫)。
ServerSocket與Socket入門詳解
分別在Qqclient(客戶端)和QqServe(服務端)項目里建立com.qq.common包,包里存放Message.java和User.java兩個類
User類就是獲得用戶輸入的賬號和密碼
package com
.qq
.common
;public class User implements java
.io
.Serializable
{private String userId
;private String passwd
;public String
getUserId(){return userId
;}public void setUserId(String userId
) {this.userId
= userId
;}public String
getPasswd(){return passwd
;}public void setPasswd(String passwd
){this.passwd
=passwd
;}
}
對發送服務端的信息規定一些規則
mesType為true 表明登陸成功
mesType為false 表明登錄失敗
所以Message就是用來判斷的
package com
.qq
.common
;
public class Message implements java
.io
.Serializable
{ private String mesType
;public String
getMesType(){return mesType
;}public void setMesType(String mesType
){this.mesType
=mesType
;}
}
主要思想
要在第一部分qq登錄界面的代碼中加上監聽(登錄按鈕),將得到的賬戶和密碼信息逐步傳入到破服務器里面,再有服務器返回,判斷是否能登錄,如果能,打開好友列表界面,
否則,觸發提示框"用戶名或密碼錯誤".
客戶端
注意:我判斷的是如果密碼為"123456"即為正確
package com
.qq
.client
.view
;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.qq.client.model.*;
import com.qq.common.*;
public class QqClientlLogin extends JFrame implements ActionListener
{ JLabel jup
; JPanel jmid
;JLabel jmid_num1
,jmid_key1
;JTextField jmid_num2
; JPasswordField jmid_key2
; JCheckBox jmid_rember
,jmid_automatic
; JPanel jdown
; JButton jdown_1
,jdown_2
; public QqClientlLogin() {jup
=new JLabel(new ImageIcon("image/up3.png"));jmid
=new JPanel(new GridLayout(3,3));Font font
= new Font("宋體", Font
.PLAIN
, 25); jmid_num1
=new JLabel("QQ號碼:",JLabel
.CENTER
); jmid_key1
=new JLabel("QQ密碼:",JLabel
.CENTER
);jmid_num1
.setFont(font
); jmid_key1
.setFont(font
); jmid_num2
= new JTextField() ; jmid_key2
=new JPasswordField();jmid_rember
=new JCheckBox("自動登錄");jmid_automatic
=new JCheckBox("記住密碼");jmid_rember
.setFont(font
); jmid_automatic
.setFont(font
); jmid_rember
.setForeground(Color
.blue
); jmid_automatic
.setForeground(Color
.blue
);jmid
.add(jmid_num1
);jmid
.add(jmid_num2
);jmid
.add(jmid_key1
);jmid
.add(jmid_key2
);jmid
.add(jmid_rember
);jmid
.add(jmid_automatic
);jdown
=new JPanel(new FlowLayout()); jdown_1
=new JButton(new ImageIcon("image/denglu.png"));jdown_1
.addActionListener(this); jdown_2
=new JButton(new ImageIcon("image/tuichu.png"));jdown
.add(jdown_1
);jdown
.add(jdown_2
);setLocation(300,300); add(jup
,"North"); add(jmid
,"Center"); add(jdown
,"South"); setSize(700,540); setDefaultCloseOperation(JFrame
.EXIT_ON_CLOSE
); setVisible(true); }public static void main(String
[] args
){QqClientlLogin qqClientlLogin
=new QqClientlLogin();} public void actionPerformed(ActionEvent arg0
){if(arg0
.getSource()==jdown_1
); {User u
=new User();u
. setUserId(jmid_num2
.getText().trim()); u
. setPasswd(new String (jmid_key2
.getPassword())); QqClientUser qqclientuser
=new QqClientUser();if(qqclientuser
.checkUser(u
)){new QqFriendList(u
.getUserId()); this.dispose(); }else{JOptionPane
.showMessageDialog(this,"用戶名或密碼錯誤");}}}
}
package com
.qq
.client
.view
;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;public class QqFriendList extends JFrame implements ActionListener
,MouseListener
{ String owner
; JPanel jup1
,jmid1
,jdown1
; JButton jup1_1
,jdown1_1
;JScrollPane jmid1_1
; JPanel jup2
,jup2_button
,jmid2
;JButton jup2_1
,jup2_2
;JScrollPane jmid2_1
; CardLayout cl
;public QqFriendList (String ownerId
){ Font font
= new Font("宋體", Font
.PLAIN
, 35);
owner
=ownerId
;jup1
=new JPanel(new BorderLayout()); jup1_1
=new JButton("我的好友");jup1_1
.setFont(font
); jmid1
=new JPanel(new GridLayout(50,1,4,4)); JLabel
[]jlist1
=new JLabel
[50]; for ( int i
=0; i
<jlist1
.length
; i
++ ){jlist1
[i
]=new JLabel(i
+1+"",new ImageIcon("image/touxiang.png"),JLabel
.LEFT
);jlist1
[i
].addMouseListener(this);jmid1
.add(jlist1
[i
]); }jmid1_1
=new JScrollPane(jmid1
);jdown1_1
=new JButton("黑名單");jdown1_1
.addActionListener(this); jdown1_1
.setFont(font
); jdown1
=new JPanel(new GridLayout(1,1));jdown1
.add(jdown1_1
); jup1
.add(jup1_1
,"North");jup1
.add(jmid1_1
,"Center");jup1
.add(jdown1
,"South");jup2
=new JPanel(new BorderLayout()); jup2_1
=new JButton("我的好友");jup2_1
.addActionListener(this); jup2_2
=new JButton("黑名單");jup2_1
.setFont(font
); jup2_2
.setFont(font
);jup2_button
=new JPanel(new GridLayout(2,1));jup2_button
.add(jup2_1
);jup2_button
.add(jup2_2
);jmid2
=new JPanel(new GridLayout(20,1,4,4)); JLabel
[]jlist2
=new JLabel
[20]; for ( int i
=0; i
<jlist2
.length
; i
++ ){jlist2
[i
]=new JLabel(i
+1+" ",new ImageIcon("image/heitou.png"),JLabel
.LEFT
);jmid2
.add(jlist2
[i
]);}jmid2_1
=new JScrollPane(jmid2
);jup2
.add(jup2_button
,"North");jup2
.add(jmid2_1
);
cl
=new CardLayout();setLayout(cl
);add(jup1
,"1"); add(jup2
,"2"); setTitle(ownerId
);setLocation(300,300); setSize(440,800);setVisible(true); }public static void main(String
[] args
) {QqFriendList qqFriendList
=new QqFriendList();}public void actionPerformed(ActionEvent arg0
){ if(arg0
.getSource()==jdown1_1
){cl
.show(this.getContentPane(), "2"); }elseif(arg0
.getSource()==jup2_1
){cl
.show(this.getContentPane(), "1");}}public void mouseEntered(MouseEvent arg0
) { JLabel jl
=(JLabel
)arg0
.getSource(); jl
.setForeground(Color
.red
); }public void mouseExited(MouseEvent arg0
) { JLabel jl
=(JLabel
)arg0
.getSource(); jl
.setForeground(Color
.black
);}public void mouseClicked(MouseEvent arg0
) { if(arg0
.getClickCount()==2) {String friendNum
=((JLabel
)arg0
.getSource()).getText();new QqChat(owner
,friendNum
); }}public void mousePressed(MouseEvent arg0
) { }public void mouseReleased(MouseEvent arg0
) { }
}
package com
.qq
.client
.model
;
import com.qq.common.*;
public class QqClientUser {public boolean
checkUser(User u
){return new QqClientConServer().sendLoginInfotoSSErver(u
);}
}
package com
.qq
.client
.model
;import java.util.*;
import java.net.*;
import java.io.*;
import com.qq.common.*;
public class QqClientConServer{public boolean
sendLoginInfotoSSErver(Object o
) { boolean b
=false;try{ 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;}catch (Exception e
){e
.printStackTrace();}finally
{}return b
;}
}
服務端
除了需要的Message.java和User.java兩個類還需要
package com
.qq
.server
.view
;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.qq.server.model.MyQqServer;
public class ControlPanel extends JFrame implements ActionListener
{JPanel jp1
;JButton jstart
,jend
;public ControlPanel(){ Font font
= new Font("宋體",Font
.PLAIN
,30);jp1
=new JPanel();jstart
=new JButton("啟動服務器");jstart
.addActionListener(this);jend
=new JButton("關閉服務器");jstart
.setFont(font
); jend
.setFont(font
);jstart
.setForeground(Color
.BLUE
); jend
.setForeground(Color
.BLUE
);jp1
.add(jstart
);jp1
.add(jend
);add(jp1
);setLocation(150,150);setSize(900,900);setDefaultCloseOperation(JFrame
.EXIT_ON_CLOSE
); setVisible(true);}public static void main(String
[] args
) {ControlPanel controlpanel
=new ControlPanel();}public void actionPerformed(ActionEvent arg0
){if(arg0
.getSource()==jstart
){new MyQqServer();}}
}
package com
.qq
.server
.model
;import java.io.*;
import java.net.*;
import java.util.*;
import com.qq.common.*;public class MyQqServer {public MyQqServer (){try{ System
.out
.println("服務器正在9999監聽");ServerSocket ss
=new ServerSocket(9999);while(true) {Socket s
=ss
.accept() ; ObjectInputStream ois
=new ObjectInputStream(s
.getInputStream());User u
=(User
)ois
.readObject();System
.out
.println("用戶Id:"+u
.getUserId()+" 密碼"+u
.getPasswd()); Message m
=new Message();ObjectOutputStream oos
=new ObjectOutputStream(s
.getOutputStream());if(u
.getPasswd().equals("123456")){m
.setMesType("1"); oos
.writeObject(m
); }else{m
.setMesType("2"); oos
.writeObject(m
); s
.close(); }}}catch(Exception e
){e
.printStackTrace();}finally
{}}
}
4.一對一的聊天
進程概念:進程是代碼在數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位。
線程概念:線程是進程的一個執行路徑,一個進程中至少有一個線程,進程中的多個線程共享進程的資源。
此處要用線程用來接收客戶端的消息,因為不僅僅一個用戶(可實現多用戶登錄)
要在message類里面加入,用戶編號,接受方,發送信息(即獲得聊天界面文本框的內容)等
在chat類里面,加入讀取,文本域中顯示聊天代碼等內容
在管理客戶端線程中使用HashMap<關鍵字,值>記錄發送者與服務器的socket,關鍵字記錄用戶編號,值記錄socket
每個包(類)或多或少都有所更改,完整代碼如下,希望對大家有所幫助,同時請大佬指正錯誤%%%
//
客戶端代碼
package com
.qq
.common
;public class Message implements java
.io
.Serializable
{ private String mesType
;private String sender
;private String getter
; private String con
; public String
getSender(){return sender
;}public void setSender(String sender
){this.sender
=sender
;}public String
getGetter(){return getter
;}public void setGetter(String getter
){this.getter
=getter
;}public String
getCon(){return con
;}public void setCon(String con
){this.con
=con
;}public String
getMesType(){return mesType
;}public void setMesType(String mesType
){this.mesType
=mesType
;}
}
package com
.qq
.common
;public class User implements java
.io
.Serializable
{private String userId
;private String passwd
;public String
getUserId(){return userId
;}public void setUserId(String userId
) {this.userId
= userId
;}public String
getPasswd(){return passwd
;}public void setPasswd(String passwd
){this.passwd
=passwd
;}}
package com
.qq
.client
.view
;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.qq.client.model.*;
import com.qq.common.*;
public class QqClientlLogin extends JFrame implements ActionListener
{ JLabel jup
; JPanel jmid
;JLabel jmid_num1
,jmid_key1
;JTextField jmid_num2
; JPasswordField jmid_key2
; JCheckBox jmid_rember
,jmid_automatic
; JPanel jdown
; JButton jdown_1
,jdown_2
; public QqClientlLogin() {jup
=new JLabel(new ImageIcon("image/up3.png"));jmid
=new JPanel(new GridLayout(3,3));Font font
= new Font("宋體", Font
.PLAIN
, 25); jmid_num1
=new JLabel("QQ號碼:",JLabel
.CENTER
); jmid_key1
=new JLabel("QQ密碼:",JLabel
.CENTER
);jmid_num1
.setFont(font
); jmid_key1
.setFont(font
); jmid_num2
= new JTextField() ; jmid_key2
=new JPasswordField();jmid_rember
=new JCheckBox("自動登錄");jmid_automatic
=new JCheckBox("記住密碼");jmid_rember
.setFont(font
); jmid_automatic
.setFont(font
); jmid_rember
.setForeground(Color
.blue
); jmid_automatic
.setForeground(Color
.blue
);jmid
.add(jmid_num1
);jmid
.add(jmid_num2
);jmid
.add(jmid_key1
);jmid
.add(jmid_key2
);jmid
.add(jmid_rember
);jmid
.add(jmid_automatic
);jdown
=new JPanel(new FlowLayout()); jdown_1
=new JButton(new ImageIcon("image/denglu.png"));jdown_1
.addActionListener(this); jdown_2
=new JButton(new ImageIcon("image/tuichu.png"));jdown
.add(jdown_1
);jdown
.add(jdown_2
);setLocation(300,300); add(jup
,"North"); add(jmid
,"Center"); add(jdown
,"South"); setSize(700,540); setDefaultCloseOperation(JFrame
.EXIT_ON_CLOSE
); setVisible(true); }public static void main(String
[] args
){QqClientlLogin qqClientlLogin
=new QqClientlLogin();} public void actionPerformed(ActionEvent arg0
){if(arg0
.getSource()==jdown_1
); {User u
=new User();u
. setUserId(jmid_num2
.getText().trim()); u
. setPasswd(new String (jmid_key2
.getPassword())); QqClientUser qqclientuser
=new QqClientUser();if(qqclientuser
.checkUser(u
)){QqFriendList qqList
=new QqFriendList(u
.getUserId()); this.dispose(); }else{JOptionPane
.showMessageDialog(this,"用戶名或密碼錯誤");}}}
}
package com
.qq
.client
.view
;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;public class QqFriendList extends JFrame implements ActionListener
,MouseListener
{ String owner
; JPanel jup1
,jmid1
,jdown1
; JButton jup1_1
,jdown1_1
;JScrollPane jmid1_1
; JPanel jup2
,jup2_button
,jmid2
;JButton jup2_1
,jup2_2
;JScrollPane jmid2_1
; CardLayout cl
;public QqFriendList (String ownerId
){ Font font
= new Font("宋體", Font
.PLAIN
, 35);
owner
=ownerId
;jup1
=new JPanel(new BorderLayout()); jup1_1
=new JButton("我的好友");jup1_1
.setFont(font
); jmid1
=new JPanel(new GridLayout(50,1,4,4)); JLabel
[]jlist1
=new JLabel
[50]; for ( int i
=0; i
<jlist1
.length
; i
++ ){jlist1
[i
]=new JLabel(i
+1+" ",new ImageIcon("image/touxiang.png"),JLabel
.LEFT
);jlist1
[i
].addMouseListener(this);jmid1
.add(jlist1
[i
]); }jmid1_1
=new JScrollPane(jmid1
);jdown1_1
=new JButton("黑名單");jdown1_1
.addActionListener(this); jdown1_1
.setFont(font
); jdown1
=new JPanel(new GridLayout(1,1));jdown1
.add(jdown1_1
); jup1
.add(jup1_1
,"North");jup1
.add(jmid1_1
,"Center");jup1
.add(jdown1
,"South");jup2
=new JPanel(new BorderLayout()); jup2_1
=new JButton("我的好友");jup2_1
.addActionListener(this); jup2_2
=new JButton("黑名單");jup2_1
.setFont(font
); jup2_2
.setFont(font
);jup2_button
=new JPanel(new GridLayout(2,1));jup2_button
.add(jup2_1
);jup2_button
.add(jup2_2
);jmid2
=new JPanel(new GridLayout(20,1,4,4)); JLabel
[]jlist2
=new JLabel
[20]; for ( int i
=0; i
<jlist2
.length
; i
++ ){jlist2
[i
]=new JLabel(i
+1+" ",new ImageIcon("image/heitou.png"),JLabel
.LEFT
);jmid2
.add(jlist2
[i
]);}jmid2_1
=new JScrollPane(jmid2
);jup2
.add(jup2_button
,"North");jup2
.add(jmid2_1
);
cl
=new CardLayout();setLayout(cl
);add(jup1
,"1"); add(jup2
,"2"); setTitle(ownerId
);setLocation(300,300); setSize(440,800);setVisible(true); }public static void main(String
[] args
) {} public void actionPerformed(ActionEvent arg0
){ if(arg0
.getSource()==jdown1_1
){cl
.show(this.getContentPane(), "2"); }elseif(arg0
.getSource()==jup2_1
){cl
.show(this.getContentPane(), "1");}}public void mouseEntered(MouseEvent arg0
) { JLabel jl
=(JLabel
)arg0
.getSource(); jl
.setForeground(Color
.red
); }public void mouseExited(MouseEvent arg0
) { JLabel jl
=(JLabel
)arg0
.getSource(); jl
.setForeground(Color
.black
);}public void mouseClicked(MouseEvent arg0
) { if(arg0
.getClickCount()==2) {String friendNum
=((JLabel
)arg0
.getSource()).getText();QqChat qqChat
=new QqChat(owner
,friendNum
); Thread t
=new Thread(qqChat
); t
.start(); }}public void mousePressed(MouseEvent arg0
) { }public void mouseReleased(MouseEvent arg0
) { }
}
package com
.qq
.client
.view
;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import com.qq.common.*;
import com.qq.client.model.*;
public class QqChat extends JFrame implements ActionListener
,Runnable
{ Font font
= new Font("宋體", Font
.PLAIN
, 20); JTextArea jta
; JTextField jtf
; JButton jb
;JPanel jp
;String ownerId
;String friendId
;public QqChat(String owner
,String
friend){ ownerId
= owner
;friendId
=friend;jta
=new JTextArea();jtf
=new JTextField(25); jb
=new JButton("發送");jb
.addActionListener(this);jb
.setFont(font
);jp
=new JPanel();jp
.add(jtf
);jp
.add(jb
); add(jta
,"Center");add(jp
,"South");setTitle(owner
+"正在和 "+friend+" 聊天"); setIconImage((new ImageIcon("image/qq.png").getImage())); setLocation(800,400); setSize(600, 500);setVisible(true);}public void showMessage(Message m
){String info
=m
.getSender()+" 給"+m
.getGetter()+" 發送:"+m
.getCon()+"\r\n";this.jta
.append(info
);}public void actionPerformed(ActionEvent arg0
) {if(arg0
.getSource()==jb
){Message m
=new Message();m
.setSender(this.ownerId
);m
.setGetter(this.friendId
);m
.setCon(jtf
.getText()); try { ObjectOutputStream oos
=new ObjectOutputStream(QqClientConServer
.s
.getOutputStream());oos
.writeObject(m
);} catch (Exception e
) {e
.printStackTrace();} } }public void run(){while(true){ try{ObjectInputStream ois
=new ObjectInputStream(QqClientConServer
.s
.getInputStream());Message m
=(Message
)ois
.readObject(); String info
=m
.getSender()+"給"+m
.getGetter()+"發送"+m
.getCon()+"\r\n";this.jta
.append(info
); }catch(Exception e
){e
.printStackTrace();}}}
}
package com
.qq
.client
.model
;
import com.qq.common.*;
public class QqClientUser {public boolean
checkUser(User u
){return new QqClientConServer().sendLoginInfotoSSErver(u
);}
}
package com
.qq
.client
.model
;import java.util.*;
import java.net.*;
import java.io.*;
import com.qq.common.*;
public class QqClientConServer{public static Socket s
;public boolean
sendLoginInfotoSSErver(Object o
) { boolean b
=false;try{ 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;}catch (Exception e
){e
.printStackTrace();}finally
{}return b
;}
}
服務端代碼(message,user與客戶端一樣,這里不在寫出,直接復制過去就可以)
package com
.qq
.server
.view
;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.qq.server.model.MyQqServer;
public class ControlPanel extends JFrame implements ActionListener
{JPanel jp1
;JButton jstart
,jend
;public ControlPanel(){ Font font
= new Font("宋體",Font
.PLAIN
,30);jp1
=new JPanel();jstart
=new JButton("啟動服務器");jstart
.addActionListener(this);jend
=new JButton("關閉服務器");jstart
.setFont(font
); jend
.setFont(font
);jstart
.setForeground(Color
.BLUE
); jend
.setForeground(Color
.BLUE
);jp1
.add(jstart
);jp1
.add(jend
);add(jp1
);setLocation(150,150);setSize(900,900);setDefaultCloseOperation(JFrame
.EXIT_ON_CLOSE
); setVisible(true);}public static void main(String
[] args
) {ControlPanel controlpanel
=new ControlPanel();}public void actionPerformed(ActionEvent arg0
){if(arg0
.getSource()==jstart
){new MyQqServer();}}
}
package com
.qq
.server
.model
;import java.io.*;
import java.net.*;
import java.util.*;
import com.qq.common.*;public class MyQqServer {public MyQqServer (){try{ System
.out
.println("服務器正在9999監聽");ServerSocket ss
=new ServerSocket(9999);while(true) {Socket s
=ss
.accept() ; ObjectInputStream ois
=new ObjectInputStream(s
.getInputStream());User u
=(User
)ois
.readObject();System
.out
.println("用戶Id:"+u
.getUserId()+" 密碼"+u
.getPasswd()); Message m
=new Message();ObjectOutputStream oos
=new ObjectOutputStream(s
.getOutputStream());if(u
.getPasswd().equals("123456")){m
.setMesType("1"); oos
.writeObject(m
); SerConClientThread scct
=new SerConClientThread(s
);ManageClientThread
.addClientThread(u
.getUserId(),scct
);scct
.start(); }else{m
.setMesType("2"); oos
.writeObject(m
); s
.close(); }}}catch(Exception e
){e
.printStackTrace();}finally
{}}
}
package com
.qq
.server
.model
;import java.net.*;
import java.io.*;
import com.qq.common.*;
public class SerConClientThread extends Thread
{ Socket s
;public SerConClientThread(Socket s
){this.s
=s
; }public void run(){while(true){try{ObjectInputStream ois
=new ObjectInputStream(s
.getInputStream());Message m
=(Message
)ois
.readObject();System
.out
.println(m
.getSender()+"給 "+m
.getGetter()+"發送: "+m
.getCon());SerConClientThread sc
=ManageClientThread
.getClientThread(m
.getGetter());ObjectOutputStream oos
=new ObjectOutputStream(sc
.s
.getOutputStream()); oos
.writeObject(m
);}catch(Exception e
){e
.printStackTrace();}}}
}
package com
.qq
.server
.model
;import java.util.*;public class ManageClientThread { public static HashMap hm
=new HashMap<String, SerConClientThread>();public static void addClientThread(String uid
,SerConClientThread ct
){hm
.put(uid
, ct
);}public static SerConClientThread
getClientThread(String uid
){return (SerConClientThread
) hm
.get(uid
);}}
總結
以上是生活随笔為你收集整理的java实现qq聊天(超详细)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。