我制作了一个GUI应用程序,但我坚持使用一种解决方法算法来将ui元素相对于另一个表面(屏幕,画布等)拖动/移动。在我的情况下,我将它用于相对于屏幕的窗口,但这不是重点,因为这个算法应该在任何可能的地方工作。这是我的算法:
代码列表-1
MouseMotionAdapter(){
int prevX = -1000, prevY = -1000, getX, getY;
public void mouseDragged(MouseEvent e) {
//if initial cursor position isn't set
if(prevX==-1000){
prevX = e.getLocationOnScreen().x;
prevY = e.getLocationOnScreen().y;
getX = e.getX();
getY = e.getY();
}
//move element to new position
theFrame.setBounds(theFrame.getBounds().x+e.getX()-getX, theFrame.getBounds().y+e.getY()-getY, 880, 583);
prevX=e.getLocationOnScreen().x;
prevY=e.getLocationOnScreen().y;
}
这个算法的问题在于鼠标光标位置肯定是相对于元素固定的,如果我试图移动/拖动元素点击元素的另一个位置/部分,整个元素移动,以便鼠标光标是位于“初始位置”,这不是我想要的行为(我希望它具有我们大多数人所知的行为,例如当我们在桌面上移动图标或在屏幕上移动窗口等时)。
任何人都可以帮忙吗?提前谢谢。
答案 0 :(得分:2)
在这种情况下,通常的方法是计算当前位置和先前位置之间的差异。然后,这种差异就是“移动”,它被添加到被拖动物体的位置。
(顺便说一句:你似乎根本没有在计算中使用prev...
值!)
在MouseMotionListener
内,大概如下所示:
class MouseDraggingControl implements MouseMotionListener
{
private Point previousPoint = new Point();
@Override
public void mouseMoved(MouseEvent e)
{
previousPoint = e.getPoint();
}
@Override
public void mouseDragged(MouseEvent e)
{
int movementX = e.getX() - previousPoint.x;
int movementY = e.getY() - previousPoint.y;
doMovement(movementX, movementY);
previousPoint = e.getPoint();
}
}
在您的情况下,doMovement
方法可能会像这样实现:
private void doMovement(int movementX, int movementY)
{
int oldX = theFrame.getX();
int oldY = theFrame.getY();
int newX = oldX + movementX;
int newY = oldY + movementY;
theFrame.setLocation(newX, newY);
}
(或类似情况,使用getBounds
/ setBounds
来电)
编辑如果鼠标移动侦听器直接连接到应该拖动的组件,则可能必须使用“屏幕上的位置”:
class MouseDraggingControl implements MouseMotionListener
{
private Point previousPoint = new Point();
@Override
public void mouseMoved(MouseEvent e)
{
previousPoint = e.getLocationOnScreen();
}
@Override
public void mouseDragged(MouseEvent e)
{
Point p = e.getLocationOnScreen();
int movementX = p.x - previousPoint.x;
int movementY = p.y - previousPoint.y;
doMovement(movementX, movementY);
previousPoint = e.getLocationOnScreen();
}
}
如果这不能解决您的问题,我想强调MadProgrammer的评论:一个展示您的实际问题的示例会对此有所帮助。