我编写了一个基本的绘图程序,但我在使用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 Component来绘制形状,而不是其他任何东西。
答案 0 :(得分:4)
myRectangle = new Rectangle2D.Double(Start_X, Start_Y, myX2, myY2);
您尝试指定两个点的参数是(x,y,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);
此外,每次单击按钮时,都会继续将适配器添加到面板中。因此,如果您单击线工具,然后是ellispse工具,然后是矩形工具,您将在面板中添加3个侦听器。我建议您在添加当前工具的监听器之前从面板中删除所有监听器。
答案 1 :(得分:3)
您正在使用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));