1. 前言

萌新上班摸鱼的时候玩了玩Swing,想着弄个桌面精灵玩玩,结果一百度发现过气Swing,根本没多少教程,只能东找找,西凑凑,终于拼出了想要的效果。给张效果图:

本质上就是个隐藏了边框的窗口,然后把背景一换,再加点自己喜欢的功能就完成了。

2. 要点讲解

因为没有一个完整的教程,所以做的时候也踩了蛮多坑,这里记录一下以备不时之需,先上一段示例代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;public class TestFrame extends JDialog {/** 主窗口 */public TestFrame(){// 获取图片ImageIcon icon = new ImageIcon(this.getClass().getResource("/pics/bp.png"));Dimension size = new Dimension(icon.getIconWidth(), icon.getIconHeight());setAlwaysOnTop(true);                                    // 窗体置顶setDefaultCloseOperation(this.DISPOSE_ON_CLOSE);     // 窗体关闭策略(关闭后挂起)setSize(size);                                            // 窗体大小和图片一致setUndecorated(true);                                   // 窗体无边框setBackground(new Color(0, 0, 0, 0));       // 窗体背景色为透明(alpha = 0)// 设置背景JLabel background = new JLabel(icon);background.setSize(background.getPreferredSize());JLayeredPane.putLayer(background, Integer.MIN_VALUE);  // 将背景放在最底层getLayeredPane().add(background);// 添加侦听器使窗口可拖动MouseDragAdapter dragAdapter = new MouseDragAdapter();addMouseListener(dragAdapter);addMouseMotionListener(dragAdapter);setVisible(true);}@Overridepublic void dispose() {super.dispose();// 主窗口销毁后直接强退System.exit(0);}/*** 鼠标拖动适配器*/private class MouseDragAdapter extends MouseAdapter {private boolean isDragging;final private Point oldPoint = new Point();@Overridepublic void mousePressed(MouseEvent e) {if (e.getButton() == MouseEvent.BUTTON1) {oldPoint.setLocation(e.getX(), e.getY());isDragging = true;}}@Overridepublic void mouseReleased(MouseEvent e) {if (e.getButton() == MouseEvent.BUTTON1) {isDragging = false;}}@Overridepublic void mouseDragged(MouseEvent e) {if (isDragging) {Component c = e.getComponent();c.setLocation(c.getX() - oldPoint.x + e.getX(), c.getY() - oldPoint.y + e.getY());}}}
}

Swing的基础知识就不拿来水了,这个网上教程还是有的,主要说一些要注意的地方

2.1. 参数配置

     setAlwaysOnTop(true);                                   // 窗体置顶setDefaultCloseOperation(this.DISPOSE_ON_CLOSE);     // 窗体关闭策略(关闭后挂起)setSize(size);                                            // 窗体大小和图片一致setUndecorated(true);                                   // 窗体无边框setBackground(new Color(0, 0, 0, 0));       // 窗体背景色为透明(alpha = 0)

主要是窗体大小,无边框和背景色透明的设置,不然带个框或者灰底也挺丑的。
这里我的TestFrame继承自JDialog,也可以用JFrame,只不过用JDialog就不会显示在任务栏里了,置顶同样,看个人喜好设置。

2.2. 设置背景

     // 设置背景JLabel background = new JLabel(icon);background.setSize(background.getPreferredSize());JLayeredPane.putLayer(background, Integer.MIN_VALUE);    // 将背景放在最底层getLayeredPane().add(background);

把图片放在layeredPane底部作为背景(好像放contentPane也行,但是我自己做的时候老是有bug),注意要通过JLayeredPane.putLayer方法设置index,直接用

     getLayeredPane().add(background, Integer.MIN_VALUE);

是不行的,因为实际不用这个index做层级判断…(翻了老半天源码才找到原因,太坑了)

2.3. 设置拖动

     // 添加侦听器使窗口可拖动MouseDragAdapter dragAdapter = new MouseDragAdapter();addMouseListener(dragAdapter);addMouseMotionListener(dragAdapter);

两种侦听器都需要,mouseListener负责鼠标点击事件,mouseMotionListener负责鼠标拖动事件

 /*** 鼠标拖动适配器*/private class MouseDragAdapter extends MouseAdapter {private boolean isDragging;final private Point oldPoint = new Point();/** 处理鼠标按下 */@Overridepublic void mousePressed(MouseEvent e) {if (e.getButton() == MouseEvent.BUTTON1) {oldPoint.setLocation(e.getX(), e.getY());isDragging = true;}}/** 处理鼠标抬起 */@Overridepublic void mouseReleased(MouseEvent e) {if (e.getButton() == MouseEvent.BUTTON1) {isDragging = false;}}/** 处理鼠标拖动 */@Overridepublic void mouseDragged(MouseEvent e) {if (isDragging) {Component c = e.getComponent();c.setLocation(c.getX() - oldPoint.x + e.getX(), c.getY() - oldPoint.y + e.getY());}}}

拖动的逻辑为:

  • 当鼠标左键按下时,检测按下处的本地坐标并记录,并激活拖动状态(isDragging = true);
  • 当鼠标拖动时,根据鼠标的相对位置变化,移动窗口,由于c.getX()和c.getY()获取的是窗口左上角的全局坐标,而e.getX()和e.getY()获取的是点击时鼠标的本地坐标,所以减去我们之前记录的本地坐标,就能保证相对位置变化都可看做基于窗口左上角拖动(可以尝试不用oldPoint记录坐标,拖动的时候窗口直接飞不见了XD);
  • 鼠标左键抬起时,取消激活拖动状态(isDragging = false).

2.4. 窗口销毁时结束进程

 @Overridepublic void dispose() {super.dispose();// 主窗口销毁后直接强退System.exit(0);}

重载dispose方法,在窗口被销毁时结束进程。有时候组件多了,窗口消失后进程还没关闭,debug也找不到原因,只能听大佬的,直接exit一了百了。

3.结尾

以上都是我从原码中摘出来的感觉比较关键的部分,详细的原码在此
桌面精灵GitHub仓库
写这个玩意的初衷只是想随便写写玩一下,没想到花了大量的时间…资料也查了一堆,还硬着头皮看了原码,好在最后折腾出来了。所以写代码用摸鱼的心态是很难有成果的(当然也许是我太菜了2333)

JAVA8 Swing 简单的桌面精灵(踩坑点记录)相关推荐

  1. storm mysql spout_storm kafkaSpout 踩坑问题记录! offset问题!

    整合kafka和storm例子网上很多,自行查找 问题描述: kafka是之前早就搭建好的,新建的storm集群要消费kafka的主题,由于kafka中已经记录了很多消息,storm消费时从最开始消费 ...

  2. Jetson Nano配置踩坑全记录

    Jetson Nano配置踩坑全记录 Jetson Nano相关参数:JetPack 4.6,cuda 10.2, SD卡内存:512G 一.Jetson Nano系统镜像烧录 在Nvidia官网下载 ...

  3. vue在微信里面的兼容问题_详解Vue微信公众号开发踩坑全记录

    本文介绍了Vue微信公众号开发踩坑全记录,分享给大家,也给自己留个笔记. 需求 微信授权登录(基于公众号的登录方案) 接入JS-SDK实现图片上传,分享等功能 现状及难点 采用的Vue框架,前后端分 ...

  4. 容器化部署(k8s)任务调度平台xxl-job(部署过程及踩坑问题记录)

    文章预览: 1 部署过程(下方ip代表服务器的ip哈) 1.1 制作服务打包镜像DockerFile 1.2 制作执行脚本run.sh 1.3 jar包上上传 1.4 kuboard创建----配置信 ...

  5. linux ubuntu安装pytorch(深度学习环境搭建记录,无sudo权限)踩坑全记录

    一些牢骚:深度学习没怎么学习几次,搭建环境已经把我搞秃了哈哈哈. 之前在网上找到的搭建环境的步骤,我没有root权限,很多操作都不行(比如运行.run文件,cuda 和cudnn的安装和修改也需要ro ...

  6. HyperLPR 开源车牌识别系统搭建踩坑全记录

    (介绍略) 一个开源的车牌识别系统. github地址:https://github.com/szad670401/HyperLPR 一.下载 git clone https://github.com ...

  7. 关于C++ Qt项目实现最简单Http Server的踩坑记录

    前言 在开发Qt项目中,需要实现一个Http服务器功能,接收并处理客户端的http请求,Qt的发行版中并没有提供相应的类来处理,所以要实现该功能只能找其他开源项目了,本文主要记录我在收集相关资料过程中 ...

  8. letex(winedit)公式和正文的间距,超级简单(以后别踩坑)

    有三种常用的方法,别人写过的,感谢 LaTeX_Fun 原站参考http://blog.sina.com.cn/s/blog_5e16f1770100mirv.html 用法,放在各种公式命令的适当位 ...

  9. 菜鸟的Django+MongoDB搭建简单爬虫显示网站踩坑心得

    本文基于<Django企业开发实战>一书和网络资料,拼拼凑凑,做了简单的网站实现,大致把前后端+数据库方面的内容结合爬虫代码做通了.不得不说,Django和MongoDB是真的不搭配,强烈 ...

  10. Vxe Table一些简单的应用和踩坑记录

    iView本身的Table在不分页数据量稍微大一点的时候,会使整个页面操作起来特别卡顿,其实element也有这个问题. 故采用vxe-table 文章目录 1. 环境 2. 自定义列排序 3. 使用 ...

最新文章

  1. 动态修改页面Meta 标签 keywords description
  2. Ubuntu12.04设置软件源
  3. JAVA只要掌握内部类,多继承和单继承都不是问题
  4. https传输基于多ip实现的网站数据传输
  5. python删除文件_python删除指定类型(或非指定)的文件实例详解
  6. chrome无法打开某些网页,但safari可以
  7. 数位DP算法概述及习题
  8. 三种数据流分析的方程、用途
  9. 周纪二 周显王元年(癸丑,公元前368年)——摘要
  10. 轻微课靠不靠谱,我的60天体验可以说说
  11. 大学数据库创建与查询实战
  12. 创意电子学-小知识:研究继电器
  13. 淘宝聚划算怎么做?大神导航,一个神奇的网站从此开启大神之路
  14. pycharm使用记录
  15. 成都玖益科技:店铺流量怎么提升
  16. Huffman图像压缩
  17. 隐藏在摄像头里的AI
  18. 视频处理软件有那些,优缺点介绍
  19. android:使用Gon解析解析json
  20. Linux 4.15 rc7,深度操作系统 15.4 RC更新详情

热门文章

  1. quartz提示This scheduler instance is still active but was recovered by another instance in the cluster
  2. TopCoder SRM 677 Div2
  3. 多普勒效应的原理及应用 一 多普勒现象的发现
  4. GitHub中国区前100名到底是什么样的人?向大佬们学习。
  5. JS实现图片不存在时显示默认图片
  6. oracle 19c em,Oracle 19C EM
  7. WebStorm2016.1.1免注册破解方法
  8. 二进制数的反码和补码
  9. 如何给服务器IIS配置文件夹配置everyone权限
  10. 网络共享计算机权限访问,局域网共享时提示:你没有权限访问,请与网络管理员联系...