2010-03-18 97 views
8

我敢肯定這是可能的,但我所有的搜索都是空白的。爪哇鼠標移動屏幕上的任何地方

在Java中,是否可以在Java應用程序之外註冊鼠標移動事件?因此,如果鼠標指針移動到屏幕上的任何位置,我都會收到回電。可以用輪詢MouseInfo.getPointerInfo進行近似,但是必須有更好的方法。

感謝

爲了說明用例: 這只是一個寵物項目,但基本上觸發事件,當鼠標點擊屏幕的邊緣。我也在想,如果你嘗試推過屏幕邊緣,可能會觸發不同的事件。爲此,我認爲鼠標移動偵聽器可能更合適。

+0

我不認爲有更好的辦法。這必須與操作系統無關,我懷疑這很容易實現。但是如果定期輪詢MouseInfo.getPointerInfo方法會出現什麼問題?你的用例是什麼? – Karussell 2010-03-18 11:56:22

回答

11

java.awt.event.MouseMotionListener只會給你提供關於應用程序窗口內鼠標移動的信息。對於在該窗口之外發生的事件,無法繞過MouseInfo.getPointerInfo。然而,你可以寫一個(潛在單)類輪詢定期的指針信息,並允許MouseMotionListeners添加:

import java.awt.Component; 
import java.awt.MouseInfo; 
import java.awt.Point; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionListener; 
import java.util.HashSet; 
import java.util.Set; 

import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

/** 
* This class checks the position every #DELAY milliseconds and 
* informs all registered MouseMotionListeners about position updates. 
*/ 
public class MouseObserver { 
    /* the resolution of the mouse motion */ 
    private static final int DELAY = 10; 

    private Component component; 
    private Timer timer; 
    private Set<MouseMotionListener> mouseMotionListeners; 

    protected MouseObserver(Component component) { 
     if (component == null) { 
      throw new IllegalArgumentException("Null component not allowed."); 
     } 

     this.component = component; 

     /* poll mouse coordinates at the given rate */ 
     timer = new Timer(DELAY, new ActionListener() { 
       private Point lastPoint = MouseInfo.getPointerInfo().getLocation(); 

       /* called every DELAY milliseconds to fetch the 
       * current mouse coordinates */ 
       public synchronized void actionPerformed(ActionEvent e) { 
        Point point = MouseInfo.getPointerInfo().getLocation(); 

        if (!point.equals(lastPoint)) { 
         fireMouseMotionEvent(point); 
        } 

        lastPoint = point; 
       } 
      }); 
     mouseMotionListeners = new HashSet<MouseMotionListener>(); 
    } 

    public Component getComponent() { 
     return component; 
    } 

    public void start() { 
     timer.start(); 
    } 

    public void stop() { 
     timer.stop(); 
    } 

    public void addMouseMotionListener(MouseMotionListener listener) { 
     synchronized (mouseMotionListeners) { 
      mouseMotionListeners.add(listener); 
     } 
    } 

    public void removeMouseMotionListener(MouseMotionListener listener) { 
     synchronized (mouseMotionListeners) { 
      mouseMotionListeners.remove(listener); 
     } 
    } 

    protected void fireMouseMotionEvent(Point point) { 
     synchronized (mouseMotionListeners) { 
      for (final MouseMotionListener listener : mouseMotionListeners) { 
       final MouseEvent event = 
        new MouseEvent(component, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), 
            0, point.x, point.y, 0, false); 

       SwingUtilities.invokeLater(new Runnable() { 
         public void run() { 
          listener.mouseMoved(event); 
         } 
        }); 
      } 
     } 
    } 

    /* Testing the ovserver */ 
    public static void main(String[] args) { 
     JFrame main = new JFrame("dummy..."); 
     main.setSize(100,100); 
     main.setVisible(true); 

     MouseObserver mo = new MouseObserver(main); 
     mo.addMouseMotionListener(new MouseMotionListener() { 
       public void mouseMoved(MouseEvent e) { 
        System.out.println("mouse moved: " + e.getPoint()); 
       } 

       public void mouseDragged(MouseEvent e) { 
        System.out.println("mouse dragged: " + e.getPoint()); 
       } 
      }); 

     mo.start(); 
    } 
} 

當心,有從標準的MouseMotionListener儘管一些顯着的差異:

  • 您將只收到mouseMoved事件,從未mouseDragged事件。這是因爲沒有辦法接收有關主窗口外點擊的信息。
  • 出於類似的原因,每個MouseEventmodifiers將始終爲0
  • 也是一樣的價值觀clickCountpopupTriggerbutton
  • 您需要提供將被用作虛擬java.awt.Component(假)來源MouseEvent s - null值不允許在這裏。