Class TransformedFigureTutorial


  • public class TransformedFigureTutorial
    extends java.lang.Object
    This tutorial shows how to make custom figures that contain their own TransformContext. Transformed Figure Tutorial In the FigureTutorial class, we showed how to make a custom figure, and how to transform the various 2D shapes in the paint() method. Here, we will use an AffineTransform to do the same thing. This technique is a little more work to figure out how to do, but it's probably better if your figure has more than a couple of Shapes in it.

    Transforms are a little tricky to get right, so the Diva Canvas provides a class, TransformContext, that you need to use to give a figure its own transform. Each instance of TransformContext contains a single AffineTransform, and a bunch of methods that deal with it.

    The start of the CloudFigure class contains this code:

         private TransformContext _transformContext;
         private Rectangle2D _cachedBounds = null;
         private Shape _cachedShape = null;
    
         public CloudFigure (
                 double x, double y,
                 double width, double height ) {
    
             _transformContext = new TransformContext(this);
             AffineTransform at = _transformContext.getTransform();
             at.translate(x,y);
             at.scale(width/100, height/100);
             _transformContext.invalidateCache();
    
             ....
         }
     
    The initial shape of this figure is in fact a "cloud" shape that is located at (0,0) and is 100 units on each side. The internal transform is therefore initialized to scale this shape to the requested coordinates.

    Now, because the shape of this figure is fairly expensive to transform, the two instance variables _cachedBounds and _cachedShape store the bounds and shape for the current transform. If you look at the source code for this class, you will see that these are created and remembered in getBounds() and getShape(). In getShape(), for example, the internally-stored shape needs to be transformed into "external" coordinates:

         public Shape getShape () {
             if (_cachedShape == null) {
                 AffineTransform at = _transformContext.getTransform();
                 _cachedShape = at.createTransformedShape(_shape);
             }
             return _cachedShape;
         }
     
    Whenever the transform changes, these shapes must be cleared. For example:
         public void transform (AffineTransform at) {
             repaint();
             _cachedShape = null;
             _cachedBounds = null;
             _transformContext.preConcatenate(at);
             repaint();
         }
     

    The only other interesting thing about this class is the paint() method. Because paint() is called recursively down the tree of figures, the TransformContext class provides two methods that "stack" transform contexts as the tree is traversed. The paint() method calls push() and pop() before and after painting the figure's contents:

         public void paint (Graphics2D g) {
             _transformContext.push(g);
    
             ....
             // Paint the big cloud
             AlphaComposite c = AlphaComposite.getInstance(
                     AlphaComposite.SRC_OVER,0.5f);
             g.setComposite(c);
             g.setPaint(Color.magenta);
             g.fill(_shape);
    
             ....
             _transformContext.pop(g);
         }
     
    That's about all that's needed to use transform contexts in a figure.
    Version:
    $Id$
    Author:
    John Reekie
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      static class  TransformedFigureTutorial.CloudFigure
      CloudFigure is a class that paints itself as a translucent "cloud." This example figure class illustrates the use of different paints and strokes to create the required image, and the use of TransformContext to position that image.
    • Constructor Summary

      Constructors 
      Constructor Description
      TransformedFigureTutorial()
      Create a JCanvas and put it into a window.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void createFigures()
      Create instances of the class defined in this file.
      static void main​(java.lang.String[] argv)
      Main function
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • TransformedFigureTutorial

        public TransformedFigureTutorial()
        Create a JCanvas and put it into a window.
    • Method Detail

      • createFigures

        public void createFigures()
        Create instances of the class defined in this file. To make the demo a little more interesting, make them draggable.
      • main

        public static void main​(java.lang.String[] argv)
        Main function