Reputation: 583
I made a GUI application but I am stuck with a workaround algorithm to drag/move ui element relatively to another surface (screen, canvas, etc.). In my case I use it for a window relative to the screen, but that's beside the point because this algorithm should work anywhere possible. Here is my algorithm:
code-listing-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;
}
The trouble with this algorithm is that the mouse cursor position is definitely fixed relatively to the element and if I try to move/drag the element clicking in another position/part of the element the whole element moves so that the mouse cursor is positioned at the "initial position", which is not the behaviour I want (I want it to have the behaviour we mostly know like when we move an icon on desktop or a window on the screen, etc.)
Can anyone help with that? Thanks in advance.
Upvotes: 2
Views: 403
Reputation: 54639
The usual approach in such a case is to compute the difference between the current and the previous position. This difference is then "the movement", that is added to the position of the dragged object.
(BTW: You seem to not use the prev...
values in your computation at all!)
Inside a MouseMotionListener
, this could roughly look as follows:
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();
}
}
In your case, the doMovement
method might be implemented like this:
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);
}
(or similar, using the getBounds
/setBounds
calls)
EDIT If the mouse motion listener is attached directly to the component that should be dragged, you might have to use the "location on screen" instead:
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();
}
}
If this does not solve your issue, I'd like to emphasize the comment from MadProgrammer: An example that demonstrates your actual problem would help here.
Upvotes: 3