Last week, we had the author of TDD for a Shopping Website LiveProject. Friday at 11am Ranch time, Steven Solomon will be hosting a live TDD session just for us. See for the agenda and registration link
I had an assignment whihc required exactly that. I used a Rectangle2D object for the drawing, encapsulated inside what I called a RectangleShape object (to avoid confusion with other classes). Note the Rectangle2D and Ellipse2D both inherit from the java.awt.geom.RectangularShape class, which has methods to set its bounding box from a diagonal or from its corners.
Resizing: I added a MouseMotionListener to the panel the shape was drawn on (I had to swap Listeners depending on the shape being drawn). Then the mouseDragged method can be used to move one or other of the corners of the bounding box. Easy
Rotation. Difficult. I had no end of trouble with it. Find the AffineTransform class and look at its methods. You will find some of the methods duplicated in the Graphics2D class, which I actually used myself.
Problem 1: Using the Transforms slowed down the rendering (without transforms is took about 1.6 microseconds to paint an object, with transforms anything from 40 to 80 microseconds, reducing to about 8 microseconds on subsequent calls with the same parameters). This gave rise to a nasty effect where dragging the window or dragging another window over it left multiple borders. I couldn't work out how to sort it out, and in a fit of desperation I added a javax.swing.Timer to the app which calls "repaint();" repeatedly. I found that a delay of 333 (1/3 second) reduced the border duplication to imperceptible.
Problem 2: After you have put a transform on, you have to take it off again. Otherwise it is still there for any shapes added subsequently. I tried several tricks, and eventually settled for setting the transform at the start of the method and setting the same with the opposite sign at the end of the method. I didn't think of a better solution until after I had to hand it in: clone the Graphics2D object, and apply the transform to the clone only. I still found that combining rotation and shearing tended to alter the scale of shapes added later.
Problem 3: Transforms take effect at the origin of the Panel, so you have to translate the origin. I am afraid I haven't got enough time to explain that just at the moment. The revering technique
My, what a lot of spellling errors in my last post. About the origin: You need to move your rectangle, so its centre lies over the origin, then, using the translate transform, move the origin to where the centre of the rectangle used to be. Then [clone and] rotate [and, if not cloned, rotate back], and move the origin back to where it used to be.
Problem 4: There are two sorts of method. There is AffineTransform.rotate(), which rotates the Graphics2D object, and there is AffineTransform.setToRotation(), which rotates and deletes other transforms. You need to decide which type of method you want. There is also, if I remember correctly, a rotate() method in Graphics2D. This does the same as AffineTransform.rotate().
There are 4 basic transformations:
Scaling (in [i]x[/b] and [i]y[/b] directions),
Translation (in [i]x[/b] and [i]y[/b] directions),
Shear (in [i]x[/b] and [i]y[/b] directions), and
There is a brief introduction to Affine Transforms in, C Horstmann and G Cornell, Core Java 2: Volume II Advanced Features, Santa Clara CA: Sun Microsystems Press (Prentice-Hall) 2004, page 488-496.