首页 文章

Java在多个监视器环境中获取鼠标位置

提问于
浏览
3

我在互联网上搜索了一段时间,但我找不到任何解决方案 . 我知道你可以获得当前的鼠标位置

PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();

问题是在多环境屏幕中我只是相对于主屏幕获得鼠标位置 . 这意味着如果第二个屏幕位于我收到的主屏幕左侧,例如X:-917.0位置Y:-137.0 . 我知道这些值取决于屏幕分辨率和显示器的顺序 . 是否有可能在当前活动屏幕上获取鼠标位置?

亲切的问候

1 回答

  • 6

    基本上,我所做的是取 PointerInfo 并从中减去 GraphicsDevice 界限,如果结果少于 0 (因为屏幕是主屏幕左侧),我将结果乘以 -1

    解决方案的核心看起来像这样......

    // 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;
    }
    

    以下示例显示第一行的实际桌面鼠标位置(由 MouseInfo 报告),第二行显示 GraphicsDevice 上下文中的"screen"位置

    Where's my mouse

    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;
    
        }
    
    }
    

相关问题