无法根据光标调整 Rectangle2D 的大小
Unable to resize a Rectangle2D following the cursor
我正在尝试使用鼠标拖动方法调整 一个Rectangle2D
。
另外我想重新居中它在JPanel
的中间。
我认为代码和公式是正确的,但它不能正常工作,因为它过度调整了矩形的大小并且它不适合跟随光标。
这里我会post相关代码
构造函数:
public Canvas(double width, double height) {
this.width = width;
this.height = height;
rect = new Rectangle2D.Double(this.x, this.y, this.width, this.height);
vertex = new Rectangle2D[4];
this.addMouseMotionListener(this);
this.addMouseListener(this);
}
vertex
是 Rectangle2D
的数组,仅当鼠标在
内时才绘制到矩形的顶点
paintComponent:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//RETTANGOLO
Graphics2D g2 = (Graphics2D)g;
Stroke oldStroke = g2.getStroke();
g2.setStroke(new BasicStroke(SPESSORE));
g2.draw(rect);
g2.setStroke(oldStroke);
g2.setColor(Color.BLACK);
setAtCenter();
//VERTICI
vertex[0] = new Rectangle2D.Double(this.x, this.y, SIZEV, SIZEV);
vertex[1] = new Rectangle2D.Double(this.x + this.width - SIZEV,
this.y, SIZEV, SIZEV);
vertex[2] = new Rectangle2D.Double(this.x, this.y + this.height - SIZEV,
SIZEV, SIZEV);
vertex[3] = new Rectangle2D.Double(this.x + this.width - SIZEV,
this.y + this.height - SIZEV,
SIZEV, SIZEV);
if (dentro) {
for (int i = 0; i < 4; i++) {
g2.draw(vertex[i]);
}
}
}
private void setAtCenter() {
this.x = ((this.getWidth()/2) - (this.width/2));
this.y = ((this.getHeight()/2) - (this.height/2));
rect.setRect(x, y, this.width, this.height);
}
mouseMoved:
@Override
public void mouseMoved(MouseEvent e) {
dentro = false;
inVertex = -1;
if (rect.contains(e.getPoint())) {
dentro = true;
}
for (int i = 0; i < 4; i++) {
if (vertex[i].contains(e.getPoint())) {
inVertex = i;
break;
}
}
}
鼠标按下:
@Override
public void mousePressed(MouseEvent e) {
if (inVertex >= 0) {
this.startX = e.getX();
this.startY = e.getY();
}
}
鼠标拖动:
@Override
public void mouseDragged(MouseEvent e) {
double dX;
double dY;
if (inVertex >= 0) {
this.endX = e.getX();
this.endY = e.getY();
dX = startX - endX;
dY = startY - endY;
this.width += dX;
this.height += dY;
this.repaint();
}
}
我希望我已经 post 提供了所有必要的信息,并且终于有人帮助我解决了这个困扰我太久的问题。
编辑:
我通过相应地设置宽度和高度来跟踪顶点的位置解决了这个问题。我简化了代码,只允许从原点调整大小。感谢支持。
谢谢大家!
mouseDragged()
会被重复调用。在您当前的实现中,每次调用 mouseDragged()
时,您都会一次又一次地添加整个距离,而不是仅仅添加自上次 mouseDragged()
调用以来发生的变化。
this.width += dX;
this.height += dY;
一个快速修复方法是在每次调用 mouseDragged()
时将当前位置存储在 startX
和 startY
中。
@Override
public void mouseDragged(MouseEvent e) {
double dX;
double dY;
if (inVertex >= 0) {
this.endX = e.getX();
this.endY = e.getY();
dX = startX - endX;
dY = startY - endY;
this.width += dX;
this.height += dY;
this.startX = this.endX;
this.startY = this.endY;
this.repaint();
}
}
但是这种将大小的增量变化相加是一种奇怪的方法。你可能最好只跟踪哪个顶点被抓取,然后更新它的位置。然后根据顶点的位置绘制形状,而不跟踪大小变化——也就是说,矩形的大小是基于顶点的位置隐含的。
我正在尝试使用鼠标拖动方法调整 一个Rectangle2D
。
另外我想重新居中它在JPanel
的中间。
我认为代码和公式是正确的,但它不能正常工作,因为它过度调整了矩形的大小并且它不适合跟随光标。
这里我会post相关代码
构造函数:
public Canvas(double width, double height) {
this.width = width;
this.height = height;
rect = new Rectangle2D.Double(this.x, this.y, this.width, this.height);
vertex = new Rectangle2D[4];
this.addMouseMotionListener(this);
this.addMouseListener(this);
}
vertex
是 Rectangle2D
的数组,仅当鼠标在
paintComponent:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//RETTANGOLO
Graphics2D g2 = (Graphics2D)g;
Stroke oldStroke = g2.getStroke();
g2.setStroke(new BasicStroke(SPESSORE));
g2.draw(rect);
g2.setStroke(oldStroke);
g2.setColor(Color.BLACK);
setAtCenter();
//VERTICI
vertex[0] = new Rectangle2D.Double(this.x, this.y, SIZEV, SIZEV);
vertex[1] = new Rectangle2D.Double(this.x + this.width - SIZEV,
this.y, SIZEV, SIZEV);
vertex[2] = new Rectangle2D.Double(this.x, this.y + this.height - SIZEV,
SIZEV, SIZEV);
vertex[3] = new Rectangle2D.Double(this.x + this.width - SIZEV,
this.y + this.height - SIZEV,
SIZEV, SIZEV);
if (dentro) {
for (int i = 0; i < 4; i++) {
g2.draw(vertex[i]);
}
}
}
private void setAtCenter() {
this.x = ((this.getWidth()/2) - (this.width/2));
this.y = ((this.getHeight()/2) - (this.height/2));
rect.setRect(x, y, this.width, this.height);
}
mouseMoved:
@Override
public void mouseMoved(MouseEvent e) {
dentro = false;
inVertex = -1;
if (rect.contains(e.getPoint())) {
dentro = true;
}
for (int i = 0; i < 4; i++) {
if (vertex[i].contains(e.getPoint())) {
inVertex = i;
break;
}
}
}
鼠标按下:
@Override
public void mousePressed(MouseEvent e) {
if (inVertex >= 0) {
this.startX = e.getX();
this.startY = e.getY();
}
}
鼠标拖动:
@Override
public void mouseDragged(MouseEvent e) {
double dX;
double dY;
if (inVertex >= 0) {
this.endX = e.getX();
this.endY = e.getY();
dX = startX - endX;
dY = startY - endY;
this.width += dX;
this.height += dY;
this.repaint();
}
}
我希望我已经 post 提供了所有必要的信息,并且终于有人帮助我解决了这个困扰我太久的问题。
编辑: 我通过相应地设置宽度和高度来跟踪顶点的位置解决了这个问题。我简化了代码,只允许从原点调整大小。感谢支持。
谢谢大家!
mouseDragged()
会被重复调用。在您当前的实现中,每次调用 mouseDragged()
时,您都会一次又一次地添加整个距离,而不是仅仅添加自上次 mouseDragged()
调用以来发生的变化。
this.width += dX;
this.height += dY;
一个快速修复方法是在每次调用 mouseDragged()
时将当前位置存储在 startX
和 startY
中。
@Override
public void mouseDragged(MouseEvent e) {
double dX;
double dY;
if (inVertex >= 0) {
this.endX = e.getX();
this.endY = e.getY();
dX = startX - endX;
dY = startY - endY;
this.width += dX;
this.height += dY;
this.startX = this.endX;
this.startY = this.endY;
this.repaint();
}
}
但是这种将大小的增量变化相加是一种奇怪的方法。你可能最好只跟踪哪个顶点被抓取,然后更新它的位置。然后根据顶点的位置绘制形状,而不跟踪大小变化——也就是说,矩形的大小是基于顶点的位置隐含的。