2014-09-29 4 views
0

Итак, у меня есть программа, в которой я могу добавлять фигуры в JPanel с помощью объектов Path2D, а затем я могу щелкнуть и перетащить их. То, что я хочу сделать, - это найти окончательные координаты X и Y формы после ее появления. Координаты должны быть верхними левыми координатами. Есть идеи?Получение исходных координат X и Y формы Path2D на Jpanel

// add a circle to center of the screen 
public void addCircle(int width, int height) { 
    Path2D circ = new Path2D.Double(); 
    circ.append(new Ellipse2D.Double(getWidth()/2 - width/2, 
      getHeight()/2 - height/2, width, height), true); 
    shapes.add(circ); 
    repaint(); 
} 
      .................. 
//paint all shapes 
@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    this.setOpaque(true); 
    this.setBackground(Color.WHITE); 
    Graphics2D g2 = (Graphics2D) g; 
    g2.setStroke(new BasicStroke(2)); 
    for (Path2D shape : shapes) { 
     g2.draw(shape); 
    } 
} 
      .................. 
    // if the mouse click is in the circle, set pressed=true 
    @Override 
    public void mousePressed(MouseEvent e) { 
     if (e.getButton() != MouseEvent.BUTTON1) { 
      return; 
     } 
     for (int i = 0; i < shapes.size(); i++) { 
      if (shapes.get(i) != null 
        && shapes.get(i).contains(e.getPoint())) { 
       currentIndex = i; 
       pressed = true; 
       this.point = e.getPoint(); 
      } 
     } 
    } 

    //if pressed=true, move circle with mouse 
    @Override 
    public void mouseDragged(MouseEvent e) { 
     if (pressed && !lineSelected) { 
      int deltaX = e.getX() - point.x; 
      int deltaY = e.getY() - point.y; 
      shapes.get(currentIndex).transform(
        AffineTransform.getTranslateInstance(deltaX, deltaY)); 
      point = e.getPoint(); 
      //I need to find the new coordinates here!!!!!!!!!!! 
      repaint(); 
     } 
    } 

Полный код

class Canvas extends JPanel { 
private static final long serialVersionUID = 1L; 

private List<Path2D> shapes = new ArrayList<Path2D>(); 
private int currentIndex; 
private Point lineStartingPoint = new Point(); 
private Point lineEndingPoint = new Point(); 
private boolean drawing; 
private boolean lineSelected; 
private Path2D.Double linePath; 
private Shapes myShapes = new Shapes(); 
private List<Path2D> circles = new ArrayList<Path2D>(); 

public Canvas() { 
    MyMouseAdapter myMouseAdapter = new MyMouseAdapter(); 
    addMouseListener(myMouseAdapter); 
    addMouseMotionListener(myMouseAdapter); 
} 

public void setList(ArrayList<UMLCircle> shapes) { 

} 

public List<UMLCircle> getList() { 
    return null; 
} 

public void addSquare(int width, int height) { 
    Path2D rect2 = new Path2D.Double(); 
    rect2.append(new Rectangle(getWidth()/2 - width/2, getHeight()/2 
      - height/2, width, height), true); 

    shapes.add(rect2); 
    repaint(); 
} 

public void addLine() { 
    lineSelected = true; 
    repaint(); 
} 

public void addCircle(int width, int height) { 
    myShapes.addCircle(getWidth()/2 - width/2, getHeight()/2 - height 
      /2, width, height); 
    Path2D circ = new Path2D.Double(); 
    circ.append(new Ellipse2D.Double(getWidth()/2 - width/2, 
      getHeight()/2 - height/2, width, height), true); 
    circles.add(circ); 
    shapes.add(circ); 
    repaint(); 
} 

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    this.setOpaque(true); 
    this.setBackground(Color.WHITE); 
    Graphics2D g2 = (Graphics2D) g; 
    if (lineSelected) { 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setStroke(new BasicStroke(2)); 
     g2.drawLine(lineStartingPoint.x, lineStartingPoint.y, 
       lineEndingPoint.x, lineEndingPoint.y); 
    } 
    g2.setStroke(new BasicStroke(2)); 
    for (Path2D shape : shapes) { 
     g2.draw(shape); 
    } 
} 

class MyMouseAdapter extends MouseAdapter { 
    private boolean pressed = false; 
    private Point point; 

    @Override 
    public void mousePressed(MouseEvent e) { 
     if (e.getButton() != MouseEvent.BUTTON1) { 
      return; 
     } 
     for (int i = 0; i < shapes.size(); i++) { 
      if (shapes.get(i) != null 
        && shapes.get(i).contains(e.getPoint())) { 
       currentIndex = i; 
       pressed = true; 
       this.point = e.getPoint(); 
      } 
      if (circles.get(i) != null 
        && circles.get(i).contains(e.getPoint())) { 
       currentIndex = i; 
       pressed = true; 
       this.point = e.getPoint(); 
      } 
     } 
     if (lineSelected) { 
      drawing = true; 
      lineStartingPoint = e.getPoint(); 
      lineEndingPoint = lineStartingPoint; 
     } 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
     if (pressed && !lineSelected) { 
      int deltaX = e.getX() - point.x; 
      int deltaY = e.getY() - point.y; 
      shapes.get(currentIndex).transform(
        AffineTransform.getTranslateInstance(deltaX, deltaY)); 
      point = e.getPoint(); 
      myShapes.updateCircleLocation(currentIndex, point.x, point.y); 
      System.out.println(point.x + " " + point.y); 
      repaint(); 
     } 
     if (drawing) { 
      lineEndingPoint = e.getPoint(); 
      repaint(); 
     } 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     if (drawing && lineSelected) { 
      drawing = false; 
      lineSelected = false; 
      lineEndingPoint = e.getPoint(); 
      linePath = new Path2D.Double(); 
      linePath.moveTo(lineStartingPoint.getX(), 
        lineStartingPoint.getY()); 
      linePath.lineTo(lineEndingPoint.getX(), lineEndingPoint.getY()); 
      shapes.add(linePath); 
      repaint(); 
     } 
     pressed = false; 
    } 
} 
} 

EDIT

Расчет для смещения:

  int deltaX = e.getX() - point.x; 
      int deltaY = e.getY() - point.y; 
      shapes.get(currentIndex).transform(
        AffineTransform.getTranslateInstance(deltaX, deltaY)); 
      point = e.getPoint(); 
      int newXPos = e.getX() - deltaX; // final X pos 
      int newXPos = e.getX() - deltaX; // final Y pos 
+0

Вам нужно o рассчитать разницу между точкой пресса в положении x/y формы, это станет смещением. При перетаскивании фигуры вы вычтите смещение от точки мыши, каждый wod даст вам положение x/y, которое должна выглядеть фигура ... – MadProgrammer

+0

Учитывая, что вы добавите различные типы фигур, нет простого ответа, поскольку один стандарт способ вычисления точки не будет работать для всех. Например, вычисление верхнего левого угла квадрата, который будет простым, просто не будет работать для круга. Возможно, есть вопрос, на который вы можете получить ответ, который вы можете получить из ожидаемых конечных результатов. – MarGar

+0

@MadProgrammer. Я редактировал, чтобы добавить свои вычисления, но когда я рисую круг с заданными координатами X, Y, он немного выключен (круг немного нарисован в левом нижнем углу оригинала). Что я делаю не так? – Harry

ответ

3

Прежде чем делать что-либо, вы должны знать, к смещению щелчок мышью от t он угловой формы, это позволит вам перетащить объект, чтобы он не вдруг «скачок» к текущей позиции курсора мыши ...

@Override 
public void mousePressed(MouseEvent e) { 
    //... 
    for (Shape shape : myShapes) { 
      //... 
      this.point = e.getPoint(); 
      int deltaX = point.x - shape.getBounds().x; 
      int deltaY = point.y - shape.getBounds().y; 
      offset = new Point(deltaX, deltaY); 
      //... 
     } 
    } 
} 

Тогда, вы бы рассчитать дельту изменения, между текущую позицию мыши и смещение. Потому что вы подаете транслите, вам также необходимо вычесть текущее местоположение фигуры, как перевод основан на текущем местоположении фигуры, и мы только хотим, чтобы применить количество изменений

@Override 
public void mouseDragged(MouseEvent e) { 
    if (pressed) { 
     int index = myShapes.indexOf(clickedShape); 
     myShapes.remove(index); 

     int deltaX = e.getPoint().x - offset.x; 
     int deltaY = e.getPoint().y - offset.y; 

     clickedShape = new Path2D.Double(clickedShape, 
         AffineTransform.getTranslateInstance(
             deltaX - clickedShape.getBounds().x, 
             deltaY - clickedShape.getBounds().y)); 
     myShapes.add(index, clickedShape); 
     point = e.getPoint(); 
     repaint(); 
    } 
} 

Теперь, сказав все что, не делайте этого ...

protected void paintComponent(Graphics g) { 
    //... 
    this.setOpaque(true); 
    this.setBackground(Color.WHITE); 

Изменения состояния компонента внутри метода краски можно настроить бесконечный цикл перекрашивать запросы, которые могут чурку вашей системы. Кроме того, изменения не будут применены к текущему графического контекста, так как эти свойства, как правило, наносятся методом paint ...

И рабочая копия ....

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.RenderingHints; 
import java.awt.Shape; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.geom.AffineTransform; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Path2D; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

class Canvas extends JPanel { 

    private static final long serialVersionUID = 1L; 

    private boolean drawing; 
    private List<Shape> myShapes = new ArrayList<Shape>(); 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new Canvas()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public Canvas() { 
     MyMouseAdapter myMouseAdapter = new MyMouseAdapter(); 
     addMouseListener(myMouseAdapter); 
     addMouseMotionListener(myMouseAdapter); 
     addSquare(100, 100); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(400, 400); 
    } 

    public void setList(ArrayList<Shape> shapes) { 

    } 

    public List<Shape> getList() { 
     return null; 
    } 

    public void addSquare(int width, int height) { 
     Path2D rect2 = new Path2D.Double(); 
     rect2.append(new Rectangle(getWidth()/2 - width/2, getHeight()/2 
         - height/2, width, height), true); 

     myShapes.add(rect2); 
     repaint(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setStroke(new BasicStroke(2)); 
     for (Shape shape : myShapes) { 
      g2.draw(shape); 
     } 
    } 

    class MyMouseAdapter extends MouseAdapter { 

     private boolean pressed = false; 
     private Point point; 
     private Point offset; 
     private Shape clickedShape; 

     @Override 
     public void mousePressed(MouseEvent e) { 
      if (e.getButton() != MouseEvent.BUTTON1) { 
       return; 
      } 
      for (Shape shape : myShapes) { 
       if (shape != null 
           && shape.contains(e.getPoint())) { 
        System.out.println("Clicked"); 
        pressed = true; 
        clickedShape = shape; 
        this.point = e.getPoint(); 
        int deltaX = point.x - shape.getBounds().x; 
        int deltaY = point.y - shape.getBounds().y; 
        offset = new Point(deltaX, deltaY); 
        System.out.println(point + "x" + offset); 
        repaint(); 
        break; 
       } 
      } 
     } 

     @Override 
     public void mouseDragged(MouseEvent e) { 
      if (pressed) { 
       int index = myShapes.indexOf(clickedShape); 
       myShapes.remove(index); 

       int deltaX = e.getPoint().x - offset.x; 
       int deltaY = e.getPoint().y - offset.y; 

       clickedShape = new Path2D.Double(clickedShape, 
           AffineTransform.getTranslateInstance(
               deltaX - clickedShape.getBounds().x, 
               deltaY - clickedShape.getBounds().y)); 
       myShapes.add(index, clickedShape); 
       point = e.getPoint(); 
       repaint(); 
      } 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
      offset = null; 
      pressed = false; 
     } 
    } 
} 
+0

Я получил эту работу, но вы можете объяснить мне, где я могу назвать this.setOpaque (true); this.setBackground (Color.WHITE); '? Если я полностью удалю его, фон по-прежнему будет серым. Еще раз спасибо – Harry

+1

Вы можете называть его в другом месте, кроме как в контексте метода рисования.Причина, по которой это работает, - это первый раз, когда компонент окрашивается, вы меняете цвет фона, который вызывает другую перерисовку, другую перерисовку и другую перерисовку, другую перерисовку и другую перерисовку и другую перерисовку ... Поэтому вызовите эти методы в конструктор, где они принадлежат ... – MadProgrammer

+0

Ahhhhh, что имеет смысл. Понял, спасибо. – Harry

Смежные вопросы