2010-03-18 81 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值不允许在这里。