您现在的位置是:网站首页 > 代码编程 > JAVA开发JAVA开发
【原】SwingQQ消息来了好友头像闪动
不忘初心 2017-12-18 围观() 评论() 点赞() 【JAVA开发】
简介:在使用QQ的时候,当有人给我们发消息,好友列表里面,他(她)的头像就会开始闪烁,如果收起了分组,那么好友分组又会开始闪烁,这个功能非常的强大,也非常的实用和人性化,能够第一时间通知用户,极大的提升了用户体验。之前在iteye上发表的SwingQQ项目中已经有这个功能了,但是杂糅在了一起,看起来不太方便,今天来单独就这个功能写一篇文章,方便大家更清晰的学习如何实现这个功能,来几张效果图看看:上图中,
在使用QQ的时候,当有人给我们发消息,好友列表里面,他(她)的头像就会开始闪烁,如果收起了分组,那么好友分组又会开始闪烁,这个功能非常的强大,也非常的实用和人性化,能够第一时间通知用户,极大的提升了用户体验。
之前在iteye上发表的SwingQQ项目中已经有这个功能了,但是杂糅在了一起,看起来不太方便,今天来单独就这个功能写一篇文章,方便大家更清晰的学习如何实现这个功能,来几张效果图看看:
上图中,是展开状态下,我点击消息来啦的按钮之后,好友1-1的头像就会开始来回闪动,向右偏移了1个单位,看起来不太明显,大家以那个企鹅的眼睛来做对比,就会发现还是有点儿偏差的。
上面这是一张收缩状态下的效果图,间隔半秒钟闪烁一次,就是空和名字轮流着显示。
而当我点击别闪了按钮的时候,则会立即停止闪动,并还原到最初状态,相当于我们在QQ上打开了这个好友的对话框。
好了,效果图就放到这里了,大家待会儿自己运行代码看效果,毕竟还是动态的才会有感觉。
实现起来并不是很难,就是不断的切换显示,再加上线程的sleep来一个停顿的效果,就可以实现闪烁的效果了
package com.wolffy.frame;
import com.wolffy.node.BuddyTreeNode;
import com.wolffy.node.GroupTreeNode;
import com.wolffy.ui.MyTreeUI;
import com.wolffy.util.ImgUtils;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.WindowConstants;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* Created by SongFei on 2017/12/18.
*/
public class FlashFrame extends JFrame {
private JPanel jPanel;
private JTree jTree;
private JButton jButton1;
private JButton jButton2;
private DefaultMutableTreeNode root;
private DefaultTreeModel model;
// 定义两个变量,记录第一个分组和第一个好友节点,因为是案例,所以就写死这两个
private GroupTreeNode groupTreeNode;
private BuddyTreeNode buddyTreeNode;
public FlashFrame() {
initGUI();
}
private void initGUI() {
setSize(700, 375);
//setUndecorated(true);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
jPanel = new JPanel();
getContentPane().add(jPanel, BorderLayout.CENTER);
root = new DefaultMutableTreeNode();
model = new DefaultTreeModel(root);
for (int i = 1; i <= 3; i++) {
GroupTreeNode cate = new GroupTreeNode(ImgUtils.getIcon("arrow_left.png"), "我的分组" + i);
if (i == 1) {
groupTreeNode = cate;
oldName = cate.getNameLabel().getText();
}
for (int j = 1; j <= 3; j++) {
BuddyTreeNode node = new BuddyTreeNode(ImgUtils.getIcon("avatar.png"), "好友" + i + "-" + j, "人生若只如初见");
if (i == 1 && j == 1) {
buddyTreeNode = node;
}
cate.add(node);
}
root.add(cate);
}
jTree = new JTree(model);
jTree.setUI(new MyTreeUI());
jPanel.add(jTree);
jButton1 = new JButton("消息来啦");
jPanel.add(jButton1);
jButton1.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (!isFlashing) {
new FlashThread().start();
isContinue = true;
isFlashing = true;
}
}
});
jButton2 = new JButton("别闪了");
jPanel.add(jButton2);
jButton2.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
isContinue = false;
isFlashing = false;
if (jTree.isExpanded(new TreePath(groupTreeNode.getPath()))) {
buddyTreeNode.getIconLabel().setBounds(8, 4, 42, 42);
} else {
groupTreeNode.getNameLabel().setText(oldName);
}
}
});
}
/**
* 是否继续运行线程,因为要实现消息通知的效果,所以就必须循环监听,要给它一个退出的机会
*/
private boolean isContinue = true;
/**
* 在点击取消闪烁的时候,不一定刚好把名字闪回去,所以记录一下,点击的时候强行还原回去
*/
private String oldName;
/**
* 是否已经在闪烁,防止重复点击启动了多个线程,这样会越闪越快,24K钛合金的眼睛都不够用
*/
private boolean isFlashing;
/**
* 闪烁的线程,必须另开线程,不然会导致主进程卡死
*/
class FlashThread extends Thread {
@Override
public void run() {
try {
// 通过一个标记来控制是否继续这个线程
while (isContinue) {
// 没展开分组时,闪烁的就是分组名称,在设置为空和名字之间来回切换
// 展开了分组时,闪烁的就是好友头像,动态切换头像区域的坐标
if (jTree.isExpanded(new TreePath(groupTreeNode.getPath()))) {
buddyTreeNode.getIconLabel().setBounds(9, 5, 42, 42);
Thread.sleep(500);
model.reload(buddyTreeNode);// 这一步很关键,起到刷新的作用,否则必须点一下才有效果
buddyTreeNode.getIconLabel().setBounds(8, 4, 42, 42);
Thread.sleep(500);
model.reload(buddyTreeNode);
} else {
groupTreeNode.getNameLabel().setText("");
Thread.sleep(500);
model.reload(groupTreeNode);
groupTreeNode.getNameLabel().setText(oldName);
Thread.sleep(500);
model.reload(groupTreeNode);
}
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
public static void main(String[] args) {
FlashFrame flashFrame = new FlashFrame();
flashFrame.setVisible(true);
flashFrame.setLocationRelativeTo(null);
}
}
为了方便,代码就放到一起了,大家可以copy过去直接运行就可以看到效果,间隔时间和头像闪烁的偏移量,大家都可以根据自己的需要来设置。
需要注意的地方就是一定要另起一个线程,否则会导致主进程卡死,好了,这里就不再多说了,其他需要注意的地方,我已经在代码中都写了注释了!
看完文章,有任何疑问,请加入群聊一起交流!!!
很赞哦! ()
上一篇:什么是高质量的内容
下一篇:SwingQQ窗体抖动效果
相关文章
- IntelliJ IDEA 2024.2发布之后强推新UI,如何恢复老的经典UI界面
- Uninstall hasn't detected folder of intelli] lDEA installation. Probablyuninstall.exe was moved from the installation folder.
- 公众号CPS变现新宠:微赚淘客查券返利机器人,开启智能省钱赚钱新时代
- 高返利优惠券公众号推荐
- 返利公众号可信吗安全吗?返利机器人哪个佣金高?
- 唯品会购物返利公众号大揭秘:哪些真正好用的返利公众号?
- 饿了么优惠券免费领取:哪些公众号值得推荐?
- 哪些有用可靠的微信公众号能领淘宝优惠券?
- 微信返利最高的微信号推荐——让你的购物更加实惠!
- 微信返利最高的微信号推荐
标签云
猜你喜欢
- IntelliJ IDEA 2019.2已经可以利用补丁永久破解激活了
- IntelliJ IDEA 2019.3利用补丁永久破解激活教程
- IntelliJ IDEA高版本最灵活的永久破解激活方法(含插件激活,时长你说了算)
- Jetbrains全家桶基于ja-netfilter的最新破解激活详细图文教程
- IntelliJ IDEA 2022.1永久破解激活教程(亲测可用,持续更新)
- 分享几个正版 IntelliJ IDEA 激活码(破解码、注册码),亲测可用,持续更新
- ja-netfilter到底需不需要mymap,2021.3.2版本激活失效?
- 如何激活idea2022.1及以上版本中的插件(亲测可用)
- 【史上最全】IntelliJ IDEA最新2022.1版本安装和激活视频教学(含插件)
- IntelliJ IDEA 2022.2 版本最新2099年永久激活方法,亲测可用,也可以开启新UI了。
站点信息
- 网站程序:spring + freemarker
- 主题模板:《今夕何夕》
- 文章统计:篇文章
- 标签管理:标签云
- 微信公众号:扫描二维码,关注我们