如何保持鼠标相对于屏幕的位置并忽略组件旋转?
Posted
技术标签:
【中文标题】如何保持鼠标相对于屏幕的位置并忽略组件旋转?【英文标题】:How to keep mouse position relative to screen and disregard component rotation? 【发布时间】:2017-12-06 04:00:03 【问题描述】:当旋转应用于画布时,如何旋转鼠标坐标系?当我旋转画布时,鼠标相对于旋转的组件保持在相同的位置。我想让鼠标坐标考虑组件的旋转,而不是坐标是相对于窗口的位置,而不考虑旋转。
我提供了一张图片来说明我所了解的更多内容。黑框代表一个形状供参考,紫框位于鼠标坐标上。 Rotation example image
最左边的图片 - 未旋转的画布 中间图片 - Java 看到的旋转画布 最右边的图片 - 期望的结果
我的示例代码模拟了通过按向左或向右箭头键旋转的画布。这个模拟显示了鼠标如何保持在相对于旋转组件的位置,而不是相对于我在屏幕上的鼠标。
有没有办法转换或计算这些新坐标(显示在最右边的图像中),以便它们在窗口中锁定我的鼠标,而不考虑旋转?
package rotation;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
@SuppressWarnings("serial")
public class RotationExample extends Canvas implements Runnable
boolean isRunning = false;
boolean left = false;
boolean right = false;
AffineTransform transform = new AffineTransform();
double rotation = 0.0d;
public RotationExample()
//Create jframe
JFrame f = new JFrame();
f.setSize(500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.setUndecorated(true);
//Add key listener
this.addKeyListener(new KeyAdapter()
public void keyPressed(KeyEvent e)
int k = e.getKeyCode();
//Set left and right variables
if(k == KeyEvent.VK_LEFT) left = true;
if(k == KeyEvent.VK_RIGHT) right = true;
public void keyReleased(KeyEvent e)
int k = e.getKeyCode();
if(k == KeyEvent.VK_LEFT) left = false;
if(k == KeyEvent.VK_RIGHT) right = false;
);
f.add(this);
f.setVisible(true);
start();
public void render()
BufferStrategy bs = this.getBufferStrategy();
if(bs == null)
this.createBufferStrategy(3);
return;
Graphics g = bs.getDrawGraphics();
Graphics2D gt = (Graphics2D) g;
gt.setTransform(transform);
gt.clearRect(0, 0, 500, 500);
//Increment rotation based on left or right variables
if(left) rotation += 0.001;
else if(right) rotation -= 0.001;
//Rotate around middle of frame
gt.rotate(rotation, 250, 250);
//Draw black rectangle in middle
gt.setColor(Color.BLACK);
gt.fillRect(175, 175, 150, 150);
//Draw red up arrow
gt.setColor(Color.RED);
gt.fillPolygon(new int[] 250, 300, 270, 270, 230, 230, 200, new int[] 200, 250, 250, 300, 300, 250, 250, 7);
//Draw rectangle at mouse coordinates
gt.setColor(Color.MAGENTA);
Point m = MouseInfo.getPointerInfo().getLocation();
gt.fillRect((int) m.getX() - 8, (int) m.getY() - 8, 16, 16);
bs.show();
gt.dispose();
public static void main(String[] args)
new RotationExample();
public void start()
isRunning = true;
new Thread(this).start();
public void run()
//Continuous rendering
while(isRunning)
render();
【问题讨论】:
java.awt.Robot
?计算紫色方块的新位置是一个简单的几何坐标变换,然后将鼠标移动到新坐标。坐标变换是一个与编程无关的纯几何问题,参考信息在网上很多地方都可以找到。
@JimGarrison 我已经尝试实现一个基本的机器人,但我最终得到了相同的结果。知道如何用机器人做到这一点吗?我对此很陌生,抱歉
【参考方案1】:
鼠标位置以绝对值报告,但方框图是经过变换的。您需要对鼠标位置进行逆变换以使其回到指针。
//Draw rectangle at mouse coordinates
gt.setColor(Color.MAGENTA);
Point m = MouseInfo.getPointerInfo().getLocation();
try
gt.getTransform().createInverse().transform(m, m);
gt.fillRect((int) m.getX() - 8, (int) m.getY() - 8, 16, 16);
catch (java.awt.geom.NoninvertibleTransformException e)
System.err.println(e);
【讨论】:
以上是关于如何保持鼠标相对于屏幕的位置并忽略组件旋转?的主要内容,如果未能解决你的问题,请参考以下文章