用Java Swing實現QQ聊天界面
先附上團隊博客鏈接
https://www.cnblogs.com/haijie-wrangler/p/12169314.html Day4(總結篇)
https://www.cnblogs.com/haijie-wrangler/p/12169146.html Day3
https://www.cnblogs.com/haijie-wrangler/p/12169272.html Day2
https://www.cnblogs.com/haijie-wrangler/p/12165487.html Day1
個人博客
https://www.cnblogs.com/cxxxxxx/p/12121836.html
文章內容概要
1.代碼過程中遇到的問題以及如何解決 |
---|
2.團隊項目中負責的功能展示 |
3.尚未完成的功能,今后的改進和總結 |
4.gitee的提交記錄 |
-
編寫Gui過程中遇到的問題
對JavaSwing布局管理器的總結
1.在控件有布局管理器的情況下,控件是無法通過setSize來控制大小的,只有當setLayout(null)的時候setSize,setLocation,setBounds方法才有實際用處 2.setPreferredSize可在有布局管理器的時生效,布局管理器會獲取空間的preferredsize,因而可以生效 3.使用布局管理器會有很多局限性,許多控件的位置不能夠正確的擺放,尤其是當有嵌套控件時如(JTextArea里插入圖片,JScrollPane插入JTextArea)等情況時,布局管理器的作用會變得很雞肋 4.使用setBounds方法可以將控件根據x,y直接插入JFrame中,同時也可以直接控件的大小,這個方法使布置控件更加靈活
對JavaSwing頁面優化的理解
Swing屬於比較老的工具集,生成的頁面布局不好看。我嘗試了很多的方法只能做到頁面簡潔,遠遠達不到美觀。 我看到比較好的優化就是重寫所有鼠標類函數,這樣做的好處是可以用JTextArea來替代Button控件,重寫鼠標懸停等函數可以使頁面看起來更加生動
下面具體演示一下優化的代碼
public void mouseDragged(MouseEvent e) {//重寫窗口拖動函數 Point p = getLocation(); setLocation(p.x + e.getX() - origin.x, p.y + e.getY()- origin.y); } });
user.addFocusListener(new FocusListener() {//重寫鼠標焦點函數 public void focusLost(FocusEvent e) {//失去焦點 } public void focusGained(FocusEvent e) {//得到焦點 }); public void mousePressed(MouseEvent e){//重寫鼠標點擊函數 }
對於前后端交替問題的體會
此次Gui圖形界面一個較難的問題就是前后端代碼的交替,前端的QQ聊天界面要做到對信息的實時更新,與信息來時的按鈕提醒。這兩個功能的實現花費了很多的時間精力,下面對這兩個問題詳細講解
實現對信息顯示的實時更新
實時更新信息分為 1.顯示離線消息 2.顯示在線消息 3.顯示聊天記錄 三個功能實現的方法大致相同 ########################## 1.顯示離線消息############################ public static void returnOfflineMessage(ArrayList<OfflineMessage> offlineMessages) { for (OfflineMessage o : offlineMessages) { if (hashMap.containsKey(o.getSender())) { hashMap.get(o.getSender()).add(o); } else { ArrayList<Message> messageArrayList = new ArrayList<>(); messageArrayList.add(o); hashMap.put(o.getSender(), messageArrayList); } } } 在上線前,先將所有獲得的信息用HashMap存儲,key為發送者,value為ArrayList<Message> public static void setButton() { for (int i = 0; i < userItem.size(); i++) {//將用戶創建button if (!userItem.get(i).getUserName().equals(sender)) { JToggleButton jToggleButton = new JToggleButton(userItem.get(i).getUserName()); jToggleButtons.add(jToggleButton); int finalI1 = i; jToggleButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { jEditorPane.setText(""); receivingEnd = userItem.get(finalI1).getUserName(); for (int i = 0; i < jToggleButtons.size(); i++) {//點擊按鈕后,把按鈕顏色變為無 if (userItem.get(finalI1).getUserName().equals(jToggleButtons.get(i).getText())) { jToggleButtons.get(i).setBackground(null); } } if (hashMap.containsKey(receivingEnd)) { for (Message M : hashMap.get(receivingEnd)) { if(M.getSender().equals(sender)){ jEditorPane.append("我" + " :" + M.getMessage() + "(" + M.getTime() + ")" + "\n"); }else { jEditorPane.append(M.getSender() + " :" + M.getMessage() + "(" + M.getTime() + ")" + "\n"); } } } } }); userListjPanel.add(jToggleButton); group.add(jToggleButton); jToggleButton.setPreferredSize(new Dimension(10, 10)); } } } 從控制台獲取UserIteam,並且以UserIteam的UserName動態創建button,這里button的使用了jToggleButton類型,並且運用了ButtonGroup的功能, 這樣可以保證一個按鈕有點下和沒點下兩種狀態,並且每次只有一個Button能被點下。在點擊Button后,令receivingEnd= userItem.get(finalI1).getUserNam 這里對receivingEnd的賦值,就確定了哪個用戶被點擊,為顯示信息做標識,接下來就對hashmap做遍歷,輸出所有發出者為該按鈕的信息 ############################2.顯示在線消息############################ public static void returnOnlineMessage(OnlineMessage onlineMessage) { if(onlineMessage.getSender().equals(receivingEnd)){ //打印到屏幕 jEditorPane.append(onlineMessage.getSender() + " :" + onlineMessage.getMessage() + "(" + onlineMessage.getTime() + ")" + "\n"); }else{ //沒點的button改變顏色 changeButton(onlineMessage); } if(hashMap.containsKey(onlineMessage.getSender())){ hashMap.get(onlineMessage.getSender()).add(onlineMessage); }else{ ArrayList<Message> tempList = new ArrayList<>(); tempList.add(onlineMessage); hashMap.put(onlineMessage.getSender(),tempList); } } 每次有信息來,把信息加入到hashmap,然后判斷發送者是否是該按鈕,是就打印該信息 ############################ 3.顯示聊天記錄########################## public static void returnHistoryList(ArrayList<HistoryMessage> list){ hashMap.clear(); for (Message m:list) { if(m.getSender().equals(sender)){ if(hashMap.containsKey(m.getReceivingEnd())){ hashMap.get(m.getReceivingEnd()).add(m); }else{ ArrayList<Message> tempList = new ArrayList<>(); tempList.add(m); hashMap.put(m.getReceivingEnd(),tempList); } }else{ if(hashMap.containsKey(m.getSender())){ hashMap.get(m.getSender()).add(m); }else{ ArrayList<Message> tempList = new ArrayList<>(); tempList.add(m); hashMap.put(m.getSender(),tempList); } } } jEditorPane.setText(""); if(receivingEnd!=null){ for (Message M : hashMap.get(receivingEnd)) { if(M.getSender().equals(sender)){ jEditorPane.append("我" + " :" + M.getMessage() + "(" + M.getTime() + ")" + "\n"); }else { jEditorPane.append(M.getSender() + " :" + M.getMessage() + "(" + M.getTime() + ")" + "\n"); } } } } 將HashMap清空,重新從后台獲取所有歷史消息,並且輸出
信息來時的按鈕提醒
1. public static void changeButton(Message message) { /**根據信息改變Button的顏色 * */ String username = message.getSender(); for (int i = 0; i < jToggleButtons.size(); i++) { if (username.equals(jToggleButtons.get(i).getText())) { jToggleButtons.get(i).setBackground(Color.RED); } } } 登陸時,如果該用戶存有信息,則改變該用戶的button的顏色 2. public static void returnOnlineMessage(OnlineMessage onlineMessage) { if(onlineMessage.getSender().equals(receivingEnd)){ //打印到屏幕 jEditorPane.append(onlineMessage.getSender() + " :" + onlineMessage.getMessage() + "(" + onlineMessage.getTime() + ")" + "\n"); }else{ //沒點的button改變顏色 changeButton(onlineMessage); } if(hashMap.containsKey(onlineMessage.getSender())){ hashMap.get(onlineMessage.getSender()).add(onlineMessage); }else{ ArrayList<Message> tempList = new ArrayList<>(); tempList.add(onlineMessage); hashMap.put(onlineMessage.getSender(),tempList); } } 當有信息來時,如果點的這個Button不是發來信息的用戶,則把Button變紅色
2.功能演示
-
登陸界面
-
注冊界面
-
聊天窗口
-
發送文件
3.尚未完成的功能
1.自行添加用戶進行群聊(由於時間的問題UI沒來得及制作) 2.注冊和聊天界面沒得及重寫函數優化 3.添加表情功能
需要改進和總結
1.第一次嘗試合作寫代碼,前后端對接方面很不熟練,導致代碼進度很慢,需要的方法寫了又改寫了又改浪費時間。 2.圖形界面的代碼是基於服務器之上的,信息顯示的功能很難調試,沒有辦法單獨運行調試 3.這次我的圖形界面做的很簡陋,只是實現了基本功能,沒有做到界面美觀,只有登陸的界面參考了別人的重寫代碼才有一點能看 4.今后學習Java的過程,應該多嘗試合作編程,做好代碼規范,寫類應該先想好要寫的方法再進行補充,不能東添西加導致代碼可讀性很差 5.代碼還是要多敲,編程語言這方面做題集和實際敲項目還是有很大區別的,通過這次課設讓我感受最深的還是敲代碼的速度慢一點點的邏輯代碼就要想很久
4.gitee提交記錄
-