Java在多显示器环境下获取鼠标位置

2024-07-01

我在互联网上搜索了一段时间,但没有找到任何解决我的问题的方法。 我知道你可以通过以下方式获取当前鼠标位置

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

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

亲切的问候


基本上,我所做的就是采取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

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;

    }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java在多显示器环境下获取鼠标位置 的相关文章

  • 无法远程连接JMX?

    由于某些奇怪的原因 我无法使用VisualVM or jconsole到 JMX 用于启动要监控的VM的参数 Dcom sun management jmxremote Dcom sun management jmxremote authe
  • 如何使用鼠标指针和键盘快捷键捕获文本?

    我想使用 C 或 java 使用鼠标指针和键盘快捷键从打开的窗口捕获文本 喜欢babylon http babylon com 所以 我需要知道什么以及如何实施 我需要使用哪些库 或者我可以使用 winapi 吗 使用脚本语言创建您想要执行
  • 媒体对象上的 javafx UNKNOWN 持续时间

    我是 Java 和 JavaFX 的新手 过去几年我一直在使用 QT 在 Python 上进行开发 现在我正在使用 Java 和 JavaFX 进行开发 我正在开发一个程序 可以为用户设定的时间播放音乐文件 然后停止 因此 我需要从媒体对象
  • 将日期从“2009-12 Dec”格式转换为“31-DEC-2009”

    2009 12 Dec should be converted to 31 DEC 2009 2010 09 Sep should be converted to 30 SEP 2010 2010 02 Feb should be conv
  • 有人可以推荐 java 8 模式来替换 switch 语句吗?

    我有以下代码 public class A private String type String getType return type 现在在许多代码位置我都有这样的代码 switch a geType case A return new
  • 您使用什么来进行复杂的构建过程? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试改进我们的构建过程 目前它是一个巨大的 Ant build xml 它调用其他 ant 构建
  • Java 让物体在按住按钮时移动

    如何使 JPanel 在按住按钮时移动并在释放按钮时停止 我尝试过将 thread start 与 Runnable 一起使用以及类似的方式 我总是遇到错误 有人可以帮助我吗 您需要考虑许多重要的因素 按钮的设计初衷并非如此 它们被设计为在
  • 从 android 将用户注册到 QuickBlox 用户

    我正在尝试在我的 Android 应用程序中使用 QuickBlox 我阅读了指南并导入了示例 一切正常 我更改了一些用户可以使用 EditText 作为用户名和另一个密码登录的内容 并且效果很好 但现在我想添加一个注册按钮 使用户能够注册
  • 数组等于忽略顺序[重复]

    这个问题在这里已经有答案了 可能的重复 Java 检查数组的相等性 顺序无关紧要 https stackoverflow com questions 10154305 java checking equality of arrays ord
  • 在 onClick 处理程序的活动类 [...] 中找不到方法 [...](View)

    当我按下按钮时fragment main xml 出现这个错误 java lang IllegalStateException Could not find a method sendMessage View in the activity
  • 在内存对象缓存中开发

    我正在开发一个基于网络的医疗应用程序 需要创建一个小型内存对象缓存 这是我的用例 我们需要显示需要某些东西 血液 肾脏等 的人提交的请求列表 并且它不会是一个巨大的列表 因为在某一天对血液或其他任何东西的请求将是有限的 请注意 我们不想使用
  • 如何使用 Spring 使用注释执行基于构造函数的依赖注入?

    好的 如果我需要在构造函数中放入一些原始值 我该怎么做 Autowired public CustomBean String name Qualifier SuperBean SuperBean superBean super this s
  • Android UserManager.isUserAGoat() 的正确用例?

    想要改进这篇文章吗 提供此问题的详细答案 包括引用和解释为什么你的答案是正确的 不够详细的答案可能会被编辑或删除 我正在查看 中引入的新 API安卓4 2 http en wikipedia org wiki Android version
  • 如何使用 Firebase 查询中的信息填充 Android ListView

    这是我的第一篇文章 所以如果我没有遵循我应该遵循的一些协议 我深表歉意 我正在尝试使用 Firebase 数据库中的一些信息填充 ListView 我认为我遇到的问题是对数据库的查询太慢 线程可能正在下载图片 并且我的活动加载其活动布局而不
  • 在 Java 8 中使用 Lambda 将流收集到 HashMap 中

    我有一个 HashMap 我需要使用一些函数来过滤它 HashMap
  • 在 JSP 中呈现 JSON 数据的最佳实践是什么?

    我需要在 JSP 中针对某些 AJAX 请求呈现 JSON 数据 我想知道在易用性和稳定性方面最好的方法是什么 假设您想要从一个或多个 Java 对象生成 JSON 以下是一种相当简单的方法 将 Java 对象设置为请求 会话范围内的属性
  • Java中从long到float的信息丢失[重复]

    这个问题在这里已经有答案了 如果你调用Java的以下方法 void processIt long a float b a do I have loss here 当我将 long 变量分配给 float 变量时 是否会丢失信息 Java 语
  • 允许轻松打印字节码指令*包括*参数的库

    我正在寻找一个图书馆easily让我查看方法的给定字节码 例子 ALOAD 0 INVOKEVIRTUAL ns c m I IRETURN 我都尝试过 ASM 我实际上可以让它打印指令和参数 但是我很难理解它的整个访问者范例 也就是说 我
  • 允许轻松打印字节码指令*包括*参数的库

    我正在寻找一个图书馆easily让我查看方法的给定字节码 例子 ALOAD 0 INVOKEVIRTUAL ns c m I IRETURN 我都尝试过 ASM 我实际上可以让它打印指令和参数 但是我很难理解它的整个访问者范例 也就是说 我
  • Java将浮点字符串解析为浮点数组?

    有没有一种简单的方法将浮点字符串解析为浮点数组 我正在编写一个导入程序 它需要解析一个 ascii 文件以获取一些值 我只是想知道是否有更简单的方法来执行此操作 然后自己搜索所有空白并使用Float parseFloat s 对于每个空格分

随机推荐