Java在多个监视器环境中获取鼠标位置 [英] Java getting mouse location on multiple monitor environment

查看:114
本文介绍了Java在多个监视器环境中获取鼠标位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在互联网上搜索了一段时间,但我没有找到解决问题的方法。
我知道你可以用

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();

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

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?

亲切的问候

推荐答案

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

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

以下示例显示实际的桌面鼠标位置(由<$ c报告) $ c> MouseInfo )在第一行,第二行显示 GraphicsDevice

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;

    }

}

这篇关于Java在多个监视器环境中获取鼠标位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆