I have searched for a while on the internet but I didn't find any solution for my problem. I know that you can get the current mouse position with
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
The problem is in a multi environment screen I am just getting the mouse position relative to the main screen. Which means if the second screen is to the left of the main screen I receive for example X: -917.0 Location Y: -137.0. I know that these values depend on the screen resolution and the order of the monitors. Is there any possibility to obtain the mouse position on the current active screen?
Kind regards
Basically, what I did was take the PointerInfo
and subtract the GraphicsDevice
bounds from it, if the result was less the 0
(because the screen was left of the main screen), I multiplied the result by -1
The heart of the solution looks like this...
// Pointer info
PointerInfo pi = MouseInfo.getPointerInfo();
Point mp = pi.getLocation();
// The devices bounds
Rectangle bounds = getDeviceBounds(pi.getDevice());
// Create new "virtual" point based on the mouse point
virtualPoint = new Point(mp);
// Subtract the x/y position of the device
virtualPoint.x -= bounds.x;
virtualPoint.y -= bounds.y;
// Clip negative values...
if (virtualPoint.x < 0) {
virtualPoint.x *= -1;
}
if (virtualPoint.y < 0) {
virtualPoint.y *= -1;
}
The following example shows the actual desktop mouse position (as reported by MouseInfo
) on the first line and the second line shows the "screen" position within the context of the GraphicsDevice
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class WheresMyMouse {
public static void main(String[] args) {
new WheresMyMouse();
}
public WheresMyMouse() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private double scale;
private List<Rectangle> screenBounds;
private Point virtualPoint;
private Point screenPoint;
public TestPane() {
screenBounds = getScreenBounds();
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
PointerInfo pi = MouseInfo.getPointerInfo();
Point mp = pi.getLocation();
Rectangle bounds = getDeviceBounds(pi.getDevice());
screenPoint = new Point(mp);
virtualPoint = new Point(mp);
virtualPoint.x -= bounds.x;
virtualPoint.y -= bounds.y;
if (virtualPoint.x < 0) {
virtualPoint.x *= -1;
}
if (virtualPoint.y < 0) {
virtualPoint.y *= -1;
}
repaint();
}
});
timer.start();
}
@Override
public void invalidate() {
super.invalidate();
Rectangle virtualBounds = getVirtualBounds();
scale = getScaleFactorToFit(virtualBounds.getSize(), getSize());
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int xOffset = 0;
int yOffset = 0;
List<Rectangle> scaledBounds = new ArrayList<>(screenBounds.size());
for (Rectangle bounds : screenBounds) {
bounds = scale(bounds);
scaledBounds.add(bounds);
if (bounds.x < xOffset) {
xOffset = bounds.x;
}
if (bounds.y < yOffset) {
yOffset = bounds.y;
}
}
if (xOffset < 0) {
xOffset *= -1;
}
if (yOffset < 0) {
yOffset *= -1;
}
for (Rectangle bounds : scaledBounds) {
bounds.x += xOffset;
bounds.y += xOffset;
g2d.setColor(Color.DARK_GRAY);
g2d.fill(bounds);
g2d.setColor(Color.GRAY);
g2d.draw(bounds);
}
FontMetrics fm = g2d.getFontMetrics();
g2d.setColor(Color.WHITE);
if (screenPoint != null) {
int x = 0;
int y = fm.getAscent();
g2d.drawString(screenPoint.toString(), x, y);
screenPoint.x += xOffset;
screenPoint.y += yOffset;
screenPoint.x *= scale;
screenPoint.y *= scale;
g2d.fillOval(screenPoint.x - 2, screenPoint.y - 2, 4, 4);
}
if (virtualPoint != null) {
int x = 0;
int y = fm.getAscent() + fm.getHeight();
g2d.drawString(virtualPoint.toString(), x, y);
}
g2d.dispose();
}
protected Rectangle scale(Rectangle bounds) {
Rectangle scaled = new Rectangle(bounds);
scaled.x *= scale;
scaled.y *= scale;
scaled.width *= scale;
scaled.height *= scale;
return scaled;
}
}
public static Rectangle getScreenBoundsAt(Point pos) {
GraphicsDevice gd = getGraphicsDeviceAt(pos);
Rectangle bounds = null;
if (gd != null) {
bounds = gd.getDefaultConfiguration().getBounds();
}
return bounds;
}
public List<Rectangle> getScreenBounds() {
List<Rectangle> bounds = new ArrayList<>(25);
GraphicsDevice device = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lstGDs[] = ge.getScreenDevices();
ArrayList<GraphicsDevice> lstDevices = new ArrayList<GraphicsDevice>(lstGDs.length);
for (GraphicsDevice gd : lstGDs) {
GraphicsConfiguration gc = gd.getDefaultConfiguration();
Rectangle screenBounds = gc.getBounds();
bounds.add(screenBounds);
}
return bounds;
}
public static Rectangle getDeviceBounds(GraphicsDevice device) {
GraphicsConfiguration gc = device.getDefaultConfiguration();
Rectangle bounds = gc.getBounds();
return bounds;
}
public static GraphicsDevice getGraphicsDeviceAt(Point pos) {
GraphicsDevice device = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lstGDs[] = ge.getScreenDevices();
ArrayList<GraphicsDevice> lstDevices = new ArrayList<GraphicsDevice>(lstGDs.length);
for (GraphicsDevice gd : lstGDs) {
Rectangle screenBounds = getDeviceBounds(gd);
if (screenBounds.contains(pos)) {
lstDevices.add(gd);
}
}
if (lstDevices.size() == 1) {
device = lstDevices.get(0);
}
return device;
}
public static Rectangle getVirtualBounds() {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lstGDs[] = ge.getScreenDevices();
for (GraphicsDevice gd : lstGDs) {
bounds.add(getDeviceBounds(gd));
}
return bounds;
}
public static double getScaleFactor(int iMasterSize, int iTargetSize) {
double dScale = 1;
dScale = (double) iTargetSize / (double) iMasterSize;
return dScale;
}
public static double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With