Mouse movement detection on screen

I created the MouseMotionDetection class, whose role is to detect that the user moves the mouse anywhere on the screen.

To this end, I created a new JFrame inside my class constructor with a screen size that is invisible, so basically I observe the movement of the mouse around the screen.

But I have a strange error:

In the current code form, as soon as this class is activated, I detect only one mouse movement and nothing else, after that it stops working. But, if I put a line that sets the back focus of the frame to 0f, 0f, 0f, 0f (transparent) in the comments and then activates, the entire screen turns gray and I continue to track all mouse movements the same way I wanted (I just may i see nothing).

I really don't understand why this is happening, have not seen the problems associated with this, nor in this related javadoc, which discusses MouseMotion events.

This is the code:

public class MouseMotionDetection extends JPanel implements MouseMotionListener{ public MouseMotionDetection(Region tableRegion, Observer observer){ addMouseMotionListener(this); setBackground(new Color(0f,0f,0f,0f)); JFrame frame = new JFrame(); frame.setUndecorated(true); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); frame.setSize(screenSize); frame.setBackground(new Color(0f,0f,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"); } 
+6
source share
2 answers

A fully transparent frame does not accept mouse events.

Here is an alternative using MouseInfo . This works if application components. invisible (transparent), not focused or minimized.

enter image description here

 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(px, py); drawLatestMouseMovement(); ActionListener al = new ActionListener() { Point lastPoint; @Override public void actionPerformed(ActionEvent e) { Point p = MouseInfo.getPointerInfo().getLocation(); if (!p.equals(lastPoint)) { gp.lineTo(px, py); drawLatestMouseMovement(); } lastPoint = p; } }; Timer timer = new Timer(40, al); timer.start(); } public void drawLatestMouseMovement() { BufferedImage biOrig = robot.createScreenCapture( new Rectangle(0, 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, 0, 0, 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, 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); } } 
+9
source

I believe that MouseEvents are not generated for transparent pixels. That is, MouseEvent is sent to the "visible" component under the frame.

So, to get an event, you cannot use absolute transparency. But you can get away from using the alpha value 1. I doubt that you will notice the difference in the picture of the "transparent frame".

Therefore, I would use the following code:

 //frame.setBackground(new Color(0f,0f,0f,0f)); frame.setBackground(new Color(0f, 0f, 0f, 1f)); 

The following is not required because you set the transparency to β€œcontentPane” when adding it to the frame:

 //setBackground(new Color(0f,0f,0f,0f)); 

It should be noted that this code will only work when your application is concentrated.

+3
source

Source: https://habr.com/ru/post/974258/


All Articles