2015-03-17 3 views
1

Я работаю над некоторым кодом для перетаскивания фигуры (в настоящее время квадрата) вокруг контейнера (JPanel). Я смог нарисовать синий квадрат, и мой слушатель мыши работает, потому что я могу перетащить квадрат. НО все еще не делает то, что я хочу, по следующим причинам:Перетаскивание фигуры в Java

  1. Я могу только перетаскивать форму по диагонали. Другими словами, независимо от того, где я перемещаю мышь, форма только перемещается по диагонали вверх или вниз по экрану.

  2. Я могу только перетащить форму один раз. Другими словами, если я щелкнул внутри фигуры, перетащил ее в новую позицию, а затем отпустил мышь, вот и все - я не могу ее переместить без перезапуска программы.

Вот соответствующие (я надеюсь!) Разделы моего кода:

  1. Декларация класса DragPanel (в основном расширением JPanel):

    public class DragPanel extends JPanel implements MouseListener, MouseMotionListener 
    { 
    Graphics2D g2; 
    Rectangle2D square; 
    Color colour; 
    
    double x1, y1, x2, y2, size; 
    double offsetX, offsetY; 
    
    boolean dragging = false; 
    
  2. Constructor метод:

    public DragPanel() 
    { 
    
    x1 = 10.0; 
    y1 = 10.0; 
    size = 40.0; 
    x2 = x1 + size; 
    y2 = y1 + size; 
    
    square = new Rectangle2D.Double(x1, y1, size, size); 
    colour = Color.BLUE; 
    
    setFocusable(true); 
    addMouseListener(this); 
    addMouseMotionListener(this); 
    this.requestFocus(); 
    
    } 
    
  3. PaintComponent Метод и MouseDragged, MousePressed, MouseReleased методы:

    public void paintComponent(Graphics g) 
    { 
    
    super.paintComponent(g); 
    g2 = (Graphics2D) g; 
    g2.draw(square); 
    g2.setColor(colour); 
    g2.draw(square); 
    
    } 
    
    @Override 
    public void mouseDragged(MouseEvent ev) 
    { 
        if (dragging) 
        { 
        double mx = ev.getX(); 
        double my = ev.getY(); 
    
        x1 = mx - offsetX; 
        y1 = mx - offsetY; 
        square = new Rectangle2D.Double(x1, y1, size, size); 
        repaint(); 
        } 
    
    } 
    
    @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; 
    } 
    
    } 
    
    @Override 
    public void mouseReleased(MouseEvent arg0) 
    { 
    dragging = false; 
    } 
    

ответ

1

в mouseDragged()

x1 = mx - offsetX; 
y1 = mx - offsetY; 

должен быть

x1 = mx - offsetX; 
y1 = my - offsetY; 
x2 = x1 + size; 
y2 = y1 + size; 

Вам необходимо обновить все границы площади каждый раз, когда он перемещался. Вместо явного хранения их в переменных экземпляра я использую встроенные прямоугольные 2D-методы, такие как getMinX() и getMaxX()

+0

по электронной почте Ой! Теперь я чувствую себя идиотом! ;-) (Хотя я знаю, что это было не ваше намерение!) – Sam

+0

Хорошо, что сработало, но я все еще не могу перетаскивать не один раз. Я думаю, что это имеет какое-то отношение к «dragging = false» в методе mouseReleased(), потому что когда я удаляю это, он работает, но тогда у меня нет способа остановить перемещение квадрата, если перетаскивание мышью находится за пределами квадрата. – Sam

+0

@Sam обнаружил проблему с перетаскиванием несколько раз – vandale

0

Хорошо, я получил его на работу! Я должен был добавить:

 x2 = x1 + size; 
     y2 = y1 + size; 

К моему методу mouseDragged() следующим образом:

@Override 
public void mouseDragged(MouseEvent ev) 
{ 
    if (dragging) 
    { 
     double mx = ev.getX(); 
     double my = ev.getY(); 

     x1 = mx - offsetX; 
     y1 = my - offsetY; 
     x2 = x1 + size; 
     y2 = y1 + size; 
     square = new Rectangle2D.Double(x1, y1, size, size); 
     repaint(); 
    } 


}