日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA8 Swing 简单的桌面精灵(踩坑点记录) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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 简单的桌面精灵(踩坑点记录)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。