Review Graphics2D class for drawing shapes in a component – paintComponent(Graphics g) – Graphics2D g2 = (Graphics2D)g; (0, 0) is the components upper-left corner Shapes: Line2D, Rectangle2D,... draw(Shape s) fill(Shape s) drawImage(Image img, – int dx1, int dy1, int dx2, int dy2, – int sx1, int sy1, int sx2, int sy2) drawString(String str, int x, int y)
A Similar Problem: Double Sponge Bob Lets solve a problem that is similar to the Image Navigator problem – Create two frame windows, each containing an instance of the Sponge Bob component – Allow each window to be scaled and translated – Keep the origins of the two windows in synch so that translating one window will perform an equivalent translation in the other window – Demo: Double Sponge Bob (Scaling, Translation, Synch)Double Sponge Bob (Scaling, Translation, Synch)
The Hard Part: Coordinate Transformations Shape dimensions and locations are defined in terms of unscaled, untranslated coordinates – We call these world coordinates Each window has its own scaling and translation settings This complicates three things: – Drawing shapes in each window at the appropriate scale and location – Doing hit testing on the shapes when mouse events occur – Keeping the translation settings of the two windows in synch When drawing shapes in a window, we must convert the shape dimensions and locations defined in world coordinates to device coordinates that can be used for drawing This conversion must account for the current scale and translation settings of the window
The Hard Part: Coordinate Transformations Example – Suppose that a window currently has a scaling factor of 0.5, and a translation of 10 pixels in the X direction and 20 pixels in the Y direction (i.e., Point (10, 20) is in the top-left corner of the window) – A shape that is 400 pixels wide in world coordinates will be drawn only 200 pixels wide in device coordinates – A shape that is located at position (250, 300) in world coordinates will be drawn at position (240, 280) in device coordinates
Scaling Start with code that implements neither scaling nor translation nor window synchronization – Double Sponge Bob (No Transforms) Double Sponge Bob (No Transforms) Now, add code to implement scaling – Add scale field to DrawingComponent and initialize to 1.0 in constructor – Add setScale method to DrawingComponent – Add slider change listener to DrawingFrame – Add methods to DrawingComponent for converting between world and device coordinates (in both directions) – Update draw methods on all DrawingShape sub-classes to handle scale – Double Sponge Bob (Scaling) Double Sponge Bob (Scaling)
Translation Start with code that implements scaling but not translation or window synchronization – Double Sponge Bob (Scaling) Double Sponge Bob (Scaling) Now, add code to implement translation – Add fields to DrawingComponent for tracking the current origin (in world coordinates), and initialize them to (0,0) in the constructor – Modify methods that convert between world and device coordinates to handle translation – Add fields and methods for implementing mouse-based translation of shapes (deltas in device coordinates must be scaled to compute equivalent deltas in world coordinates) – Double Sponge Bob (Scaling & Translation) Double Sponge Bob (Scaling & Translation)
Window Synchronization Start with code that implements scaling and translation but not window synchronization – Double Sponge Bob (Scaling & Translation) Double Sponge Bob (Scaling & Translation) Now, add code to implement translation – Add DrawingListener interface – Add list of listeners and addDrawingListener method to DrawingComponent – Add notifyOriginChanged method to DrawingComponent and call it from mouseDragged – Implement two listeners on the Drawing class (one for each window), add addDrawingListener method to DrawingFrame, and add a listener to each frame in Drawing – Add setOrigin methods to DrawingComponent and DrawingFrame – Double Sponge Bob (Scaling & Translation & Synch) Double Sponge Bob (Scaling & Translation & Synch)
Swing Coordinate Transformations In Swing, there is actually a much easier way to draw shapes according to the current scaling and translation settings The Graphics2D class can be configured to perform scaling, translation, and other transformations automatically on all drawing operations – scale(…), translate(…), rotate(…), shear(…) methods There is no need to manually scale shape sizes or adjust shape locations. Graphics2D does all of this automatically You still need methods to convert between world and device coordinates to do hit testing on mouse events Example: Double Sponge Bob (Swing Transforms)Double Sponge Bob (Swing Transforms)
Image Navigator How can we apply these ideas to keep the Image Panel and Image Navigator in synch in the Record Indexer project?
Image Navigator How can we apply these same ideas to keep the Image Panel and Image Navigator in synch in the Record Indexer project? – The Image Panel has its own scale and translation settings – The Image Navigator has its own scale setting (based on its current size) – Conversions between device and world coordinates are similar to the Double Sponge Bob example – Zooming in Image Panel preserves the center point (i.e., the point at the center of the window should stay fixed during zooming) – Image Panel keeps track of the current center point (in world coordinates) – The Image Navigator can query the Image Panel for the currently visible rectangle (so it can draw the navigator rectangle) – The Image Navigator can adjust the Image Panels center point as the navigator rectangle is dragged
Your consent to our cookies if you continue to use this website.