首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 即時獲取滑鼠螢幕座標工具:MouseInfo + Swing 透視窗口實現

     編輯:Java 相關知識

Java AWT 提供 MouseInfo.getPointerInfo().getLocation() 即可獲取全螢幕滑鼠座標。本文構建一個置頂、無邊框、半透明、即時刷新的 Swing 小工具,展示 MouseInfo、TimerTask 定時輪詢、JDialog 視窗屬性設定的完整代碼,並討論跨螢幕、高 DPI、權限等實務考量。

核心 API

// 靜態方法,無需實例化
PointerInfo pi = MouseInfo.getPointerInfo();
if (pi != null) {
  Point pt = pi.getLocation(); // x, y 為螢幕絕對座標
  System.out.println("X=" + pt.x + ", Y=" + pt.y);
}

完整工具代碼

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Timer;
import java.util.TimerTask;

public class MouseLocator extends JDialog {
  private final JLabel lblX = new JLabel("X: 0");
  private final JLabel lblY = new JLabel("Y: 0");
  private final Timer timer = new Timer("MouseLocator", true); // daemon

  public MouseLocator() {
    // 1. 視窗屬性:無邊框、置頂、半透明、不進任務欄
    setUndecorated(true);
    setAlwaysOnTop(true);
    setType(Type.UTILITY); // 不顯示在任務欄
    setBackground(new Color(0, 0, 0, 0)); // 支援半透明
    setLayout(new BorderLayout(5, 5));
    
    // 2. 內容面板:半透明背景 + 文字
    JPanel panel = new JPanel(new GridLayout(2, 2, 5, 5)) {
      @Override protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setColor(new Color(0, 0, 0, 180));
        g2.fillRoundRect(0, 0, getWidth(), getHeight(), 10, 10);
        g2.dispose();
      }
    };
    panel.setOpaque(false);
    panel.setBorder(BorderFactory.createEmptyBorder(10, 15, 10, 15));
    
    Font font = new Font("微軟正黑體", Font.BOLD, 18);
    lblX.setFont(font); lblX.setForeground(Color.WHITE);
    lblY.setFont(font); lblY.setForeground(Color.WHITE);
    panel.add(new JLabel("X:")); panel.add(lblX);
    panel.add(new JLabel("Y:")); panel.add(lblY);
    add(panel, BorderLayout.CENTER);
    
    // 3. 拖拽移動 (無邊框需自行實現)
    panel.addMouseListener(new MouseAdapter() {
      Point dragStart;
      public void mousePressed(MouseEvent e) { dragStart = e.getPoint(); }
      public void mouseReleased(MouseEvent e) { dragStart = null; }
    });
    panel.addMouseMotionListener(new MouseMotionAdapter() {
      Point dragStart;
      public void mouseDragged(MouseEvent e) {
        if (dragStart != null) {
          Point loc = getLocation();
          setLocation(loc.x + e.getX() - dragStart.x, 
                      loc.y + e.getY() - dragStart.y);
        }
      }
    });
    
    // 4. 關閉鍵:ESC
    getRootPane().registerKeyboardAction(e -> dispose(),
        KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
    
    pack();
    setLocation(100, 100);
    setVisible(true);
    
    // 5. 定時輪詢 (100ms = 10fps)
    timer.scheduleAtFixedRate(new TimerTask() {
      public void run() {
        PointerInfo pi = MouseInfo.getPointerInfo();
        if (pi != null) {
          Point pt = pi.getLocation();
          SwingUtilities.invokeLater(() -> {
            lblX.setText("X: " + pt.x);
            lblY.setText("Y: " + pt.y);
          });
        }
      }
    }, 0, 100);
  }

  public static void main(String[] args) {
    // 啟用系統外觀 (可選)
    try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ignored) {}
    SwingUtilities.invokeLater(MouseLocator::new);
  }
}

關鍵實作細節

需求實現方式
置頂不被遮蓋setAlwaysOnTop(true)
不佔用任務欄/Alt+TabsetType(Type.UTILITY) (Java 7+)
半透明圓角背景setUndecorated(true) + setBackground(new Color(0,0,0,0)) + 覆寫 paintComponent
拖拽移動滑鼠事件計算偏移 setLocation
ESC 關閉registerKeyboardAction + KeyStroke(VK_ESCAPE)
定時器不阻塞退出new Timer(name, true) daemon 執行緒
UI 更新線程安全SwingUtilities.invokeLater

進階考量與避坑

  1. 多螢幕座標系:getLocation() 返回虛擬螢幕絕對座標 (主螢幕左上為 0,0),副螢幕在左/上方時座標為負數,正常。
  2. 高 DPI 縮放:Windows 縮放 150% 時,AWT 返回邏輯像素,若需物理像素須乘以縮放比 (Java 9+ GraphicsDevice.getDisplayMode() 可查)。
  3. 權限限制:Linux Wayland / macOS 安全性策略可能阻擋全域滑鼠座標讀取,需授予「輔助使用」權限或簽名打包。
  4. 效能:100ms 輪詢 CPU 佔用極低 (<1%),若需更平滑可改 50ms (20fps) 或用 Native Hook (JNativeHook) 事件驅動。
  5. 關閉資源:視窗關閉時 timer.cancel(),避免 daemon 執行緒殘留 (雖 daemon 隨 JVM 結束自動回收)。

擴展想法

  • 加入顏色拾取器:Robot.getPixelColor(x, y) 顯示滑鼠下像素 RGB/HEX。
  • 座標複製:雙擊文字自動複製到剪貼簿。
  • 多螢幕標註:顯示當前所在螢幕索引、解析度、縮放比。
  • 打包分發:jpackage 生成原生安裝包 (exe/dmg/deb),含 JRE、圖標、檔案關聯。

總結

MouseInfo.getPointerInfo().getLocation() 是 Java 獲取全域滑鼠座標的標準 API。結合 JDialog 無邊框置頂視窗、Timer 定時輪詢、SwingUtilities.invokeLater 線程安全更新,即可構建專業級座標拾取小工具。注意高 DPI 縮放、Wayland/macOS 權限、多螢幕負座標三大實務坑點,並善用 jpackage 打包分發,即得開箱即用的開發輔助工具。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved