diva.canvas.tutorial
Class FigureTutorial

java.lang.Object
  extended by diva.canvas.tutorial.FigureTutorial

public class FigureTutorial
extends java.lang.Object

An example showing how to make custom figures.

Although the Diva Canvas provides a number of pre-built concrete figures in diva.canvas.toolbox (BasicFigure is used in many of the examples), you will in general want to define your own Figure classes. The Diva Canvas deliberately does not attempt to hide the power of the Java2D API, but instead to augment it. This means that anything but the simplest types of Figure require some knowledge of Java2D.

In general, defining a completely new type of Figure means implementing the Figure interface. However, it is usually simpler just to subclass the AbstractFigure class and override at least the methods getShape(), transform(), and paint(). The example in this file does that to create a new leaf figure. Our example (see the source file for the complete code) extends AbstractFigure:

     public class CustomRectangle extends AbstractFigure {
         private Rectangle2D _bounds;
         public CustomRectangle (
                 double x, double y,
                 double width, double height) {
             _bounds = new Rectangle2D.Double(x,y,width,height);
         }

         ....
     }
 

The appearance of this figure is shown in the image above (the yellow outline is the highlighting, and is not part of this figure). It has a fill, a 1-point black outline, and some additional stuff drawn on it.

Let's look at the individual methods of this class. The getBounds() method gets the shape of the figure's stroke outline, and then takes the bounding box of that shape. (If we were to simply return _bounds, part of the outline would fall outside the bounding box and we would get "dirt" on the screen when we moved the figure.)

     public Rectangle2D getBounds () {
         Stroke s = new BasicStroke(1.0f);
         return s.createStrokedShape(_bounds).getBounds2D();
     }
 

The getShape() method simply returns the outline rectangle. getShape() is used by methods in the Diva canvas to do things like place grab-handles on figures and to put highlights around them:

     public Shape getShape () {
         return _bounds;
     }
 

The paint() method is where most of the work (in this example) is done. Note that the argument is an instance of java.awt.Graphics2D. This method will be called in the event thread whenever AWT redraws the JCanvas that contains this figure. We won't show all of this method here, just the start:

     public void paint (Graphics2D g) {
         Stroke s = new BasicStroke(1.0f);
         g.setStroke(s);
         g.setPaint(Color.blue);
         g.fill(_bounds);
         g.setPaint(Color.black);
         g.draw(_bounds);

         ....
      }
 
Finally, the transform() method transforms the figure. This method is used whenever a figure is scaled or moved. Note that this code calls the repaint() method before and after transforming the figure shape. This ensures that the screen is properly redrawn.
     public void transform (AffineTransform at) {
         repaint();
         _bounds = (Rectangle2D) CanvasUtilities.transform(_bounds, at);
         repaint();
     }
 
There are other methods that may need to be over-ridden, depending on what exactly your figure class does. For more information on the methods of Figure, see the API documentation.

A simpler, although somewhat slower executing, way to specify the look of a figure is to create a GIF file that looks like the figure. The GIF file can be loaded into an Image and the Image embedded into a figure. An ImageFigure does exactly this.

         // Create an image figure and make it draggable
         Image img = Toolkit.getDefaultToolkit().getImage(IMAGE_FILE_NAME);
         MediaTracker tracker = new MediaTracker(canvas);
         tracker.addImage(img,0);
         try {
             tracker.waitForID(0);
         }
         catch (InterruptedException e) {
             System.err.println(e + "... in FigureTutorial");
         }
         ImageFigure imgFig = new ImageFigure(img);
         imgFig.translate(300,100);
         layer.add(imgFig);
         imgFig.setInteractor(defaultInteractor);
 
The media tracker is responsible for waiting for the image to be completely loaded from the file before creating the ImageFigure. After being created, the ImageFigure can be used exactly like other figures.

There are also other ways of creating new Figure classes. You can subclass AbstractFigureContainer to produce a new figure class that contains other figures. You can also subclass FigureWrapper to add application-specific behavior to an existing figure class by "wrapping" it.

Version:
$Id: FigureTutorial.java 47561 2007-12-16 07:29:50Z cxh $
Author:
John Reekie

Nested Class Summary
static class FigureTutorial.CustomRectangle
          CustomRectangle is a class that paints itself as a rectangle and draw a red plus sign over the top of itself.
 
Field Summary
private  JCanvas canvas
           
private  GraphicsPane graphicsPane
           
static java.lang.String IMAGE_FILE_NAME
          The file name for the image that is displayed.
 
Constructor Summary
FigureTutorial()
          Create a JCanvas and put it into a window.
 
Method Summary
 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
 

Field Detail

IMAGE_FILE_NAME

public static final java.lang.String IMAGE_FILE_NAME
The file name for the image that is displayed.

See Also:
Constant Field Values

canvas

private JCanvas canvas

graphicsPane

private GraphicsPane graphicsPane
Constructor Detail

FigureTutorial

public FigureTutorial()
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.

Parameters:
argv - The arguments, currently ignored.