我创建了一个MouseMotionDetection类,该角色只是检测用户是否已将鼠标移动到屏幕上的任何位置.
为此我在我的类构造函数中创建了一个新的JFrame,其屏幕大小是不可见的,所以基本上我在整个屏幕上观察鼠标运动.
但是,我有一个奇怪的错误:
在代码的当前形式中,一旦激活此类,我只检测到一个鼠标移动而没有其他任何东西,它在此之后就会停止工作.但是,如果我将设置帧backfround的行放在注释中的0f,0f,0f(透明)然后激活,整个屏幕变为灰色,我会按照我的需要跟踪所有鼠标动作(我只是可以看不到任何东西.
我真的不明白为什么会发生这种情况,没有看到相关问题,也没有相关的javadoc,which discusses MouseMotion events.
这是代码:
public class MouseMotionDetection extends JPanel implements MouseMotionListener{ public MouseMotionDetection(Region tableRegion,Observer observer){ addMouseMotionListener(this); setBackground(new Color(0f,0f)); JFrame frame = new JFrame(); frame.setUndecorated(true); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); frame.setSize(screenSize); frame.setBackground(new Color(0f,0f)); frame.setDefaultCloSEOperation(JFrame.DISPOSE_ON_CLOSE); frame.setAlwaysOnTop(true); JComponent contentPane = this; contentPane.setOpaque(true); frame.getContentPane().add(contentPane,BorderLayout.CENTER); frame.setVisible(true); } @Override public void mouseDragged(MouseEvent arg0) { } @Override public void mouseMoved(MouseEvent arg0) { System.out.println("mouse movement detected"); }
解决方法
完全透明的框架不会接收鼠标事件.
这是使用MouseInfo的替代方法.这适用于应用程序的组件.是不可见的(透明的),未聚焦的或最小化的.
import java.awt.*; import java.awt.event.*; import java.awt.geom.GeneralPath; import java.awt.image.BufferedImage; import javax.swing.*; import javax.swing.border.EmptyBorder; public class MouseMoveOnScreen { Robot robot; JLabel label; GeneralPath gp; Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); MouseMoveOnScreen() throws AWTException { robot = new Robot(); label = new JLabel(); gp = new GeneralPath(); Point p = MouseInfo.getPointerInfo().getLocation(); gp.moveTo(p.x,p.y); drawLatestMouseMovement(); ActionListener al = new ActionListener() { Point lastPoint; @Override public void actionPerformed(ActionEvent e) { Point p = MouseInfo.getPointerInfo().getLocation(); if (!p.equals(lastPoint)) { gp.lineTo(p.x,p.y); drawLatestMouseMovement(); } lastPoint = p; } }; Timer timer = new Timer(40,al); timer.start(); } public void drawLatestMouseMovement() { BufferedImage biOrig = robot.createScreenCapture( new Rectangle(0,d.width,d.height)); BufferedImage small = new BufferedImage( biOrig.getWidth() / 4,biOrig.getHeight() / 4,BufferedImage.TYPE_INT_RGB); Graphics2D g = small.createGraphics(); g.scale(.25,.25); g.drawImage(biOrig,label); g.setStroke(new BasicStroke(8)); g.setColor(Color.RED); g.draw(gp); g.dispose(); label.setIcon(new ImageIcon(small)); } public JComponent getUI() { return label; } public static void main(String[] args) throws Exception { Runnable r = new Runnable() { @Override public void run() { JPanel ui = new JPanel(new BorderLayout(2,2)); ui.setBorder(new EmptyBorder(4,4,4)); try { MouseMoveOnScreen mmos = new MouseMoveOnScreen(); ui.add(mmos.getUI()); } catch (AWTException ex) { ex.printStackTrace(); } JFrame f = new JFrame("Track Mouse On Screen"); // quick hack to end the frame and timer f.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); f.setContentPane(ui); f.pack(); f.setLocationByPlatform(true); f.setVisible(true); } }; SwingUtilities.invokeLater(r); } }