Java AWT QuadCurve2D show draggable control point
import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.QuadCurve2D; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; class MyBoard extends JComponent implements MouseListener, MouseMotionListener { private boolean selectedShape; private boolean hoveredShape; private QuadCurve2D s = new QuadCurve2D.Float(50, 50, 125,210, 150, 50); private Point2D translatePt; private Point2D anchorPt; private AffineTransform moveTranslate = new AffineTransform(); private int moveType = -1; public static final int START_POINT = 1; public static final int CNTRL_POINT = 2; public static final int END_POINT = 3; public static final int MOVE = 4; @Override/*from w w w.jav a2s . co m*/ protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setBackground(Color.WHITE); g2d.clearRect(0, 0, getParent().getWidth(), getParent().getHeight()); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.drawString("Bounded Rectangle " + s.getBounds2D().getX() + ", " + s.getBounds2D().getY(), 10, 20); AffineTransform origTransform = g2d.getTransform(); if (selectedShape && translatePt != null && moveType == MOVE) { moveTranslate.setToTranslation(translatePt.getX() - anchorPt.getX(), translatePt.getY() - anchorPt.getY()); g2d.setTransform(moveTranslate); } g2d.draw(s); if (hoveredShape) { g2d.setColor(Color.LIGHT_GRAY); float dash[] = { 2, 2 }; g2d.setStroke(new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, dash, 0)); g2d.draw(s.getBounds2D()); } if (selectedShape) { g2d.setColor(Color.RED); float dash[] = { 2, 2 }; g2d.setStroke(new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, dash, 2)); g2d.draw(s.getBounds2D()); g2d.setPaint(Color.BLACK); g2d.setStroke(new BasicStroke(1)); Rectangle2D ctrl1Rect = new Rectangle2D.Double(s.getCtrlPt().getX() - 2, s.getCtrlY() - 2, 5, 5); g2d.draw(ctrl1Rect); Rectangle2D startPtRect = new Rectangle2D.Double(s.getX1() - 2, s.getY1() - 2, 5, 5); g2d.setPaint(Color.WHITE); g2d.fill(startPtRect); g2d.setPaint(Color.BLACK); g2d.draw(startPtRect); Rectangle2D endPtRect = new Rectangle2D.Double(s.getX2() - 2, s.getY2() - 2, 5, 5); g2d.setPaint(Color.WHITE); g2d.fill(endPtRect); g2d.setPaint(Color.BLACK); g2d.draw(endPtRect); } g2d.setTransform(origTransform); } @Override public void mouseClicked(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { boolean anySelected = false; if (selectedShape) { Rectangle2D ctrl1Rect = new Rectangle2D.Double(s.getCtrlX() - 2, s.getCtrlY() - 2, 5, 5); if (ctrl1Rect.contains(e.getPoint())) { moveType = CNTRL_POINT; repaint(); return; } Rectangle2D startRect = new Rectangle2D.Double(s.getX1() - 2, s.getY1() - 2, 5, 5); if (startRect.contains(e.getPoint())) { moveType = START_POINT; repaint(); return; } Rectangle2D endRect = new Rectangle2D.Double(s.getX2() - 2, s.getY2() - 2, 5, 5); if (endRect.contains(e.getPoint())) { moveType = END_POINT; repaint(); return; } if (s.contains(e.getPoint())) { moveType = MOVE; anchorPt = (Point2D) e.getPoint().clone(); repaint(); return; } } if (s.contains(e.getPoint()) && !selectedShape) { selectedShape = true; anySelected = true; } if (!anySelected) { selectedShape = false; } repaint(); } @Override public void mouseReleased(final MouseEvent e) { moveType = -1; if (anchorPt != null) { double dx = e.getPoint().getX() - anchorPt.getX(); double dy = e.getPoint().getY() - anchorPt.getY(); // update all points in shape s.setCurve(s.getX1() + dx, s.getY1() + dy, s.getCtrlX() + dx, s.getCtrlY() + dy, s.getX2() + dx, s.getY2() + dy); // reset for subsequent drag operation anchorPt = null; translatePt = null; } repaint(); } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mouseDragged(MouseEvent e) { if (selectedShape) { switch (moveType) { case START_POINT: s.setCurve(e.getPoint(), s.getCtrlPt(), s.getP2()); break; case CNTRL_POINT: s.setCurve(s.getP1(), e.getPoint(), s.getP2()); break; case END_POINT: s.setCurve(s.getP1(), s.getCtrlPt(), e.getPoint()); break; case MOVE: translatePt = e.getPoint(); break; } } repaint(); } @Override public void mouseMoved(MouseEvent e) { // move over shape if (s.contains(e.getPoint()) && !hoveredShape) { hoveredShape = true; } // move away from shape if (!s.contains(e.getPoint()) && hoveredShape) { hoveredShape = false; } repaint(); } } public class Main { public static void main(String[] args) { // create frame for Main JFrame frame = new JFrame("java2s.com"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Main Main = new Main(); MyBoard c = new MyBoard(); c.addMouseListener(c); c.addMouseMotionListener(c); c.setPreferredSize(new Dimension(409, 726)); frame.add(c); frame.setSize(300, 210); frame.setVisible(true); } }