// file SelectShape.java // Demo of Selection of drawn shapes // Harriet Fell // February 6, 2002 // Trying to transform the shape instead of the graphic2 import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; import java.awt.Shape.*; import java.util.Random; public class SelectShape extends JComponent implements MouseListener, MouseMotionListener { private MyShape myShapes [] = new MyShape[4]; private int mStartX, mStartY; // for last mouse position private final AffineTransform minRotation = AffineTransform.getRotateInstance(Math.PI); public SelectShape(int windowWidth) { // Listen for mouse movements and clicks addMouseMotionListener(this); addMouseListener(this); mStartX = 0; mStartY = 0; // Initialize Shapes for (int im = 0; im < 4; im++) { // Place shapes along the diagonal myShapes[im] = new MyShape(im*windowWidth/4, im*windowWidth/4); } myShapes[0].shape = new Rectangle2D.Double(myShapes[0].x0, myShapes[0].y0, windowWidth/5, windowWidth/5); myShapes[0].color = new Color(255, 0, 0); // red myShapes[1].shape = new Ellipse2D.Double(myShapes[1].x0, myShapes[1].y0, windowWidth/5, windowWidth/5); myShapes[1].color = new Color(0, 200, 200); // cyan myShapes[2].shape = new Arc2D.Double(myShapes[2].x0, myShapes[2].y0, windowWidth/5, windowWidth/5, 0, 270, Arc2D.PIE); myShapes[2].color = new Color(255, 150, 255); // light magenta myShapes[3].shape = new RoundRectangle2D.Double(myShapes[3].x0, myShapes[3].y0, windowWidth/5, windowWidth/5, windowWidth/25, windowWidth/25); myShapes[3].color = new Color(175, 0, 255); // violet } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; int wd = getSize().width; int ht = getSize().height; for (int im = 0; im < 4; im++) { // draw the shape. It is already transformed g2.setColor(myShapes[im].color); g2.fill(myShapes[im].shape); //g2.setStroke(new BasicStroke(10)); //g2.draw(myShapes[im].shape); g2.setColor(Color.black); // reset color to black //highlight selected Shape if (myShapes[im].selected) { g2.setPaint(Color.yellow); g2.setStroke(new BasicStroke(10)); g2.draw(myShapes[im].shape); // we can draw the shape instead of the bounding rectangle g2.setPaint(Color.black); g2.setStroke(new BasicStroke(1)); } } } public void mouseDragged(MouseEvent e) { AffineTransform at = new AffineTransform(); int xx = e.getX(); int yy = e.getY(); for (int im = 0; im < 4; im++) { if(myShapes[im].selected) { // at is the latest translation at.translate(xx - mStartX, yy - mStartY); // translate (x0, y0) myShapes[im].x0 += xx - mStartX; myShapes[im].y0 += yy - mStartY; // reset (mStartX, mStartY) mStartX = xx; mStartY = yy; // transform the shape by at myShapes[im].shape = at.createTransformedShape(myShapes[im].shape); } } repaint(); } public void mouseMoved(MouseEvent e) { int mods = e.getModifiers(); AffineTransform at = new AffineTransform(); for (int im = 0; im < 4; im++) { if(myShapes[im].selected) { if ((mods & InputEvent.SHIFT_MASK) != 0) { // rotate counter-clockwise if shift is down // reset shape transform at.translate(myShapes[im].x0, myShapes[im].y0); at.rotate(Math.PI/6); at.translate(-myShapes[im].x0, -myShapes[im].y0); // transform the shape myShapes[im].shape = at.createTransformedShape(myShapes[im].shape); } else if ((mods & InputEvent.CTRL_MASK) != 0) { // rotate clockwise if Ctrl is down at.translate(myShapes[im].x0, myShapes[im].y0); at.rotate(-Math.PI/6); at.translate(-myShapes[im].x0, -myShapes[im].y0); // transform shape myShapes[im].shape = at.createTransformedShape(myShapes[im].shape); } } } repaint(); } public void mousePressed(MouseEvent e) { mStartX = e.getX(); mStartY = e.getY(); } public void mouseReleased(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseClicked(MouseEvent e) { int x, y; x = e.getX(); y = e.getY(); boolean selected = false; // so at most one is selected below for (int im = 3; im >= 0; im--) { Point2D pt = new Point2D.Double(x, y); if (myShapes[im].shape.contains(pt) && !selected) { myShapes[im].selected = true; selected = true; } else myShapes[im].selected = false; } repaint(); } public static void main(String[] args){ JFrame f = new JFrame("Select"); int windowWidth = 600; Container c = f.getContentPane(); c.setLayout(new BorderLayout()); c.add(new SelectShape(windowWidth), BorderLayout.CENTER); f.setSize(windowWidth, windowWidth + 22); f.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setVisible(true); } }