用Java Swing实现QQ聊天界面
文章内容概要
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提交记录