MouseEvent getX 和 getY 与实际坐标的偏移量
MouseEvent getX and getY offset from actual coordinate
我正在编写一个基本的绘画程序,但我一直在使用 Rectangle
和 Ellipse
工具时遇到问题。如果您单击并拖动,您应该能够使用基于 startpoint
和 endpoint
的尺寸绘制形状(均使用 getX()
和 getY()
),问题在于这两个形状使 startpoint
正确,但 endpoint
在 x 和 y 坐标中均有偏移。
除了分别将 Line2D
与 Rectangle2D
和 Ellipse2D
交换之外,下面的代码与我在直线工具中使用的代码(工作正常)几乎相同。
package tools;
import gui.DrawingPanel;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
/**
* Creates the Rectangle Action.
*@version 1
*/
public class RectangleAction extends AbstractAction {
private final DrawingPanel myPanel;
private Rectangle2D.Double myRectangle;
private double Start_X;
private double Start_Y;
/**
* Constructor for Rectangle Action.
*/
public RectangleAction(final DrawingPanel thePanel) {
super("Rectangle", getImageIcon());
myPanel = thePanel;
putValue(Action.MNEMONIC_KEY, KeyEvent.VK_R);
putValue(Action.SELECTED_KEY, true);
}
@Override
public void actionPerformed(final ActionEvent theEvent) {
myPanel.addMouseListener(new MyMouseListener());
myPanel.addMouseMotionListener(new MyMouseListener());
}
/**
* gets the image icon of the action.
* @return the image icon.
*/
public static ImageIcon getImageIcon() {
return new ImageIcon("./images/rectangle.gif");
}
/**
* Listens for mouse clicks, to draw on our panel.
*/
private class MyMouseListener extends MouseAdapter {
private double myX2;
private double myY2;
/**
* Handles a click event.
*
* @param theEvent The event.
*/
@Override
public void mousePressed(final MouseEvent theEvent) {
Start_X = (double) theEvent.getX();
Start_Y = (double) theEvent.getY();
}
/**
* Handles the release event.
*
* @param theEvent The event.
*/
@Override
public void mouseReleased(final MouseEvent theEvent) {
myX2 = (double) theEvent.getX();
myY2 = (double) theEvent.getY();
myRectangle = new Rectangle2D.Double(Start_X, Start_Y, myX2, myY2);
myPanel.setShape(myRectangle);
myPanel.repaint();
}
/**
* Handles a click event.
*
* @param theEvent The event.
*/
@Override
public void mouseDragged(final MouseEvent theEvent) {
myX2 = (double) theEvent.getX();
myY2 = (double) theEvent.getY();
myRectangle = new Rectangle2D.Double(Start_X, Start_Y, myX2, myY2);
myPanel.setShape(myRectangle);
myPanel.repaint();
}
}
}
我应该注意,我确实看过 this similar question,但它没有给我想要的答案; DrawingPanel
也只是一个 JPanel
,带有一个用于绘制形状的 Paint 组件,仅此而已。
您正在使用释放的 x 和 y 而不是宽度和高度来初始化矩形。
替换
myRectangle = new Rectangle2D.Double(Start_X, Start_Y, myX2, myY2);
和
int x;
int y;
if (Start_X > myX2) {
x = myX2;
} else {
x = Start_X;
}
if (Start_Y > myY2) {
y = myY2;
} else {
y = Start_Y;
}
myRectangle = new Rectangle2D.Double(x, y, Math.abs(myX2 - Start_X), Math.abs(myY2 - Start_Y));
myRectangle = new Rectangle2D.Double(Start_X, Start_Y, myX2, myY2);
参数是(x, y, width, height) 你试图指定两个点。
您的绘画逻辑假定您始终将鼠标从 top/left 拖动到 bottom/right。当您根据两个点计算 width/height 时,总是可能会出现鼠标向上和向左拖动的情况,这会导致负值。
这是我用来正确计算矩形边界的代码:
int x = Math.min(startPoint.x, e.getX());
int y = Math.min(startPoint.y, e.getY());
int width = Math.abs(startPoint.x - e.getX());
int height = Math.abs(startPoint.y - e.getY());
您不需要创建两个侦听器,您可以共享同一个侦听器:
//myPanel.addMouseListener(new MyMouseListener());
//myPanel.addMouseMotionListener(new MyMouseListener());
MouseAdapter myMouseAdapter = new MyMouseListener();
myPanel.addMouseListener( myMouseAdapter );
myPanel.addMouseMotionListener( myMouseAdapter);
此外,每次单击按钮时,您都会继续将适配器添加到面板。所以如果你点击你的线条工具,然后是椭圆工具,然后是矩形工具,你就会有 3 个监听器添加到面板中。我建议您在为当前工具添加侦听器之前从面板中删除所有侦听器。
我正在编写一个基本的绘画程序,但我一直在使用 Rectangle
和 Ellipse
工具时遇到问题。如果您单击并拖动,您应该能够使用基于 startpoint
和 endpoint
的尺寸绘制形状(均使用 getX()
和 getY()
),问题在于这两个形状使 startpoint
正确,但 endpoint
在 x 和 y 坐标中均有偏移。
除了分别将 Line2D
与 Rectangle2D
和 Ellipse2D
交换之外,下面的代码与我在直线工具中使用的代码(工作正常)几乎相同。
package tools;
import gui.DrawingPanel;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
/**
* Creates the Rectangle Action.
*@version 1
*/
public class RectangleAction extends AbstractAction {
private final DrawingPanel myPanel;
private Rectangle2D.Double myRectangle;
private double Start_X;
private double Start_Y;
/**
* Constructor for Rectangle Action.
*/
public RectangleAction(final DrawingPanel thePanel) {
super("Rectangle", getImageIcon());
myPanel = thePanel;
putValue(Action.MNEMONIC_KEY, KeyEvent.VK_R);
putValue(Action.SELECTED_KEY, true);
}
@Override
public void actionPerformed(final ActionEvent theEvent) {
myPanel.addMouseListener(new MyMouseListener());
myPanel.addMouseMotionListener(new MyMouseListener());
}
/**
* gets the image icon of the action.
* @return the image icon.
*/
public static ImageIcon getImageIcon() {
return new ImageIcon("./images/rectangle.gif");
}
/**
* Listens for mouse clicks, to draw on our panel.
*/
private class MyMouseListener extends MouseAdapter {
private double myX2;
private double myY2;
/**
* Handles a click event.
*
* @param theEvent The event.
*/
@Override
public void mousePressed(final MouseEvent theEvent) {
Start_X = (double) theEvent.getX();
Start_Y = (double) theEvent.getY();
}
/**
* Handles the release event.
*
* @param theEvent The event.
*/
@Override
public void mouseReleased(final MouseEvent theEvent) {
myX2 = (double) theEvent.getX();
myY2 = (double) theEvent.getY();
myRectangle = new Rectangle2D.Double(Start_X, Start_Y, myX2, myY2);
myPanel.setShape(myRectangle);
myPanel.repaint();
}
/**
* Handles a click event.
*
* @param theEvent The event.
*/
@Override
public void mouseDragged(final MouseEvent theEvent) {
myX2 = (double) theEvent.getX();
myY2 = (double) theEvent.getY();
myRectangle = new Rectangle2D.Double(Start_X, Start_Y, myX2, myY2);
myPanel.setShape(myRectangle);
myPanel.repaint();
}
}
}
我应该注意,我确实看过 this similar question,但它没有给我想要的答案; DrawingPanel
也只是一个 JPanel
,带有一个用于绘制形状的 Paint 组件,仅此而已。
您正在使用释放的 x 和 y 而不是宽度和高度来初始化矩形。
替换
myRectangle = new Rectangle2D.Double(Start_X, Start_Y, myX2, myY2);
和
int x;
int y;
if (Start_X > myX2) {
x = myX2;
} else {
x = Start_X;
}
if (Start_Y > myY2) {
y = myY2;
} else {
y = Start_Y;
}
myRectangle = new Rectangle2D.Double(x, y, Math.abs(myX2 - Start_X), Math.abs(myY2 - Start_Y));
myRectangle = new Rectangle2D.Double(Start_X, Start_Y, myX2, myY2);
参数是(x, y, width, height) 你试图指定两个点。
您的绘画逻辑假定您始终将鼠标从 top/left 拖动到 bottom/right。当您根据两个点计算 width/height 时,总是可能会出现鼠标向上和向左拖动的情况,这会导致负值。
这是我用来正确计算矩形边界的代码:
int x = Math.min(startPoint.x, e.getX());
int y = Math.min(startPoint.y, e.getY());
int width = Math.abs(startPoint.x - e.getX());
int height = Math.abs(startPoint.y - e.getY());
您不需要创建两个侦听器,您可以共享同一个侦听器:
//myPanel.addMouseListener(new MyMouseListener());
//myPanel.addMouseMotionListener(new MyMouseListener());
MouseAdapter myMouseAdapter = new MyMouseListener();
myPanel.addMouseListener( myMouseAdapter );
myPanel.addMouseMotionListener( myMouseAdapter);
此外,每次单击按钮时,您都会继续将适配器添加到面板。所以如果你点击你的线条工具,然后是椭圆工具,然后是矩形工具,你就会有 3 个监听器添加到面板中。我建议您在为当前工具添加侦听器之前从面板中删除所有侦听器。