Question

On my canvas, I have Circle A and Circle B. Circle A is to be the designated parent to Circle B. What I'm trying to develop is a Parent-Child relationship between the two shapes. So if Circle A is dragged 50 units on the X-axis and 25 units on the Y-Axis, Circle B will also move as such. But if Circle B is dragged, Circle A stays in its last position.

The problem I'm having is re-dragging Circle A. From both circles, initial position, dragging Circle A will move Circle B accordingly. But once I release the mouse and try to drag Circle A again, Circle B moves x-amount of units more than Circle A's x-position and y-amount of units more than Circle A's y-position. So each time that I re-click and drag Circle A, Circle B increments to a new position on it's own x and y axes at a further distance each time the mouse button is pressed.

// initial positions of Circles (Part of Circle class which draws two circles)
int parentCirclePosX = 100;
int parentCirclePosY = 100;
int childCirclePosX = 103;
int childCirclePosY = 143;

public void mouseInput()
{
    getCanvas().addMouseListener(new MouseAdapter()
    {   
        @Override
        public void mouseReleased(MouseEvent event)
        {
            super.mouseReleased(event);
            _cir.isDraggable = false;               
            Main.parentLabel.setText("Released " + _cir.isDraggable);               
        }

        @Override
        public void mousePressed(MouseEvent event)
        {
            super.mousePressed(event);

            // Original mouse coordinates before dragging
            last_x = _cir.getParentCircleX() - event.getX();
            last_y = _cir.getParentCircleY() - event.getY();

            // Child Circle's last position
            lastChildx = _cir.getChildCircleX();
            lastChildy = _cir.getChildCircleY();

            int button = event.getModifiers();

            // Check if mouse pointer is hovering over Parent Circle
            boolean inXBounds = event.getX() > _cir.getParentCircleX() && 
                    event.getX() < _cir.getParentCircleX() + _cir.PARENT_CIRCLE_SIZE;

            boolean inYBounds = event.getY() > _cir.getParentCircleY() && 
                    event.getY() < _cir.getParentCircleY() + _cir.PARENT_CIRCLE_SIZE;

            if (button == InputEvent.BUTTON1_MASK && inXBounds && inYBounds)
            {
                _cir.isDraggable = true;
                Main.parentLabel.setText("Pressed " + _cir.isDraggable);    
            }
            getCanvas().repaint();
        }       
    });


    getCanvas().addMouseMotionListener(new MouseAdapter()
    {
        @Override
        public void mouseDragged(MouseEvent event)
        {
            super.mouseDragged(event);

            if (_bone.isDraggable)
            {   
                updateLocation(event);
                Main.parentLabel.setText(" Parent X: " + _cir.getParentCircleX() + " Y: " + _cir.getParentCircleY());
                Main.childLabel.setText("Child X: " + _cir.getChildCircleX() + " Y: " + _cir.getChildCircleY());
            }
            getCanvas().repaint();
        }
    });
}

private void updateLocation(MouseEvent e)
{
    _cir.setParentCircleX(last_x  - _cir.PARENT_CIRCLE_SIZE / 2);
    _cir.setParentCircleY(last_y  - _cir.PARENT_CIRCLE_SIZE / 2);
    _cir.setChildCircleX(lastChildx + e.getX() - 108 );
    _cir.setChildCircleY(lastChildy + e.getY() - 108);

    last_x = e.getX();
    last_y = e.getY();
}
Was it helpful?

Solution 2

Figured out what was the problem. The problem was that I wasn't calculating in maintaining the distance between Circle A and Circle B when setting the position for Circle B:

// store distance between circle's axes for later (called in constructor)
 offsetX = _bone.getParentCircleX() - _bone.getChildCircleX();
offsetY = _bone.getParentCircleY() - _bone.getChildCircle();

// helper for mimicking Circle A's movement (called in updateLocation())
int diffX = e.getX() - last_x;
int diffY = e.getY() - last_y;

_cir.setChildCircleX(lastChildx - diffX - (_cir.PARENT_CIRCLE_SIZE / 2)) 
_cir.setChildCircleY(lastChildY - diffY - (_cir.PARENT_CIRCLE_SIZE / 2));


// update position and readjust for next time
lastChildx = last_x - offsetX;
lastChildy = last_y - offsetY;

OTHER TIPS

You could make two boolean variables like this and surround the movement movement handlers by if statements lik this:

CircleAMoving = false;
CircleBMoving = false;

if(CircleAMoving){CircleAMoving = true; CircleBMoving = true;}
if(CircleBMoving){CircleAMoving = false;}

if(CircleAMoving){
//move circle A like you want to.

}

 if(CircleBMoving){
//move circle B like you want to.

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top