日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

JavaGUI--模拟QQ聊天界面私聊群聊

發(fā)布時間:2023/12/16 java 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaGUI--模拟QQ聊天界面私聊群聊 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

點擊下載源代碼

目錄

JFrame類的幾個重要方法

持久層

服務(wù)端創(chuàng)建

用戶注冊模塊

用戶登錄窗口

好友列表和群聊列表模塊

用戶私聊邏輯

群聊創(chuàng)建

群聊消息


JFrame類的幾個重要方法

  • Frame類的構(gòu)造方法,設(shè)置所畫出的窗口的名稱:public JFrame(String title)
  • 設(shè)置該窗口下的所有窗體(panel):public void setContentPane(Container contentPane)
  • 設(shè)置窗口關(guān)閉之后的狀態(tài):public void setDefaultCloseOperation(int operation)
  • 設(shè)置窗口顯示位置(傳入為null時則默認(rèn)顯示在屏幕正中央):public void setLocationRelativeTo(Component c)
  • 根據(jù)布局來確定窗口的最佳大小 public void pack()
  • 設(shè)置頁面是否顯示(默認(rèn)不顯示):public void setVisible(boolean b)

持久層

  • 創(chuàng)建User對象
  • 創(chuàng)建持久層層基礎(chǔ)類,封裝數(shù)據(jù)源,獲取連接,關(guān)閉資源等操作
  • 創(chuàng)建用戶持久層模塊

用戶對象和數(shù)據(jù)庫對應(yīng)

package com.lin.client.entity;import java.util.Set;/*** Description:* Author: llf* Created in 2019/8/23 16:30*/ public class User {private Integer id;private String userName;private String password;private String brief;private Set<String> userNames;public User() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getBrief() {return brief;}public void setBrief(String brief) {this.brief = brief;}public Set<String> getUserNames() {return userNames;}public void setUserNames(Set<String> userNames) {this.userNames = userNames;} }

dao層基類

package com.lin.client.dao;import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; import com.alibaba.druid.pool.DruidPooledConnection; import com.lin.client.entity.User; import com.lin.util.CommUtils;import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties;/*** Description:dao層基礎(chǔ)類i,封裝數(shù)據(jù)源,獲取連接,關(guān)閉資源等操作* Author: llf* Created in 2019/8/23 16:30*/ public class BasedDao {//獲取數(shù)據(jù)源private static DruidDataSource dataSource;static{Properties properties= CommUtils.loadProperties("db.properties");try {dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {System.out.println("獲取數(shù)據(jù)源失敗");e.printStackTrace();}}//獲取連接protected DruidPooledConnection getConnection() {try {return (DruidPooledConnection) dataSource.getPooledConnection();} catch (SQLException e) {System.out.println("數(shù)據(jù)庫連接失敗");e.printStackTrace();}return null;}//關(guān)閉資源protected void closeResources(Connection connection,Statement statement) {try {if (connection != null) connection.close();if (statement != null) statement.close();} catch (SQLException e) {e.printStackTrace();}}protected void closeResources(Connection connection,Statement statement,ResultSet resultSet) {closeResources(connection,statement);if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}}}

用戶查詢和插入DAO模塊

package com.lin.client.dao;import com.alibaba.druid.pool.DruidPooledConnection; import com.lin.client.entity.User; import org.apache.commons.codec.digest.DigestUtils;import java.sql.*;/*** Description:* Author: llf* Created in 2019/8/23 16:30*/ public class AccountDao extends BasedDao{public User userLogin(String userName, String password) {Connection connection=null;PreparedStatement statement=null;ResultSet resultSet=null;try{connection=getConnection();String sql="select * from user where username=? and password=?";statement = connection.prepareStatement(sql);statement.setString(1,userName);//******解密 ********************statement.setString(2, DigestUtils.md5Hex(password));resultSet=statement.executeQuery();if (resultSet.next()) {User user=getUser(resultSet);return user;}}catch (SQLException e) {System.out.println("用戶登陸失敗");e.printStackTrace();}finally {closeResources(connection,statement,resultSet);}return null;}private User getUser(ResultSet resultSet) throws SQLException {User user=new User();user.setId(resultSet.getInt("id"));user.setUserName(resultSet.getString("username"));user.setPassword(resultSet.getString("password"));user.setBrief(resultSet.getString("brief"));return user;}public boolean userReg(User user) {Connection connection=null;PreparedStatement statement=null;try{connection = getConnection();String str="insert into user(username,password,brief) values (?,?,?)";//接收執(zhí)行sql語句影響的行數(shù),statement=connection.prepareStatement(str, Statement.RETURN_GENERATED_KEYS);statement.setString(1,user.getUserName());//加密 *************statement.setString(2,DigestUtils.md5Hex(user.getPassword()));statement.setString(3,user.getBrief());int rows = statement.executeUpdate();if (rows==1) {return true;}}catch (SQLException ex) {System.out.println("用戶注冊失敗");ex.printStackTrace();}finally {closeResources(connection,statement);}return false;} }

服務(wù)端創(chuàng)建

  • 設(shè)置工具類,讀取配置文件中的IP和PORT
  • 設(shè)置Json格式和Object類之間的相互轉(zhuǎn)換
  • 設(shè)置客戶端和服務(wù)端之間通信的VO對象
public class CommUtils {//這里我們使用的是谷歌推出的GSON類,創(chuàng)建對象(建造者模式) private static final Gson GSON=new GsonBuilder().create();//加載配置文件public static Properties loadProperties(String fileName) {Properties properties=new Properties();InputStream in=CommUtils.class.getClassLoader().getResourceAsStream(fileName);try {properties.load(in);} catch (IOException e) {return null;}return properties;}//將實例化對象轉(zhuǎn)換為JSON格式public static String object2Json(Object obj) {return GSON.toJson(obj);}//將JSON格式轉(zhuǎn)換為實例化對象public static Object json2Object(String jsonStr, Class objClass) {return GSON.fromJson(jsonStr,objClass);} }

創(chuàng)建客戶端和服務(wù)端之間通信的VO對象

public class MessageVO {/*** 客戶端和服務(wù)器之間的協(xié)議*/private String type;/*** 客戶端與服務(wù)端之間發(fā)送數(shù)據(jù)的內(nèi)容*/private String content;/*** 客戶端告訴服務(wù)器要將信息發(fā)送給何處,在群聊中也可封裝群聊用戶集合等數(shù)據(jù)*/private String to;public String getType() {return type;}public void setType(String type) {this.type = type;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getTo() {return to;}public void setTo(String to) {this.to = to;} }

創(chuàng)建服務(wù)端

public class MultiThreadServer {private static final String IP;private static final int PORT;static {//讀取socket配置文件Properties pros= CommUtils.loadProperties("socket.properties");IP=pros.getProperty("address");PORT=Integer.parseInt(pros.getProperty("port"));}public static void main(String[] args) throws IOException {//創(chuàng)建服務(wù)端ServerSocket serverSocket=new ServerSocket(PORT);//創(chuàng)建線程池設(shè)置連接服務(wù)端的人數(shù)ExecutorService executors = Executors.newFixedThreadPool(50);for (int i = 0; i < 50; i++) {System.out.println("等待客戶端連接...");Socket client = serverSocket.accept();System.out.println("有新的客戶端連接,端口號為"+client.getPort());//有客戶端連接就創(chuàng)建線程不斷監(jiān)聽該客戶端發(fā)來的信息executors.submit(new ExecuteClient(client));}} }

封裝客戶端與服務(wù)端的連接

public class Connect2Server {private static final String IP;private static final int PORT;static {Properties properties = CommUtils.loadProperties("socket.properties");IP=properties.getProperty("address");PORT= Integer.parseInt(properties.getProperty("port"));}private Socket client;private InputStream in;private OutputStream out;public Connect2Server() {try {//連接服務(wù)器的端口,所以此處與服務(wù)器端讀取同一個配置文件client=new Socket(IP,PORT);//獲取連接的輸入流in=client.getInputStream();//獲取連接的輸出流out=client.getOutputStream();} catch (IOException e) {e.printStackTrace();}}public InputStream getIn() {return in;}public OutputStream getOut() {return out;} }

用戶注冊模塊

創(chuàng)建GUI Form畫布(窗口):設(shè)置相應(yīng)的窗體名稱,Idea軟件會為我們自動生成窗口的對應(yīng)的屬性,

分析

當(dāng)點擊注冊按鈕之后獲取窗體數(shù)據(jù),封裝成User對象,調(diào)用數(shù)據(jù)庫進行創(chuàng)建,

? ? ? ? 創(chuàng)建成功,顯示創(chuàng)建成功,創(chuàng)建用戶窗口關(guān)閉

? ? ? ? 創(chuàng)建失敗,顯示失敗信息

public class UserReg {private JTextField userNameText;private JPasswordField passwordText;private JTextField brifeText;private JButton regBtn;private JPanel userRegPanel;private AccountDao accountDao=new AccountDao();public UserReg() {JFrame frame = new JFrame("用戶注冊");//包含這個窗口下的所有窗體frame.setContentPane(userRegPanel);//設(shè)置關(guān)閉即該窗口永久消失frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//使窗口顯示在正中央frame.setLocationRelativeTo(null);//根據(jù)布局來確定窗口的最佳大小frame.pack();//窗口圖形界面可視, 默認(rèn)不可視frame.setVisible(true);//點擊注冊按鈕,將信息持久化到db中,成功彈出提示框regBtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//獲取表單參數(shù)String userName = userNameText.getText();//獲取加密的密碼String password = String.valueOf(passwordText.getPassword());String brief=brifeText.getText();//封裝User保存到數(shù)據(jù)庫中User user=new User();user.setUserName(userName);user.setPassword(password);user.setBrief(brief);if (accountDao.userReg(user)) {//注冊成功JOptionPane.showMessageDialog(frame,"注冊成功!","提示信息",JOptionPane.INFORMATION_MESSAGE);frame.setVisible(false);}else {//注冊失敗JOptionPane.showMessageDialog(frame,"注冊失敗!","錯誤信息",JOptionPane.ERROR_MESSAGE);}}});} }

用戶登錄窗口

用畫布畫出該窗口

分析

用戶在登陸界面當(dāng)點擊注冊按鈕時,創(chuàng)建注冊按鈕,跳轉(zhuǎn)到注冊頁面邏輯

用戶在登陸頁面點擊登陸按鈕時,獲取窗體數(shù)據(jù),調(diào)用數(shù)據(jù)庫根據(jù)密碼和用戶名查詢是否存在該用戶

? ? ? ? ?若存在:提示登陸成功信息,

? ? ? ? ? ? ?? ? ? ? ? ?點擊確定,創(chuàng)建連接,將自己的信息以協(xié)議“1”發(fā)送到服務(wù)端,標(biāo)識為登陸邏輯,方便服務(wù)端轉(zhuǎn)向,

? ? ? ? ? ? ? ? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? * 此時?type = 1? ? ?content? = userName

? ? ? ? ? ? ? ? ? ? ? ? 登陸頁面關(guān)閉,創(chuàng)建用戶列表界面

? ? ? ??若不存在

? ? ? ? ? ? ? ? ? ? ? ??提示錯誤信息即可

package com.lin.client.service;import com.lin.client.dao.AccountDao; import com.lin.client.entity.User; import com.lin.util.CommUtils; import com.lin.vo.MessageVO;import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.util.Scanner; import java.util.Set;/*** Description:登陸成功,將當(dāng)前用戶所有的在線好友發(fā)送到服務(wù)器* Author: llf* Created in 2019/8/23 19:04*/ public class UserLogin {private JButton regButton;private JButton loginButton;private JTextField userNameText;private JPasswordField passwordText;private JPanel userPanel;private JPanel UserLoginPanel;private JFrame frame;private AccountDao accountDao=new AccountDao();public UserLogin() {frame = new JFrame("用戶登陸");frame.setContentPane(UserLoginPanel);//退出即關(guān)閉該對象frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//將窗口置于屏幕中央frame.setLocationRelativeTo(null);//根據(jù)頁面布局設(shè)置窗口的大小frame.pack();//圖形界面可視frame.setVisible(true);//創(chuàng)建監(jiān)聽事件,注冊按鈕,當(dāng)點擊該按鈕,創(chuàng)建出一個注冊頁面regButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {new UserReg();}});//創(chuàng)建監(jiān)聽事件,登陸按鈕loginButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//獲取表單參數(shù) 校驗用戶信息String userName = userNameText.getText();String password = String.valueOf(passwordText.getPassword());User user = accountDao.userLogin(userName,password);if (user!=null) {//顯示成功信息**************JOptionPane.showMessageDialog(frame,"登陸成功","提示信息",JOptionPane.INFORMATION_MESSAGE);//登陸頁面關(guān)閉frame.setVisible(false);/*** 與服務(wù)器建立連接* 讀取服務(wù)端所有好友信息* 新建一個后臺進程不斷讀取服務(wù)器發(fā)來的信息* type 1* content userName* to 私聊 群聊*///以協(xié)議1的方式向服務(wù)器發(fā)送數(shù)據(jù)Connect2Server connect2Server=new Connect2Server();MessageVO msg2Server=new MessageVO();msg2Server.setType("1");msg2Server.setContent(userName);String json2Server=CommUtils.object2Json(msg2Server);try {PrintStream out=new PrintStream(connect2Server.getOut(),true,"UTF-8");//發(fā)送數(shù)據(jù)到服務(wù)器out.println(json2Server);//接收服務(wù)器發(fā)來的消息,顯示所有在線好友,加載用戶列表/*** type 1* content 在線用戶信息* to*/Scanner in=new Scanner(connect2Server.getIn());if (in.hasNextLine()) {String msgFromServerStr = in.nextLine();MessageVO msgFromServer=(MessageVO) CommUtils.json2Object(msgFromServerStr,MessageVO.class);//將服務(wù)器發(fā)送過來的信息封裝成一個儲存user對象的Set集合,傳入好友列表進行顯示,Set<String> users = (Set<String>) CommUtils.json2Object(msgFromServer.getContent(), Set.class);System.out.println("所有在線用戶為:" + users);//加載用戶列表界面,將當(dāng)前用戶名,所有在線好友,與服務(wù)器建立連接,傳遞到好友列表界面***********new FriendsList(userName,users,connect2Server);}} catch (UnsupportedEncodingException ex) {ex.printStackTrace();}}else {//登陸失敗,留在當(dāng)前登陸頁面,顯示錯誤信息JOptionPane.showMessageDialog(frame,"登陸失敗!","錯誤信息",JOptionPane.ERROR_MESSAGE);}}});}public static void main(String[] args) {UserLogin userLogin=new UserLogin();} }

服務(wù)器端程序

?//type:“1”?

?//content 所有在線好友? ? ?

//緩存當(dāng)前服務(wù)器所有在線的客戶信息private static Map<String,Socket> clients=new ConcurrentHashMap<>();private static class ExecuteClient implements Runnable{private Socket client;private Scanner in;private PrintStream out;public ExecuteClient(Socket client) {this.client=client;try {this.in=new Scanner(client.getInputStream());this.out=new PrintStream(client.getOutputStream(),true,"UTF-8");} catch (IOException e) {e.printStackTrace();}}@Overridepublic void run() {while (true) {if (in.hasNextLine()) {String jsonStrFromClient = in.nextLine();MessageVO msgFromClient = (MessageVO) CommUtils.json2Object(jsonStrFromClient, MessageVO.class);if (msgFromClient.getType().equals("1")) {//獲取客戶發(fā)來的用戶名String userName=msgFromClient.getContent();/*** 將當(dāng)前所有在線用戶發(fā)送給新用戶* 將新用戶上限信息發(fā)送給其他用戶(上線提醒)* 保存新用戶上線信息*///將當(dāng)前在線的所有用戶發(fā)回客戶端MessageVO msg2Client=new MessageVO();msg2Client.setType("1");msg2Client.setContent(CommUtils.object2Json(clients.keySet()));out.println(CommUtils.object2Json(msg2Client));//將新上線的用戶信息發(fā)回給當(dāng)前以在線的所有用戶sendUserLogin("newLogin:"+userName);//將當(dāng)前用戶注冊到服務(wù)端緩存clients.put(userName,client);System.out.println(userName+"上線了!");System.out.println("當(dāng)前聊天室共有"+clients.size()+"人"); }}}}private void sendUserLogin(String msg) {for(Map.Entry<String,Socket> entry:clients.entrySet()) {Socket socket=entry.getValue();try {PrintStream out=new PrintStream(socket.getOutputStream(),true,"UTF-8");out.println(msg);}catch (IOException e) {e.printStackTrace();}}}}

好友列表和群聊列表模塊

用畫布畫出好友列表和群聊列表窗口的靜態(tài)部分,動態(tài)部分由代碼實現(xiàn)

分析

登陸成功后程序邏輯
服務(wù)端
1.保存新用戶上線信息??request
2.將當(dāng)前所有在線用戶發(fā)回給新用戶?response
3.將新用戶上線信息發(fā)給所有其他用戶(上線提醒)
客戶端
1.與服務(wù)器建立連接,將自己的用戶名與Socket保存到服務(wù)端緩存
2.讀取服務(wù)端的所有在線好友信息
3.新建一個后臺線程不斷讀取服務(wù)器發(fā)來的信息

?

?

public class FriendsList {private JButton createGroupBtn;private JScrollPane friendsList;private JScrollPane groupListPanel;private JPanel friendsPanel;private JFrame frame;private String userName;private Set<String> users;private Connect2Server connect2Server;public FriendsList(String userName, Set<String> users, Connect2Server connect2Server) {this.userName = userName;this.users = users;this.connect2Server = connect2Server;frame = new JFrame(userName);frame.setContentPane(friendsPanel);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(400, 300);//使窗口顯示在正中央frame.setLocationRelativeTo(null);//圖形界面可視, 默認(rèn)不可視frame.setVisible(true);//加載所有在線用戶信息loadUsers();//啟動后臺線程不斷監(jiān)聽服務(wù)器發(fā)來的消息*************************************Thread daemonThread = new Thread(new DaemonTask());//設(shè)置為守護線程daemonThread.setDaemon(true);daemonThread.start();}//好友列表后臺任務(wù),不斷監(jiān)聽服務(wù)器發(fā)來的信息,好友上限提醒,用戶私聊,群聊private class DaemonTask implements Runnable {private Scanner in = new Scanner(connect2Server.getIn());@Overridepublic void run() {while (true) {if (in.hasNextLine()) {//接收服務(wù)到發(fā)來的信息String strFromServer = in.nextLine();//此時服務(wù)器端發(fā)來一個Json字串if (strFromServer.startsWith("{")) {} else {if (strFromServer.startsWith("newLogin:")) { //好友上線邏輯String newFriendName = strFromServer.split(":")[1];users.add(newFriendName);JOptionPane.showMessageDialog(frame,newFriendName + "上線了!", "上線提醒", JOptionPane.INFORMATION_MESSAGE);//刷新好友列表loadUsers();}}}}}}private void loadUsers() {//創(chuàng)建好友列表的盤子JLabel[] userLables = new JLabel[users.size()];JPanel friends = new JPanel();//垂直布局friends.setLayout(new BoxLayout(friends, BoxLayout.Y_AXIS));Iterator<String> iterator = users.iterator();int i = 0;while (iterator.hasNext()) {String userName = iterator.next();userLables[i] = new JLabel(userName); //將好友列表加到盤子中friends.add(userLables[i]);i++;}//將所有的好友的數(shù)組盤子加到friendsList的大盤子friendsList.setViewportView(friends);//設(shè)置滾動條垂直滾動 friendsList.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);//刷新friends.revalidate();friendsList.revalidate();} }

用戶私聊邏輯

用畫布畫出該窗口的靜態(tài)部分,顯示聊天信息部分由代碼實現(xiàn)


?

//緩存所有私聊界面private Map<String, PrivateChatGUI> privateChatGUIList = new ConcurrentHashMap<>();//私聊點擊事件private class PrivateLabelAction implements MouseListener {private String labelName;//根據(jù)標(biāo)簽名稱跳轉(zhuǎn)私聊界面public PrivateLabelAction(String labelName) {this.labelName = labelName;}//鼠標(biāo)點擊事件@Overridepublic void mouseClicked(MouseEvent e) {//判斷好友列表是否緩存私聊標(biāo)簽,if (privateChatGUIList.containsKey(labelName)) {//找到該標(biāo)簽使其顯示PrivateChatGUI privateChatGUI = privateChatGUIList.get(labelName);privateChatGUI.getFreame().setVisible(true);} else {//第一次點擊,創(chuàng)建私聊界面PrivateChatGUI privateChatGUI = new PrivateChatGUI(labelName, userName, connect2Server);privateChatGUIList.put(labelName, privateChatGUI);}}//鼠標(biāo)一直按下事件@Overridepublic void mousePressed(MouseEvent e) {}//鼠標(biāo)按下釋放事件@Overridepublic void mouseReleased(MouseEvent e) {}//鼠標(biāo)移入執(zhí)行事件@Overridepublic void mouseEntered(MouseEvent e) {}//鼠標(biāo)移出事件@Overridepublic void mouseExited(MouseEvent e) {}}

分析

客戶端:

主動發(fā)送方

1.點擊要私聊的用戶標(biāo)簽,彈出私聊界面 (緩存私聊界面對象)?

2.按照指定的協(xié)議向服務(wù)器發(fā)送私聊信息

? ? ? ?// type:2

? ? ? // content:sender-msg

? ? ? // to:目標(biāo)客戶端的用戶名

package com.lin.client.service;import com.lin.util.CommUtils; import com.lin.vo.MessageVO;import javax.swing.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.PrintStream; import java.io.UnsupportedEncodingException;/*** Description:* Author: llf* Created in 2019/8/24 18:55*/ public class PrivateChatGUI {private JTextArea readFromServer;private JPanel privateChatPanel;private JTextField send2Server;private String friendName;private String myName;private Connect2Server connect2Server;private JFrame frame;private PrintStream out;public PrivateChatGUI(String friendName,String myName,Connect2Server connect2Server) {this.friendName=friendName;this.connect2Server=connect2Server;this.myName=myName;try {this.out=new PrintStream(connect2Server.getOut(),true,"UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}frame = new JFrame("與"+friendName+"私聊中...");frame.setContentPane(privateChatPanel);//設(shè)置窗口關(guān)閉操作,將其設(shè)置為隱藏frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);frame.setSize(400,400);frame.setVisible(true);//捕捉輸入框的鍵盤輸入send2Server.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {StringBuilder sb=new StringBuilder();sb.append(send2Server.getText());//當(dāng)捕捉到按下enterif(e.getKeyCode()==KeyEvent.VK_ENTER) {String msg=sb.toString();MessageVO messageVO=new MessageVO();messageVO.setType("2");messageVO.setContent(myName+"-"+msg);messageVO.setTo(friendName);PrivateChatGUI.this.out.println(CommUtils.object2Json(messageVO));//將自己發(fā)送的信息展示到當(dāng)前私聊界面*******readFromServer(myName+"說:"+ msg);send2Server.setText("");}}});}//給信息接收者public void readFromServer(String s) {readFromServer.append(s+"\n");}public JFrame getFreame() {return this.frame;} }

?

服務(wù)端:

1.收到客戶端發(fā)來的私聊信息,取出目標(biāo)端Socket,做信息轉(zhuǎn)發(fā)?

? ? ?// type:2

? ? ?// content:sender-msg

? ? ?// to

private static class ExecuteClient implements Runnable{private Socket client;private Scanner in;private PrintStream out;public ExecuteClient(Socket client) {this.client=client;try {this.in=new Scanner(client.getInputStream());this.out=new PrintStream(client.getOutputStream(),true,"UTF-8");} catch (IOException e) {e.printStackTrace();}}@Overridepublic void run() {while (true) {if (in.hasNextLine()) {String jsonStrFromClient = in.nextLine();MessageVO msgFromClient = (MessageVO) CommUtils.json2Object(jsonStrFromClient, MessageVO.class);if (msgFromClient.getType().equals("1")) {//用戶登錄邏輯}else if (msgFromClient.getType().equals("2")) {//用戶私聊 Type2//Content:myName-msg//to:friendNameString friendName=msgFromClient.getTo();Socket clientSocket=clients.get(friendName);try{PrintStream out=new PrintStream(clientSocket.getOutputStream(),true,"UTF-8");MessageVO msg2Client=new MessageVO();msg2Client.setType("2");msg2Client.setContent(msgFromClient.getContent());System.out.println("收到私聊消息,內(nèi)容為:"+msgFromClient.getContent());out.println(CommUtils.object2Json(msg2Client));}catch (IOException ex){ex.printStackTrace();} }}}}

信息接收方:

1.判斷服務(wù)端發(fā)來的消息是否是私聊信息,若是,判斷緩存中是否有該界面?

2.按照指定協(xié)議來讀取內(nèi)容,發(fā)送消息

//緩存所有私聊界面private Map<String, PrivateChatGUI> privateChatGUIList = new ConcurrentHashMap<>();private class DaemonTask implements Runnable {private Scanner in = new Scanner(connect2Server.getIn());@Overridepublic void run() {while (true) {if (in.hasNextLine()) {//接收服務(wù)到發(fā)來的信息String strFromServer = in.nextLine();//此時服務(wù)器端發(fā)來一個Json字串if (strFromServer.startsWith("{")) {MessageVO messageVO = (MessageVO) CommUtils.json2Object(strFromServer, MessageVO.class);if (messageVO.getType().equals("2")) {String friendName = messageVO.getContent().split("-")[0];String msg = messageVO.getContent().split("-")[1];//判斷此私聊是不是第一次創(chuàng)建if (privateChatGUIList.containsKey(friendName)) {PrivateChatGUI privateChatGUI = privateChatGUIList.get(friendName);privateChatGUI.getFreame().setVisible(true);privateChatGUI.readFromServer(friendName + "說:" + msg);} else {PrivateChatGUI privateChatGUI = new PrivateChatGUI(friendName, userName, connect2Server);privateChatGUIList.put(friendName, privateChatGUI);privateChatGUI.readFromServer(friendName + "說:" + msg);}}} else {if (strFromServer.startsWith("newLogin:")) { //********************** 好友上線邏輯String newFriendName = strFromServer.split(":")[1];users.add(newFriendName);JOptionPane.showMessageDialog(frame,newFriendName + "上線了!", "上線提醒", JOptionPane.INFORMATION_MESSAGE);//刷新好友列表loadUsers();}}}}}}

群聊創(chuàng)建

用畫布畫出該窗口的靜態(tài)部分,顯示好友列表的復(fù)選框部分由代碼實現(xiàn)

分析:點擊提交信息,獲取表單參數(shù),發(fā)送到服務(wù)端

客戶端

? ? ?// type:3

? ? ?// content:groupName

? ? ?// to:selectedFriends

package com.lin.client.service;import com.lin.util.CommUtils; import com.lin.vo.MessageVO; import javafx.scene.effect.SepiaTone; import sun.plugin2.message.Message;import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.util.HashSet; import java.util.Iterator; import java.util.Set;/*** Description:* Author: llf* Created in 2019/8/29 18:43*/ public class CreateGroupGUI {private JPanel createGroupPanel;private JTextField groupNameText;private JButton conformBtn;private JPanel friendLabelPanel;private String myName;private Set<String> friends;private Connect2Server connect2Server;private FriendsList friendsList;public CreateGroupGUI(String myName,Set<String> friends,Connect2Server connect2Server,FriendsList friendsList){this.myName=myName;this.friends=friends;this.connect2Server=connect2Server;this.friendsList=friendsList;JFrame frame = new JFrame("創(chuàng)建群聊");frame.setContentPane(createGroupPanel);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(400,300);//居中frame.setLocationRelativeTo(null);frame.setVisible(true);//將在線好友以checkBox展示到界面中friendLabelPanel.setLayout(new BoxLayout(friendLabelPanel,BoxLayout.Y_AXIS));Iterator<String> iterator=friends.iterator();while (iterator.hasNext()) {String lableName=iterator.next();JCheckBox checkBox=new JCheckBox(lableName);friendLabelPanel.add(checkBox);}friendLabelPanel.revalidate();conformBtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {Set<String> selectedFriends=new HashSet<>();Component[] comps=friendLabelPanel.getComponents();for (Component comp : comps) {//向下轉(zhuǎn)型JCheckBox checkBox= (JCheckBox) comp;if (checkBox.isSelected()) {String labelName= checkBox.getText();selectedFriends.add(labelName);}}//創(chuàng)建記得加入自己的名字selectedFriends.add(myName);//獲取群名String groupName=groupNameText.getText();//發(fā)送給服務(wù)器MessageVO messageVO=new MessageVO();/*** 協(xié)議3*/messageVO.setType("3");messageVO.setContent(groupName);messageVO.setTo(CommUtils.object2Json(selectedFriends));try {PrintStream out=new PrintStream(connect2Server.getOut(),true,"UTF-8");out.println(CommUtils.object2Json(messageVO));} catch (UnsupportedEncodingException e1) {e1.printStackTrace();}//將當(dāng)前群聊界面隱藏frame.setVisible(false);friendsList.addGroup(groupName,selectedFriends);friendsList.loadGroupList();}});}}

服務(wù)端

//緩存當(dāng)前服務(wù)器所有的群名以及群好友private static Map<String,Set<String>> groups=new ConcurrentHashMap<>(); private static class ExecuteClient implements Runnable{private Socket client;private Scanner in;private PrintStream out;public ExecuteClient(Socket client) {this.client=client;try {this.in=new Scanner(client.getInputStream());this.out=new PrintStream(client.getOutputStream(),true,"UTF-8");} catch (IOException e) {e.printStackTrace();}}@Overridepublic void run() {while (true) {if (in.hasNextLine()) {String jsonStrFromClient = in.nextLine();MessageVO msgFromClient = (MessageVO) CommUtils.json2Object(jsonStrFromClient, MessageVO.class);if (msgFromClient.getType().equals("1")) {//用戶登陸邏輯}else if (msgFromClient.getType().equals("2")) {//用戶私聊邏輯}else if (msgFromClient.getType().equals("3")) {String groupName=msgFromClient.getContent();Set<String> friends= (Set<String>) CommUtils.json2Object(msgFromClient.getTo(), Set.class);groups.put(groupName,friends);System.out.println("有新的群注冊成功,群名為:"+groupName+",一共有"+groups.size()+"個群");} }}}

好友列表窗口

//存儲所有的群名稱和群好友private Map<String, Set<String>> groupMap = new ConcurrentHashMap<>(); public void addGroup(String groupName, Set<String> friends) {groupMap.put(groupName, friends);}public void loadGroupList() {//存儲所有群名稱的標(biāo)簽JpanelJPanel groupNamePanel = new JPanel();groupNamePanel.setLayout(new BoxLayout(groupNamePanel, BoxLayout.Y_AXIS));JLabel[] labels = new JLabel[groupMap.size()];//Map遍歷Set<String> entries = groupMap.keySet();Iterator<String> iterator = entries.iterator();int i = 0;while (iterator.hasNext()) {String groupName = iterator.next();labels[i] = new JLabel(groupName);//添加到自定義的盤子groupNamePanel.add(labels[i]);i++;}//將自定義盤子加到滾動條中g(shù)roupListPanel.setViewportView(groupNamePanel);//設(shè)置垂直滾動groupListPanel.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);//刷新groupListPanel.revalidate();}

群聊消息

用畫布畫出該窗口的靜態(tài)部分,顯示好友列表和群聊消息的部分由代碼實現(xiàn)


?

//緩存所有的群聊頁面 群聊名 和群聊界面private Map<String, GroupChatGUI> groupChatGUIMap=new ConcurrentHashMap<>();//群聊點擊事件private class GroupLabelAction implements MouseListener {private String groupName;public GroupLabelAction(String groupName) {this.groupName=groupName;}@Overridepublic void mouseClicked(MouseEvent e) {if (groupChatGUIMap.containsKey(groupName)) {GroupChatGUI groupChatGUI=groupChatGUIMap.get(groupName);groupChatGUI.getFrame().setVisible(true);}else {// 獲得所有的群聊成員Set<String> names=groupMap.get(groupName);GroupChatGUI groupChatGUI=new GroupChatGUI(groupName,names,userName,connect2Server);groupChatGUIMap.put(groupName,groupChatGUI);}}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}}

分析
客戶端
群聊發(fā)起者?
1.點擊群名稱標(biāo)簽,彈出群聊界面
2.將群聊內(nèi)容發(fā)送到服務(wù)端
//?type:4
//?content:senderName-msg
//?to:groupName

package com.lin.client.service;import com.lin.util.CommUtils; import com.lin.vo.MessageVO;import javax.swing.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.util.Iterator; import java.util.Set;/*** Description:* Author: llf* Created in 2019/8/29 20:30*/ public class GroupChatGUI {private JPanel groupPanel;private JTextArea readFromServer;private JTextField send2Server;private JPanel friendsPanel;private String groupName;private Set<String> friends;private String myName;private Connect2Server connect2Server;private JFrame frame;public GroupChatGUI(String groupName,Set<String> friends,String myName,Connect2Server connect2Server) {frame= new JFrame("GroupChatGUI");frame.setContentPane(groupPanel);frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);frame.setLocationRelativeTo(null);frame.setSize(400,400);frame.setVisible(true);friendsPanel.setLayout(new BoxLayout(friendsPanel,BoxLayout.Y_AXIS));Iterator<String> iterator=friends.iterator();while (iterator.hasNext()) {String lableName=iterator.next();JLabel jLabel=new JLabel(lableName);friendsPanel.add(jLabel);}send2Server.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {StringBuilder sb=new StringBuilder();sb.append(send2Server.getText());//捕捉回車按鍵if (e.getKeyCode()==KeyEvent.VK_ENTER) {String str2Server=sb.toString();/*** type:4* content:myName-msg* to:groupName*/MessageVO messageVO=new MessageVO();messageVO.setType("4");messageVO.setContent(myName+"-"+str2Server);messageVO.setTo(groupName);try {PrintStream out=new PrintStream(connect2Server.getOut(),true,"UTF-8");out.println(CommUtils.object2Json(messageVO));send2Server.setText("");} catch (UnsupportedEncodingException e1) {e1.printStackTrace();}}}});}public void readFromServer(String msg) {readFromServer.append(msg+"\n");}public JFrame getFrame() {return frame;} }

服務(wù)端?
1.收到群聊信息,解出群名
2.根據(jù)群名稱找到該群的所有用戶的用戶名
3.再根據(jù)用戶名找到該用戶的Socket,發(fā)送群聊信息

//?type:4
//?content:senderName-msg
//?to:groupName-[該群的所有群成員]

?

@Overridepublic void run() {while (true) {if (in.hasNextLine()) {String jsonStrFromClient = in.nextLine();MessageVO msgFromClient = (MessageVO) CommUtils.json2Object(jsonStrFromClient, MessageVO.class);if (msgFromClient.getType().equals("1")) {//登陸成功邏輯}else if (msgFromClient.getType().equals("2")) {//用戶私聊 }else if (msgFromClient.getType().equals("3")) {//創(chuàng)建群組}else if (msgFromClient.getType().equals("4")) {// type:4// content:myName-msg// to:groupNameString groupName=msgFromClient.getTo();Set<String> names=groups.get(groupName);Iterator<String> iterator=names.iterator();while (iterator.hasNext()) {String socketName=iterator.next();Socket client=clients.get(socketName);try {PrintStream out=new PrintStream(client.getOutputStream(),true,"UTF-8");/*** typr=4* content直接轉(zhuǎn)發(fā)* 組名-所有的群成員*/MessageVO messageVO=new MessageVO();messageVO.setType("4");messageVO.setContent(msgFromClient.getContent());messageVO.setTo(groupName+"-"+CommUtils.object2Json(names));out.println(CommUtils.object2Json(messageVO));System.out.println("服務(wù)器發(fā)送的群聊消息為:"+messageVO);} catch (IOException e) {e.printStackTrace();}}}}}

群聊接收者
1.當(dāng)?shù)谝淮问盏饺盒畔?#xff0c;先刷新本客戶端的群聊列表信息
2.彈出群聊界面

private class DaemonTask implements Runnable {private Scanner in = new Scanner(connect2Server.getIn());@Overridepublic void run() {while (true) {if (in.hasNextLine()) {//接收服務(wù)到發(fā)來的信息String strFromServer = in.nextLine();//此時服務(wù)器端發(fā)來一個Json字串if (strFromServer.startsWith("{")) {MessageVO messageVO = (MessageVO) CommUtils.json2Object(strFromServer, MessageVO.class);if (messageVO.getType().equals("2")) {//私聊客戶端邏輯}else if (messageVO.getType().equals("4")) {/*** 收到服務(wù)器發(fā)來的群聊信息* type* content:sender-msg* to:groupName-[]*/String groupName = messageVO.getTo().split("-")[0];String senderName = messageVO.getContent().split("-")[0];String groupMsg = messageVO.getContent().split("-")[1];//若此名稱在群聊列表if (groupMap.containsKey(groupName)) {if (groupChatGUIMap.containsKey(groupName)) {//緩存中有群聊界面 彈出GroupChatGUI groupChatGUI = groupChatGUIMap.get(groupName);groupChatGUI.getFrame().setVisible(true);groupChatGUI.readFromServer(senderName+"說:"+groupMsg);}else {//緩存中沒有Set<String> names=groupMap.get(groupName);GroupChatGUI groupChatGUI=new GroupChatGUI(groupName,names,userName,connect2Server);groupChatGUIMap.put(groupName,groupChatGUI);groupChatGUI.readFromServer(senderName+"說:"+groupMsg);}}else {/*** 用戶第一次收到群聊消息*/Set<String> friends= (Set<String>) CommUtils.json2Object(messageVO.getTo().split("-")[1],Set.class);groupMap.put(groupName,friends);loadGroupList();//彈出群聊界面GroupChatGUI groupChatGUI = new GroupChatGUI(groupName,friends,userName,connect2Server);groupChatGUIMap.put(groupName,groupChatGUI);groupChatGUI.readFromServer(senderName+"說:"+groupMsg);}}} else {if (strFromServer.startsWith("newLogin:")) { //********************** 好友上線邏輯String newFriendName = strFromServer.split(":")[1];users.add(newFriendName);JOptionPane.showMessageDialog(frame,newFriendName + "上線了!", "上線提醒", JOptionPane.INFORMATION_MESSAGE);//刷新好友列表loadUsers();}}}}}}

?

?

總結(jié)

以上是生活随笔為你收集整理的JavaGUI--模拟QQ聊天界面私聊群聊的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

97国产一区 | 正在播放一区二区 | 极品久久久久久久 | 日日操日日 | 亚洲精品短视频 | 成人av电影免费观看 | 亚洲aⅴ一区二区三区 | 99久久精品免费看国产免费软件 | 日本精品一区二区 | www.夜夜夜 | 久久综合色播五月 | 美女网站视频色 | 91麻豆免费视频 | 五月婷婷在线播放 | 午夜精品久久久久99热app | 偷拍精偷拍精品欧洲亚洲网站 | 日本三级中文字幕在线观看 | 一区二区三区四区精品 | 中文字幕在线观看视频一区 | 久草视频在线免费看 | 亚洲精品视频在线观看免费 | 日韩电影在线观看一区二区三区 | 国产精选视频 | 97中文字幕| 91九色视频导航 | 欧美韩日精品 | 射射射综合网 | 久久久久久亚洲精品 | 一区二区在线电影 | 99精品视频在线播放观看 | 欧美一级片播放 | 欧美精品成人在线 | 国产一区二区精 | 日本中文字幕在线一区 | 麻豆一精品传二传媒短视频 | 国产大陆亚洲精品国产 | 夜夜操天天 | 四虎永久国产精品 | 成人免费观看完整版电影 | 国模精品一区二区三区 | 成人国产网站 | 日韩精品久久久 | 天天添夜夜操 | 伊甸园av在线 | av成人在线电影 | 国产亚洲精品v | 国产中文字幕网 | 久久99精品久久只有精品 | 日韩成人一级大片 | 91成人短视频在线观看 | 一本一本久久a久久精品牛牛影视 | 欧美精品在线观看免费 | 在线v| 久久久久国产精品一区二区 | 日韩欧美视频在线观看免费 | 六月婷婷久香在线视频 | 探花视频免费在线观看 | 国产一二三四在线观看视频 | 国产日韩高清在线 | 亚洲精品88欧美一区二区 | 久久久久久久久久久影视 | www.久久久com| 国产午夜三级一区二区三 | 在线影视 一区 二区 三区 | 天天干天天弄 | 日日操天天操夜夜操 | 91.麻豆视频 | 97国产超碰| 免费看的黄色片 | www亚洲一区| 99久久激情视频 | 免费网站看av片 | 色成人亚洲网 | www.午夜 | 欧美日韩中文在线观看 | 99在线视频免费观看 | 在线观看aa | 国产人成精品一区二区三 | caobi视频 | 亚洲一区美女视频在线观看免费 | 国产无套精品久久久久久 | 久久久亚洲影院 | 激情综合一区 | 99热官网 | 国产免费观看久久黄 | 国产精品日韩久久久久 | 久久99视频免费观看 | 97色se| 国产高清免费在线观看 | 国产亲近乱来精品 | 999久久久| 在线亚洲激情 | 成年人免费av网站 | 日本午夜在线亚洲.国产 | 成人资源在线播放 | 一级做a爱片性色毛片www | 中文字幕在线观看第二页 | 久久国产精品二国产精品中国洋人 | 国产在线中文 | 欧美日韩一区二区久久 | 一区 在线观看 | 婷婷色 亚洲 | 欧美日本不卡高清 | 亚洲精品乱码久久久久v最新版 | 成人黄色免费在线观看 | 香蕉免费在线 | 国产精品午夜在线观看 | 午夜精品一区二区三区在线观看 | 亚洲黑丝少妇 | 欧美日韩激情视频8区 | 久草新在线 | 日韩精品极品视频 | 久久久亚洲电影 | 成人久久久久久久久久 | 亚洲国产高清在线观看视频 | 中文资源在线观看 | 国产不卡一区二区视频 | 操操操天天操 | 免费在线观看视频一区 | 天天干天天射天天爽 | 日韩欧美视频一区二区三区 | 国产亚洲欧美日韩高清 | 成人免费在线观看电影 | 婷婷丁香花五月天 | 久久久性 | 久久福利剧场 | 大荫蒂欧美视频另类xxxx | 偷拍视频一区 | 一本一本久久a久久精品综合妖精 | 国产涩涩网站 | 97av超碰 | 91色蜜桃| 中文乱幕日产无线码1区 | 美女久久网站 | 在线观看不卡视频 | 99久热精品 | 亚洲黄色一级视频 | 午夜av免费 | 国产又粗又硬又爽的视频 | 欧美久久久久久久久久 | 操久在线 | 五月花激情 | 欧洲av在线 | 久久精国产 | 国产成人精品av | 69久久99精品久久久久婷婷 | 欧美激情第一区 | 最近高清中文字幕 | 成人性生活大片 | 精品超碰 | 99日精品| 天天舔天天射天天操 | 日日成人网 | 黄色网在线免费观看 | 亚洲第一久久久 | 成人毛片在线观看视频 | 蜜臀av.com| 成人免费视频观看 | 99精品视频在线看 | 午夜视频久久久 | 女人18片 | 99视频导航 | 激情片av| 午夜国产在线观看 | 国产高清在线看 | av超碰在线| 亚洲va欧美va人人爽春色影视 | 国产精品久久久久久久久久不蜜月 | 国产最新网站 | 91在线永久| 色视频在线免费 | 免费在线91| 久久综合五月天婷婷伊人 | 人人澡澡人人 | 国产成人一级 | 色wwwww| 99视频在线观看视频 | 少妇bbb好爽 | 亚洲欧美国产精品va在线观看 | 久久精品欧美一区 | 亚洲经典在线 | 日韩欧美精品在线观看视频 | 欧美精品一区二区三区一线天视频 | 一级性视频 | ww亚洲ww亚在线观看 | 男女全黄一级一级高潮免费看 | 正在播放国产一区 | 日本三级在线观看中文字 | 日韩欧美精品在线 | 色99导航 | 亚洲成免费 | 五月婷婷视频在线观看 | 九九热视频在线免费观看 | 97人人人人| 亚洲黄网站 | 91成人区| 天堂av影院 | 特级免费毛片 | www色网站 | 国产免费又黄又爽 | 色婷婷激婷婷情综天天 | 天无日天天操天天干 | 亚洲精品婷婷 | 超碰在线个人 | 日韩在线观看视频网站 | 一区二区三区在线观看免费 | 国产在线观看一区 | 日韩日韩日韩日韩 | 免费h精品视频在线播放 | 亚洲第五色综合网 | 99r在线视频 | 亚洲色图 校园春色 | 91在线播 | 成人黄色免费在线观看 | 久久全国免费视频 | 91尤物国产尤物福利在线播放 | 狠狠网亚洲精品 | 天堂在线视频中文网 | 五月天久久精品 | 日韩精品中文字幕一区二区 | 特级a老妇做爰全过程 | 国产精品久久久久9999 | 碰超在线| 精品久久久久久久久久久久久久久久 | 亚洲专区在线视频 | 欧美亚洲精品在线观看 | 久久精品视频在线免费观看 | 成人在线免费看 | 一区二区av | 日韩伦理一区二区三区av在线 | 91视频91色 | 亚洲精品视频在线观看免费 | 五月激情久久 | 亚洲精品大全 | 丁香视频在线观看 | av+在线播放在线播放 | 亚洲国产成人av网 | 免费高清看电视网站 | 奇米影视四色8888 | 超碰人人草人人 | 日三级在线 | 97超碰国产在线 | 久久免费av电影 | 久草免费在线观看 | 91九色porny在线| 中文字幕专区高清在线观看 | 亚洲欧美日韩精品久久奇米一区 | 久久都是精品 | av网址aaa| 超碰在线人 | 久久伦理视频 | 国产精品一区二区久久精品爱涩 | 中文字幕精品www乱入免费视频 | 国产精品视屏 | 久久免费视频网 | 色在线亚洲 | 九色porny真实丨国产18 | 中文字幕 影院 | 免费福利在线播放 | 色视频成人在线观看免 | 精品免费视频123区 午夜久久成人 | 国内三级在线观看 | 2023天天干| 久久精品99国产国产 | 亚洲人人爱 | 高潮久久久 | 在线免费观看黄色 | 国产精品久久久久久av | 国产999精品视频 | 九色福利视频 | 久久avav| 日韩网站在线播放 | 一本一道久久a久久综合蜜桃 | 97热在线观看 | 综合色中文 | 亚洲精品乱码久久久一二三 | 91精品视频免费看 | 日韩乱码中文字幕 | 亚洲va韩国va欧美va精四季 | a黄色影院 | 国产精品久久久久亚洲影视 | 国产成人777777 | 亚洲另类在线视频 | 999电影免费在线观看2020 | 五月天久久综合网 | 亚洲aⅴ在线 | av免费在线观看1 | 国产精品久久网站 | 国产精品久久嫩一区二区免费 | 久久精品欧美日韩精品 | 久二影院 | 伊人伊成久久人综合网小说 | 六月激情网| 天天干天天干天天干天天干天天干天天干 | 九九免费精品视频在线观看 | 亚洲午夜精品一区 | 99热精品久久 | 国产精品专区在线观看 | 三级黄色免费 | 高清不卡毛片 | 日韩视频 一区 | 久久综合影院 | 天天av综合网 | av高清不卡 | 在线观看日本高清mv视频 | www.色在线| 日韩和的一区二在线 | 久久婷亚洲五月一区天天躁 | 五月天亚洲综合小说网 | 日韩精品无码一区二区三区 | 在线观看成人毛片 | 五月天综合 | 天天天天天天操 | 欧美色黄 | 久久久久久久久久久电影 | 美女黄色网在线播放 | 九色91av| 日韩久久午夜一级啪啪 | 久久香蕉一区 | 日韩免费小视频 | 97在线观| 中文字幕在线免费 | 在线国产高清 | 不卡的av在线播放 | 草在线 | 国产精品免费在线播放 | 日韩久久一区二区 | 色偷偷888欧美精品久久久 | 97超级碰碰碰视频在线观看 | 又爽又黄又无遮挡网站动态图 | 国产精品9999久久久久仙踪林 | 丝袜精品视频 | 成人在线免费av | 中文字幕在线网址 | 99爱精品在线 | 日本深夜福利视频 | 欧美亚洲国产精品久久高清浪潮 | 精品福利网站 | 久久999精品 | 九九热1| 黄a在线观看 | 亚洲视频999 | 久久免费视频在线观看30 | 中文字幕在线一区二区三区 | av福利电影| 看国产黄色片 | 在线观av | 亚洲精品国产片 | 久久综合九色综合久99 | 久久看片网站 | 97香蕉久久国产在线观看 | 三级av在线播放 | 亚洲欧美国产精品va在线观看 | 中文字幕国产亚洲 | 中文字幕在线看 | 国产黄色免费在线观看 | 中文字幕4 | 天天干人人干 | 最新婷婷色 | 麻豆国产电影 | av电影在线观看 | 在线视频福利 | 综合网五月天 | 亚洲欧美国产视频 | 午夜av在线电影 | 日韩在线观看不卡 | 中文字幕超清在线免费 | 高清不卡一区二区三区 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 国产免费黄视频在线观看 | 国产一区二区久久久 | 一区二区视频电影在线观看 | 免费黄在线看 | 91爱在线 | 超碰在线色 | 亚洲 综合 国产 精品 | 亚洲精品乱码久久久久久蜜桃91 | 欧美日性视频 | av千婊在线免费观看 | 国产欧美日韩精品一区二区免费 | 99久久精品免费看国产一区二区三区 | 成人小视频在线观看免费 | 狠狠色丁香婷婷综合久小说久 | 久久爱992xxoo | 日韩在线观看的 | 黄色在线成人 | 91免费视频网站在线观看 | 天天操网 | 欧美日韩综合在线 | 国产精品自产拍在线观看中文 | 中文字幕在线观看第一页 | 国产精品久久久久久久久久久不卡 | 激情偷乱人伦小说视频在线观看 | 国产精品永久久久久久久久久 | 在线免费观看视频一区 | 人人澡超碰碰 | 亚洲一区二区三区在线看 | 99国产免费网址 | 免费高清男女打扑克视频 | 久久影院精品 | 精品麻豆 | 五月天久久狠狠 | 久久人人爽人人爽 | 日韩黄色免费在线观看 | 亚洲日韩中文字幕 | 日韩av网站在线播放 | 久久久久久久精 | 九色激情网 | 亚洲激情中文 | 在线黄色国产电影 | 四虎国产免费 | 最新精品视频在线 | 美女一级毛片视频 | 免费色av| 黄色国产大片 | 五月婷婷六月丁香在线观看 | 欧美日韩国产一区 | 91久久精品一区二区二区 | 久久久久草 | 久久久久久久久久电影 | 欧美日韩午夜在线 | 久久精品国产免费看久久精品 | 国产精品igao视频网网址 | 国产一区二区不卡在线 | 丁香五月亚洲综合在线 | 国产黑丝袜在线 | 欧美肥妇free | 国产精品欧美在线 | 黄色片视频免费 | 97视频在线播放 | 国产中文字幕在线播放 | 国产系列精品av | 中文字幕精 | av黄色在线观看 | 国产亚洲精品电影 | 久久99网| 美女黄视频免费看 | 涩涩伊人 | 日韩免费看 | 成人三级av | 成人av影视观看 | .国产精品成人自产拍在线观看6 | 日批视频国产 | 亚洲激情视频 | 国产精品www| 国产你懂的在线 | 久精品视频在线观看 | 亚洲国产三级在线 | 西西444www大胆高清视频 | 国产精品一区二区久久精品 | 久草99 | 96国产在线 | 欧美激情第十页 | 久久99热这里只有精品国产 | 综合色狠狠 | 久久成年人 | 精品久久久久久久久久国产 | 国产精品二区三区 | 国产亚洲精品久久久久久移动网络 | a电影在线观看 | 国产亚洲一级高清 | 国产成人久久精品77777 | 精品久久久久国产免费第一页 | 天天操天天操天天操天天操 | 国产精品色婷婷视频 | 日韩在线电影一区二区 | 中文字幕在线视频一区二区三区 | 婷婷四房综合激情五月 | 一个色综合网站 | 久久久色| 亚洲国产美女久久久久 | 狠狠色丁香婷婷综合久小说久 | 久久精品视频中文字幕 | 丁香花在线视频观看免费 | 欧美va在线观看 | 久久99热精品这里久久精品 | 一本一本久久a久久精品综合妖精 | 一区二区三区电影大全 | 亚洲午夜精品一区二区三区电影院 | 中文字幕亚洲精品在线观看 | 天天插天天干天天操 | 久久av免费| 开心激情婷婷 | 最近中文字幕mv免费高清在线 | 免费看v片网站 | 久久久久久久久久久网 | 日日夜夜精品视频天天综合网 | 激情综合中文娱乐网 | 亚洲综合五月 | 综合网天天射 | 久久国产影视 | 国产又黄又爽又猛视频日本 | 午夜精品久久久久久99热明星 | 精品久久久久久久久中文字幕 | 久一在线 | 午夜久久久影院 | 999国内精品永久免费视频 | 亚洲综合色网站 | 国产黄色av| 久久精品人| 日韩欧美在线观看一区二区 | 国产专区在线播放 | 男女靠逼app| 在线中文日韩 | 午夜电影久久久 | 久久综合久久综合九色 | 91精品对白一区国产伦 | 久久99国产精品免费 | a资源在线| 欧美成人xxxx | 中文字幕第 | 亚洲黄色app| 国产精品手机视频 | a在线播放 | 久久国产系列 | 日批视频国产 | 黄色网址av | 亚洲成人第一区 | 91人人视频在线观看 | 精品欧美在线视频 | wwxxxx日本| 国产精品每日更新 | 狠狠狠狠狠狠狠狠 | 99精品在线免费观看 | 亚洲国产精品久久久久久 | 国产91在线看 | 色av色av色av | 中文字幕日韩伦理 | 日韩精品中文字幕在线观看 | 1000部国产精品成人观看 | 国产污视频在线观看 | 午夜精品视频免费在线观看 | 日韩午夜在线观看 | 狠狠的日| 香蕉久久国产 | 亚洲精品视频在线观看免费视频 | 国产精品一区二区久久精品 | 国产成人综合图片 | 中文字幕乱码一区二区 | 91精品国产成人www | 激情av综合 | 日韩电影中文字幕在线 | 色婷婷狠 | 天天综合狠狠精品 | 成人蜜桃 | 国产精品第54页 | 97av超碰| 久久综合九色99 | 狠狠色综合网站久久久久久久 | 在线观看福利网站 | 五月天婷婷综合 | 精品中文字幕在线播放 | 在线精品亚洲 | www.av免费| 91久久精品日日躁夜夜躁国产 | 操操操日日日干干干 | 91精品网站在线观看 | 人人爽人人澡 | 国产精品一区二区在线 | 天天弄天天操 | 五月天com| 中文av网 | 国产色网站| 91福利国产在线观看 | 亚洲视频电影在线 | 国产女人40精品一区毛片视频 | 97超碰人人澡人人 | 国产99久久久精品 | 国产精品一区二区av日韩在线 | 深爱激情五月婷婷 | 国产在线一区二区 | 久草网免费 | 天天色天天爱天天射综合 | 超碰公开在线 | 中文字幕免费一区 | 国产在线精品国自产拍影院 | 欧美日韩三区二区 | 国产韩国精品一区二区三区 | 欧美一区免费观看 | 91看片在线免费观看 | 成年人免费观看在线视频 | 国产色啪| 久久国产精品色婷婷 | 福利一区二区在线 | 国内精品毛片 | 日韩欧美一区二区在线 | 亚洲成人资源网 | 日韩欧美精品在线观看 | 日本在线中文 | 日本黄色黄网站 | 亚洲精品免费播放 | 九九视频在线观看视频6 | 久久一级片 | 午夜久久福利影院 | 2021久久 | 在线日韩三级 | 国产高清视频在线播放 | h视频在线看 | 国产精品美女免费视频 | 国产成人黄色在线 | 最近中文字幕在线 | 国产精品人成电影在线观看 | 国产精品久久久久久五月尺 | 综合网色 | 亚洲激情校园春色 | 国产美女精品在线 | 成年美女黄网站色大片免费看 | 国产精品自产拍在线观看网站 | 免费精品视频 | 亚洲 欧美变态 另类 综合 | 五月婷婷六月丁香在线观看 | 国产视频一区二区在线观看 | 午夜视频免费播放 | 成人一级在线 | 丁香综合激情 | av解说在线观看 | 最新国产视频 | 日韩精品一区在线播放 | 精品久久久久久国产91 | 亚洲自拍偷拍色图 | a天堂最新版中文在线地址 久久99久久精品国产 | 欧美日韩在线视频免费 | 久久婷婷视频 | 99re6热在线精品视频 | 中文字幕专区高清在线观看 | 黄网站色 | 亚洲综合射 | 亚洲资源在线观看 | 精品在线观看一区二区三区 | 91精品福利在线 | 国产 欧美 日韩 | 黄色中文字幕 | 97超碰人人澡人人 | 国产视频二区三区 | 欧美日韩在线视频一区二区 | 亚洲精品国产精品国自 | 香蕉视频在线网站 | 国产粉嫩在线 | 成人午夜性影院 | 国产日韩欧美在线影视 | 成人久久久电影 | 日韩精品免费一区 | 国产99在线免费 | 久久国产精品99久久久久久老狼 | 国产录像在线观看 | 91麻豆免费视频 | 午夜a区 | 久久久九色精品国产一区二区三区 | 成人h视频在线播放 | 国产精品女人久久久久久 | 久久久影院一区二区三区 | 99在线观看精品 | 美女国产 | 国产午夜三级 | 日韩大片在线观看 | 日韩av电影中文字幕在线观看 | 国产精品成人一区 | 日韩aa视频| 国产精品久久久久久久婷婷 | 国产高清永久免费 | 国产精品美| 成人aaa毛片 | 精品播放| 99热官网| 欧美贵妇性狂欢 | 久久久久亚洲精品成人网小说 | 国产在线久草 | 国产黄av| 天天艹日日干 | 免费a网址 | 久久久精品 | 亚洲一区精品人人爽人人躁 | 亚洲国产三级在线 | 免费成人在线观看视频 | 亚洲最快最全在线视频 | 国产亚洲精品福利 | 久久这里有精品 | 在线观看精品黄av片免费 | 99精品在这里 | 天天综合色天天综合 | 六月天综合网 | 亚洲精品视频一二三 | 天天操天天操天天操天天操天天操天天操 | 亚洲欧美偷拍另类 | 国产福利精品一区二区 | 99在线播放 | 婷婷综合久久 | 国产精品久久久久久一区二区三区 | 97免费| 91福利在线导航 | 日韩精品免费一线在线观看 | 91福利试看 | 国产中文字幕免费 | 亚洲男男gⅴgay双龙 | 色视频网页 | 成人久久精品视频 | 欧美成年网站 | 亚洲激情在线视频 | 中文字幕欧美日韩va免费视频 | 精品国产乱码一区二区三区在线 | 成人在线视频你懂的 | 日韩电影在线观看一区二区三区 | 五月天国产 | 91一区二区三区久久久久国产乱 | 亚洲日韩欧美一区二区在线 | 91视频久久| 国产一线天在线观看 | 欧美激情视频一区二区三区免费 | 日本精品中文字幕 | 国产精品日韩在线播放 | 久久国产免费看 | 色www永久免费 | 国产一区二区三区免费观看视频 | 精品国内 | 黄色视屏免费在线观看 | 色婷婷中文 | 99久久精品国产一区二区三区 | 国产成人a亚洲精品v | 91成人精品 | 九九日九九操 | 五月av在线| 青青啪| 婷婷去俺也去六月色 | 亚洲精品视频第一页 | 麻豆一精品传二传媒短视频 | 国产精品久久久久一区二区国产 | 免费在线观看毛片网站 | 最近中文字幕完整高清 | 色中文字幕在线观看 | 国产精品免费观看国产网曝瓜 | 在线国产视频观看 | 国产精品岛国久久久久久久久红粉 | 久久国产露脸精品国产 | 日韩成人免费观看 | 天天操导航| 777久久久 | 日韩免费电影网站 | 视频一区二区视频 | 婷婷激情5月天 | 最近最新中文字幕 | 成x99人av在线www | 国产精品你懂的在线观看 | 四虎影视精品 | 最新久久久 | 999电影免费在线观看 | 天天操天天射天天添 | 久久久www成人免费毛片 | 天天操天天摸天天射 | 亚洲精品中文在线 | 国内免费久久久久久久久久久 | 国产免费片 | 亚洲欧美日韩精品久久奇米一区 | 精品色综合 | 国产一级免费播放 | 久久久久久久久久国产精品 | 久久久久久福利 | 国产v视频 | 久草在线视频网站 | 久久久精品电影 | 国产区精品区 | 黄色视屏免费在线观看 | 日韩欧美一区二区在线 | 99久高清在线观看视频99精品热在线观看视频 | 色婷婷www| www.大网伊人| 久久综合久久八八 | 亚洲精品成人在线 | 黄色免费网站大全 | 亚洲综合黄色 | 国产一区影院 | 夜夜操天天摸 | 少妇bbb好爽 | 精品国产视频在线 | 91在线一区二区 | 2019中文字幕网站 | 在线观看中文字幕av | 日韩三级视频在线看 | 国产成人免费观看久久久 | 99热在线网站 | 久久久综合 | 香蕉影院在线观看 | 少妇bbbb | 欧美日韩一二三四区 | 极品久久久久 | 人人盈棋牌| 久久爱www. | 亚洲精品视频网站在线观看 | 国产高清av免费在线观看 | av在线一二三区 | 人人澡人人添人人爽一区二区 | 一区二区 久久 | 国产在线精品一区 | 国产一区二区精品久久 | 免费在线观看毛片网站 | 在线之家官网 | 人成午夜视频 | 视频国产在线 | 日本xxxxav | 精品国产乱码久久久久 | 久久国色夜色精品国产 | 国产精品久久久久三级 | 国产精品成人一区二区三区吃奶 | 国产理论免费 | 夜夜操网 | 国产成人一二三 | 精品一区二区在线免费观看 | 日韩av在线免费看 | 一区二区三区久久精品 | 综合网在线视频 | 日韩精品免费专区 | 成人午夜黄色影院 | 国产经典 欧美精品 | 国产精品美女久久久久aⅴ 干干夜夜 | 在线观看一 | 玖玖视频国产 | 日韩中文久久 | 日日干干夜夜 | 国产在线观看国语版免费 | 国产精品手机在线 | 日韩免费观看av | 亚洲深夜影院 | 天天干.com | 成人9ⅰ免费影视网站 | 免费看久久久 | 精品国产区在线 | 激情综合五月婷婷 | 久久99精品久久只有精品 | 超碰免费久久 | 99精品视频在线播放免费 | 久久亚洲国产精品 | 欧美成人在线免费 | 精品视频99 | 久久在线看 | 狠狠色丁香婷婷综合 | 久精品视频免费观看2 | 日本99久久| 欧美精品久久久久久久久免 | 亚洲欧美一区二区三区孕妇写真 | 国产成人一区二区三区影院在线 | 18性欧美xxxⅹ性满足 | 日本久久综合视频 | 91精品国产乱码久久桃 | 麻豆成人精品视频 | 国产专区日韩专区 | 精品久久网站 | 狠狠干夜夜 | 久久免费精品国产 | 五月天久久久久 | 27xxoo无遮挡动态视频 | 日韩精品一区二区三区免费观看视频 | 一本到视频在线观看 | 久久久综合精品 | 成人一区二区在线观看 | 国产.精品.日韩.另类.中文.在线.播放 | 久久免费播放视频 | 国产在线毛片 | 五月婷婷六月丁香在线观看 | 亚洲激情在线播放 | 最近中文字幕免费观看 | 91免费高清视频 | 亚洲精品玖玖玖av在线看 | adc在线观看 | 奇米影视四色8888 | 久久久久久久久久亚洲精品 | 91九色视频观看 | 欧美一区二区三区激情视频 | 久久久久久久久久久黄色 | 97视频亚洲| 一本一道波多野毛片中文在线 | 亚洲国产免费看 | 色播五月婷婷 | 麻豆一区二区三区视频 | 精品国产区在线 | 成人午夜精品 | 久久久污 | 欧美a√在线 | 久久神马影院 | 欧美激情第八页 | www.玖玖玖 | 又黄又爽又刺激视频 | 欧美一区二区视频97 | 最近最新最好看中文视频 | 亚洲天堂色婷婷 | 成人av高清在线 | 99热999| 色婷婷久久久 | 91精品一区二区三区蜜臀 | 久99久中文字幕在线 | 免费av高清 | 九九色在线观看 | 黄色电影小说 | 香蕉视频网址 | 成年人视频免费在线播放 | 久久av黄色 | 国产中文字幕在线免费观看 | 中文字幕你懂的 | 日日操操 | 91伊人久久大香线蕉蜜芽人口 | 精品福利网 | www久| 免费高清在线观看成人 | 夜夜骑日日 | 亚洲在线视频观看 | 免费观看丰满少妇做爰 | 精品久久久久_ | 在线电影a | 精品一区二区在线看 | 免费网站黄 | 亚洲一区精品人人爽人人躁 | 日韩电影在线观看一区 | 97人人澡人人爽人人模亚洲 | 91aaa在线观看| 探花视频在线版播放免费观看 | 欧美亚洲久久 | 在线观看国产成人av片 | 91日韩在线视频 | 国产精品自拍在线 | 国产一区二区成人 | 四虎成人精品在永久免费 | 日韩啪啪小视频 | 在线免费高清一区二区三区 | 日韩有码在线播放 | 日韩一区正在播放 | 亚洲黄色a | 欧美性黑人 | 9在线观看免费高清完整版 玖玖爱免费视频 | 99精品观看 | 国产高清在线 | 亚洲国产精品久久久 | 国产成人免费精品 | av中文在线影视 | 亚洲综合色网站 | 男女啪啪免费网站 | 免费欧美精品 | a电影在线观看 | 五月花丁香婷婷 | 久久免费视频这里只有精品 | 99麻豆视频 | 日本精品久久久久 | 91麻豆福利 | 一本色道久久综合亚洲二区三区 | 亚洲色图美腿丝袜 | 久久久久伊人 | 国产精品日韩在线观看 | 亚洲尺码电影av久久 | 日韩欧美专区 | 精品一二三四在线 | 国产欧美日韩视频 | 欧美精品久久久久久 | 亚洲精品理论 | 久久成人国产精品入口 | 国产精品一区二区中文字幕 | 日韩在线视频一区 | 亚洲狠狠婷婷综合久久久 | 欧美日韩一区久久 | 97在线影院 | 99久久日韩精品视频免费在线观看 | 色视频网站在线 | 成人免费视频网址 | 91成人免费视频 | 精品毛片在线 | 久久电影中文字幕视频 | 婷婷午夜| 337p日本欧洲亚洲大胆裸体艺术 | 在线播放日韩av | 九九视频一区 | 国产在线精品二区 | 99热这里精品 | 亚洲视频在线免费观看 | 9在线观看免费高清完整版 玖玖爱免费视频 | 国产999在线 | 国产资源网 | 开心激情五月婷婷 | 亚洲精品久久久久久中文传媒 | 91精品亚洲影视在线观看 | 免费在线播放 | av不卡中文 | 97超碰香蕉 | 久久久免费精品国产一区二区 | 久久久久久影视 | 免费日韩精品 | 国产成人一区二区三区 | 欧美日韩裸体免费视频 | 国产成人在线观看 | 久久久久久久久网站 | www看片网站 | 在线电影日韩 | 国产福利精品视频 | 日韩av在线不卡 | 天天躁天天狠天天透 | 国产精品久久中文字幕 | 超碰免费av | 国产精品午夜久久久久久99热 | 亚洲一级久久 | 在线a亚洲视频播放在线观看 | 免费成人看片 | 蜜臀av性久久久久蜜臀aⅴ涩爱 | 91丨九色丨勾搭 |