2014-09-29 165 views
0

因此,我有一個程序,可以使用Path2D對象向JPanel添加形狀,然後單擊並拖動它們。我想要做的是能夠找到藥物後形狀的最終X和Y座標。座標需要爲左上座標。有任何想法嗎?爲抵消獲取在Jpanel上繪製的Path2D形狀的(起始)X和Y座標

// 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; 
    } 
} 
} 

編輯

計算:

  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 2014-09-29 21:00:41

+0

鑑於您將添加不同類型的形狀,因此作爲一個標準沒有簡單的答案計算積分的方法不適用於所有人。比如計算一個正方形的左上角,這很簡單,根本不適用於一個圓。也許有一個問題,你可以得到一個答案,你可以從預期的最終結果中得出答案。 – MarGar 2014-09-29 21:21:45

+0

@MadProgrammer我已經編輯過來添加我的計算,但是當我用給定的X,Y座標繪製圓時,它稍微偏離了一點(這個圓稍微向原始的左下方繪製)。我究竟做錯了什麼? – Harry 2014-09-29 22:55:03

回答

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方法中改變組件的狀態可以設置重繪請求,可以塞滿您的系統的無限循環。此外,你做不會應用到當前圖形上下文,因爲這些屬性通常由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 2014-10-01 01:19:40

+1

除了在繪畫方法的範圍內,您可以在任何地方調用它。它似乎工作的原因是組件第一次被繪製,你改變背景顏色,這會導致另一個重繪和另一個重繪,另一個重繪和另一個重繪,另一個重繪和另一個重繪...所以調用這些方法在構造函數,他們所屬... – MadProgrammer 2014-10-01 02:01:25

+0

這是有道理的啊。知道了謝謝。 – Harry 2014-10-01 02:21:23