我在尝试调整Java中可拖动方块的大小时遇到了烦人的问题。为了调整方块的大小,我正在检查鼠标光标是否位于方形右下角的矩形区域内 - 如果是,则在拖动鼠标时方块会调整大小。这段代码工作正常,但如果我点击方块将其拖动到屏幕上,它会跳回到默认大小100 x 100。
我的班级就这样开始:
public class DragPanel extends JPanel implements MouseListener,
MouseMotionListener, MouseWheelListener
{
Graphics2D g2;
Rectangle2D square;
Color colour;
double x1, y1, x2, y2, sizex, sizey;
double offsetX, offsetY;
double oldx, oldy;
boolean dragging = false;
boolean resizing = false;
public DragPanel()
{
x1 = 10.0;
y1 = 10.0;
sizex = 100.0;
sizey = 100.0;
x2 = x1 + sizex;
y2 = y1 + sizey;
square = new Rectangle2D.Double(x1, y1, sizex, sizey);
colour = Color.BLUE;
setFocusable(true);
addMouseListener(this);
addMouseMotionListener(this);
addMouseWheelListener(this);
this.requestFocus();
}
这是我的鼠标按下和鼠标拖动方法:
鼠标按下:
@Override
public void mousePressed(MouseEvent ev)
{
double mx = ev.getX();
double my = ev.getY();
if (mx > x1 && mx < x2 && my > y1 && my < y2)
{
dragging = true;
offsetX = mx - x1;
offsetY = my - y1;
}
if (mx > x2 - 3 && mx < x2 + 3 && my > y2 - 3 && my < y2 + 3)
{
oldx = mx;
oldy = my;
resizing = true;
}
}
鼠标拖动:
@Override
public void mouseDragged(MouseEvent ev)
{
if (dragging)
{
double mx = ev.getX();
double my = ev.getY();
x1 = mx - offsetX;
y1 = my - offsetY;
x2 = x1 + sizex;
y2 = y1 + sizey;
square = new Rectangle2D.Double(x1, y1, sizex, sizey);
repaint();
}
if (resizing)
{
double mx = ev.getX();
double my = ev.getY();
double diffx, diffy;
diffx = oldx - mx;
diffy = oldy - my;
square = new Rectangle2D.Double(x1, y1, sizex - diffx, sizey - diffy);
repaint();
}
}
您在上面看到的代码在调整大小方面做了我想要它做的事情,但正如我已经解释的那样,当我在调整大小后尝试拖动方块时,它无法正常工作。而且我知道为什么 - 这是因为这条线:
square = new Rectangle2D.Double(x1, y1, sizex - diffx, sizey - diffy);
所以我的解决方案是更改if (resizing)
块的最后一部分,如下所示:
diffx = oldx - mx;
diffy = oldy - my;
sizex -= diffx;
sizey -= diffy;
square = new Rectangle2D.Double(x1, y1, sizex, sizey);
repaint();
然而,当我这样做时,事情就停止了!我仍然可以拖动广场,但是如果我尝试调整大小,那么这个动作是不稳定和极端的。
我做错了什么?
答案 0 :(得分:1)
在我看来,拖动和调整大小的条件并不相互排斥,特别是靠近边界。假设您在鼠标释放时将这两个标志设置为false,则单击鼠标或单击一次仍然可以同时进入两种模式。
我会放else if (mx > x2 - 3 && mx < x2 + 3 && my > y2 - 3 && my < y2 + 3)
和else if (resizing)
以避免任何预期后果。这将使任何拖动优先于任何调整大小。
作为一个图形化的东西,很难说这是你的问题(或者它的一部分),但是让它清除这一点可能会有所不同。
编辑:当然,您可能希望调整大小条件优先于(之前)拖动条件,因为调整大小的区域远小于拖动区域。
编辑2:BTW,当您调整大小时,您正在修改square
,而不是sizex
和sizey
变量。当然,当您在拖动时询问这些值时,它们与之前相同(100)。存储更改,它应该工作。在这方面,对同一信息进行多次表示可能是个坏主意。它会导致像这样的冗余和同步问题。如果可能的话,删除这些变量:double x1, y1, x2, y2, sizex, sizey;
然后从当前的平方状态读取/写入(您可能每次都不需要新的方块)。
答案 1 :(得分:0)
我将这些视为两个独立的功能:
这些类中的代码比您需要的更复杂,但您可能需要考虑在最终解决方案中为每个函数分离逻辑。
答案 2 :(得分:0)
我找到了解决方案,或者更确切地说,我找到了 解决方案。我在if (resizing)
方法中更改了mouseDragged
语句,如下所示:
旧:
if (resizing)
{
double mx = ev.getX();
double my = ev.getY();
double diffx, diffy;
diffx = oldx - mx;
diffy = oldy - my;
square = new Rectangle2D.Double(x1, y1, sizex - diffx, sizey - diffy);
repaint();
}
新:
if (resizing)
{
double mx = ev.getX();
double my = ev.getY();
x2 = mx - rOffX;
y2 = my - rOffX;
sizex = x2 - x1;
sizey = sizex;
square.setRect(x1, y1, sizex, sizey);
repaint();
}