Как перемещать две фигуры одновременно, перетаскивая одну фигуру?

На моем полотне у меня есть круг A и круг B. Круг A должен быть назначенным родителем для круга B. То, что я пытаюсь разработать, - это отношения между родителями и детьми между двумя фигурами. Таким образом, если Circle A перетащит 50 единиц по оси X и 25 единиц по оси Y, кружок B также будет двигаться как таковой. Но если Circle B перетаскивается, Circle A остается в своей последней позиции.

Проблема, с которой я столкнулась, - это перетягивание круга A. Из обоих кругов исходное положение, перемещение круга A будет соответствующим образом перемещать круг B. Но как только я отпущу мышь и попытаюсь снова перетащить Circle A, Circle B переместит x-количество единиц больше, чем Circle A x-position и y-количество единиц больше, чем Y-позиция Circle A. Поэтому каждый раз, когда я повторно нажимаю и перетаскиваю круг A, круг B увеличивается на новую позицию на своих собственных осях x и y на другом расстоянии при каждом нажатии кнопки мыши.

// 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 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();
}
2 ответа

Выяснил, в чем проблема. Проблема заключалась в том, что я не рассчитывал на поддержание расстояния между кругом A и кругом B при установке положения для круга B:

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

// helper for mimicking Circle A 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;


Вы могли бы сделать две булевы переменные, подобные этому, и окружить обработчики перемещения движения, если бы утверждения соответствовали этому:

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 3.0 with attribution.