在 Java awt applet 中拖放一个形状

Drag and Drop a shape in Java awt applet

我正在尝试创建一个 awt 小程序,用户可以在其中拖动已在小程序上绘制的矩形。我不明白为什么我的小程序中的矩形只能沿对角线和正 x 方向拖动,我不能将它向上或向下或向左移动,它只能向右对角线拖动。有人可以告诉我我的逻辑有什么问题吗?

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class DragRectangle extends Applet implements MouseMotionListener {

  boolean clicked_in_rectangle = false;

  int rectangleX, rectangleY, mouseX, mouseY;
  int rectangle_width = 80, rectangle_height = 50;

  public void init() {
    rectangleX = 0;
    rectangleY = 0;
    mouseX = 0;
    mouseY = 0;
    addMouseMotionListener(this);

  }

  public void paint(Graphics g) {
      g.drawRect(rectangleX, rectangleY, rectangle_width, rectangle_height);
      if(clicked_in_rectangle) {
        rectangleX = mouseX;
        rectangleY = mouseY;
        g.drawRect(rectangleX, rectangleY, rectangle_width,   rectangle_height);
      }

  }

  public void mouseDragged(MouseEvent e) {
    mouseX = e.getX();
    mouseY = e.getY();

    clicked_in_rectangle = mouseX > rectangleX && mouseY > rectangleY &&
                           mouseX < rectangleX + rectangle_width && mouseY < rectangleY + rectangle_height;

    repaint();
  }

  public void mouseMoved(MouseEvent e) {

  }

}

我认为问题在于您将矩形的位置设置为鼠标指针的位置,当您尝试向上或向左拖动矩形时,指针将超出矩形的边界并且 clicked_in_rectangle 将是 false.

你可以试试这个:

if (clicked_in_rectangle) {
    rectangleX = mouseX - 3;
    rectangleY = mouseY - 3;
    g.drawRect(rectangleX, rectangleY, rectangle_width, rectangle_height);
}

但这仍然不是一个理想的解决方案,如果您尝试快速拖动矩形(向上或向左)它会停止工作,那是因为 rectangleXrectangleY 不有机会更新到新职位。

如果你想要更可靠的东西,你可以这样做:

public class DragRectangle extends Applet implements MouseMotionListener, MouseListener {

boolean clicked_in_rectangle = false, dragStarted = false;

int x, y, px, py;
Rectangle rect = new Rectangle(0, 0, 80, 50);

public void init() {
    addMouseMotionListener(this);
    addMouseListener(this);
}

public void paint(Graphics g) {
    if (clicked_in_rectangle) {
        int nx = rect.x + (x - px);
        int ny = rect.y + (y - py);

        Rectangle bounds = g.getClipBounds();
        boolean reset = false;
        if (nx + rect.width > bounds.width || nx < 0) {
            nx = rect.x;
            reset = true;
        }
        if (ny + rect.height > bounds.height || ny < 0) {
            ny = rect.y;
            reset = true;
        }
        if (reset) {
            px = 0;
            py = 0;
        } else {
            px = x;
            py = y;
        }

        rect = new Rectangle(nx, ny, rect.width, rect.height);
    }
    g.drawRect(rect.x, rect.y, rect.width, rect.height);

}

public void mouseDragged(MouseEvent e) {
    if (dragStarted) {
        x = e.getX();
        y = e.getY();
        if (px == 0 && py == 0) {
            px = x;
            py = y;
        } else {
            clicked_in_rectangle = new Rectangle(x, y, 1, 1).intersects(rect);
            if (clicked_in_rectangle) {
                repaint();
            }
        }
    }
}

public void mouseMoved(MouseEvent e) {

}

@Override
public void mouseClicked(MouseEvent e) {
}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
}

@Override
public void mousePressed(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) {
        dragStarted = new Rectangle(e.getX(), e.getY(), 1, 1).intersects(rect);
    }
}

@Override
public void mouseReleased(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) {
        px = 0;
        py = 0;
    }
}

}

我可能已经把它弄得更复杂了,无论如何,我的想法是根据连续指针坐标之间的差异来更改形状的位置,而不是将其位置设置为与指针相同的位置.