当显示 BufferedImage 并设置相对于缩放比例的鼠标单击位置时,我遇到了鼠标单击与 JFrame 位置相关联的问题。
(代码来自此论坛:在面板内放大和缩小)
`
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
if (zoomer) {
AffineTransform at = new AffineTransform();
double xRel = MouseInfo.getPointerInfo().getLocation().getX() - getLocationOnScreen().getX();
double yRel = MouseInfo.getPointerInfo().getLocation().getY() - getLocationOnScreen().getY();
double zoomDiv = zoomFactor / prevZoomFactor;
xOffset = (zoomDiv) * (xOffset) + (1 - zoomDiv) * xRel;
yOffset = (zoomDiv) * (yOffset) + (1 - zoomDiv) * yRel;
at.translate(xOffset, yOffset);
at.scale(zoomFactor, zoomFactor);
totalZoom *=zoomFactor;
prevZoomFactor = zoomFactor;
g2.transform(at);
zoomer = false;
}
if (dragger) {
AffineTransform at = new AffineTransform();
at.translate(xOffset + xDiff, yOffset + yDiff);
at.scale(zoomFactor, zoomFactor);
g2.transform(at);
if (released) {
xOffset += xDiff;
yOffset += yDiff;
dragger = false;
}
}
} }`
我尝试通过使用数学来更改鼠标单击位置,但我很难正确地做到这一点。
@Override
public void mouseClicked(MouseEvent me) {
double x = MouseInfo.getPointerInfo().getLocation().getX() - getLocationOnScreen().getX();
double y = MouseInfo.getPointerInfo().getLocation().getY() - getLocationOnScreen().getY();
try {
CommandFromClient clientSubmission= new CommandFromClient(CommandFromClient.GETBOARD);
os.writeObject(clientSubmission);
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println("x: " + getLocationOnScreen().getX()/zoomFactor + "y: " + getLocationOnScreen().getY()/zoomFactor);
Point clicked = new Point((int)((me.getPoint().x*10-x)),(int)((me.getPoint().y*10-y)));
System.out.println(1f/zoomFactor);
System.out.println("CLICK DETECTED: " + clicked);
for(int i = yellow.size()-1;i>=0;i--) {
Rectangle bounds = new Rectangle(yellow.get(i).getX(),yellow.get(i).getY(),yellow.get(i).getImg().getWidth(),yellow.get(i).getImg().getHeight());
System.out.print("checks");
if(bounds.contains(clicked)){
System.out.print("collided");
System.out.print(yellow.get(i));
break;
}
}
}
如果您正在查找已通过同一系列仿射变换进行变换的鼠标单击位置,那么您可以保存要应用于图像的当前仿射变换,然后将其应用于该点。为此,请在面板类中创建一个 AffineTransformation 变量,
private AffineTransform currentTransform = new AffineTransform();
然后您的绘制方法将被更新以将仿射变换保存到该变量。该方法如下所示,并注释了更新的位:
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
//if zoomer or dragger is true, this means that a new affine transformation is going to be made, so the currentTransform is reset
if (zoomer || dragger) {
currentTransform = new AffineTransform();
}
//if neither zoomer or dragger is true, then the graphics object will have no affine transformation to apply to the shapes on screen, so it will temporarily reset the screen
//this line counteracts that, applying the current transformation to the shapes so they maintain their location on screen
else {
g2d.transform(currentTransform);
}
if (zoomer) {
AffineTransform at = new AffineTransform();
double xRel = MouseInfo.getPointerInfo().getLocation().getX() - getLocationOnScreen().getX();
double yRel = MouseInfo.getPointerInfo().getLocation().getY() - getLocationOnScreen().getY();
double zoomDiv = zoomFactor / prevZoomFactor;
xOffset = (zoomDiv) * (xOffset) + (1 - zoomDiv) * xRel;
yOffset = (zoomDiv) * (yOffset) + (1 - zoomDiv) * yRel;
at.translate(xOffset, yOffset);
at.scale(zoomFactor, zoomFactor);
prevZoomFactor = zoomFactor;
currentTransform.concatenate(at);//adds the calculated zoom transformation to the current transformation
g2d.transform(at);
zoomer = false;
}
if (dragger) {
AffineTransform at = new AffineTransform();
at.translate(xOffset + xDiff, yOffset + yDiff);
at.scale(zoomFactor, zoomFactor);
currentTransform.concatenate(at);//adds the dragger transformation so the current transformation is now a combination of the zoom and drag transformation
g2d.transform(at);
if (released) {
xOffset += xDiff;
yOffset += yDiff;
dragger = false;
}
}
g2d.fillRect(0,0,200,200);
g2d.drawImage(image, 0, 0, this);
}
最后,我们可以在单击发生时将保存的仿射变换应用到鼠标点:
public void mouseClicked(MouseEvent me) {
Point2D mousePoint = currentTransform.transform(me.getPoint(), null);
System.out.println(mousePoint);
repaint();
}
让我知道这是否是您正在寻找的内容,您的措辞让我有点困惑,但我想我明白了。