新規グラフィック・オブジェクト・クラスの作成

新しいグラフィック・オブジェクト・クラスを作成する手順は、ジオメトリー・プロパティーと描画を処理するメソッドを定義する部分と、オブジェクトを永続化する部分で構成されます。
この例では、クラス ShadowEllipse を作成します。ShadowEllipse 例の完全なソース・コードは、 <installdir> /jviews-framework89/codefragments/shadow-ellipse/src/ShadowEllipse.javaにあります。

手順 1 - クラスの作成

クラスを作成するには、以下の手順に従います。
  1. 新規クラスと必要なオーバーロードしたメソッドを定義する ShadowEllipse.java という名前のファイルを作成します。すべてのメソッドをオーバーロードする必要はありません。
  2. ファイルの最初に次のステートメントを追加します。
    import ilog.views.*;
    import ilog.views.io.*;
    import ilog.views.graphic.*;
    import java.awt.*;
    import java.io.*;
    
    これらのステートメントを追加すると、Rogue Wave JViews ライブラリーの基本、入出力、グラフィック・パッケージを使用できます。
  3. IlvGraphic クラスから継承するクラスを定義します。
    このクラスには、楕円に 1 つと影用に 1 つ、2 つの色があります。影の太さも定義します。
  4. オブジェクトの矩形領域を定義します。
    これを行うには、タイプが IlvRectdrawrect という名前のメンバー変数を追加します。
    import ilog.views.*;
    import ilog.views.io.*;
    import ilog.views.graphic.*;
    import java.awt.*;
    import java.io.*;
     
    /**
     * A shadow ellipse object. A graphic object defined by two
     * ellipses: The main ellipse and a second ellipse of the same
     * size underneath the first one that represents a shadow.
     */
    public class ShadowEllipse
    extends IlvGraphic
    {
      /**
       * The definition rectangle of the ellipse.
       * This rectangle is the bounding rectangle of the
       * graphic object.
       */
      protected final IlvRect drawrect = new IlvRect();
      /**
       * The color of the ellipse.
       */
      private Color  color = Color.blue;
      /** 
       * The color of the shadow.
       */
      private Color  shadowColor = Color.black;
      /**
       * The thickness of the shadow.
       */
      private int thickness = 5;
    

手順 2 - コンストラクターの定義

  • コンストラクターを定義して、新規の影付き楕円を作成します。これらのコンストラクターは、定義矩形の値を設定するか、または既存の ShadowEllipse インスタンスから新規の ShadowEllipse を作成します。
      /**
       * Creates a new shadow ellipse.
       * @param rect the bounding rectangle of the shadow ellipse.
       */
      public ShadowEllipse(IlvRect rect)
      {
        super();
        // Stores the bounding rectangle of the object.
        drawrect.reshape(rect.x, rect.y, rect.width, rect.height);
      }
    
    /**
       * Creates an ellipse by copying another one.
       * @param source the object to copy.
       */
      public ShadowEllipse(ShadowEllipse source) 
      {
        // First call the superclass constructor 
        // that will copy the information of the superclass.
        super(source);
    
        // Copies the bounding rectangle.
        drawrect.reshape(source.drawrect.x, source.drawrect.y, 
    		     source.drawrect.width, source.drawrect.height);
        // Copies the color and the color of the shadow.
        setColor(source.getColor());
        setShadowColor(source.getShadowColor());
        // Copies the thickness
        setThickness(source.getThickness());
      }
    
    

手順 3 - draw メソッドのオーバーライド

  • AWT Graphics クラスに含まれているプリミティブ・メソッドを呼び出して、オブジェクトを描画します。
    /**
       * Draws the object.
       * Override the draw method to define the way the object will appear.
       * @param dst The AWT object that will perform the
       * drawing operations. 
       * @param t This parameter is the transformer used to draw the object.
       * This parameter may be a translation, a zoom or a rotation.
       * When the graphic object is drawn in a view (IlvManagerView),
       * this transformer is the transformer of the view.
       */
      public void draw(Graphics dst, IlvTransformer t)
      {
        // First copy the rectangle that defines the bounding
        // rectangle of the object so that it is not modified.
         
        IlvRect r = new IlvRect(drawrect);
         
        // To compute the bounding rectangle of the object in 
        // the view coordinate system, apply the transformer ’t’
        // to the definition rectangle.
        // The transformer may define a zoom, a translation or a rotation.
         
        // applyFlooris used so the resulting rectangle
        // is correctly projected for drawing in the view.
        // The object’s coordinate system is defined by ’float’ values
        // Need ’int’ values to be able to draw. applyFloor will
        // apply the transformation to ’r’ and then call Math.floor to
        // translate ’float’ values to ’int’ values.
        if (t != null) 
          t.applyFloor(r);
        else
          r.floor();
         
        // The variable ’r’ now contains the bounding rectangle
        // of the object in the view’s coordinate system ready to
        // draw in this rectangle. In this rectangle, two ellipses
        // are drawn: first the shadow ellipse on the bottom
        // right corner of the definition rectangle, then the main
        // ellipse on the top-left corner. Each ellipse will be of size
        // (r.width-thickness, r.height-thickness).
     
        int thick = thickness;
     
        // Computes a correct value for thickness.
        // Since the size of the ellipses should
        // be (r.width-thickness, r.height-thickness), need to
        // check that the thickness is not too big.
     
        if ((r.width <= thick) || (r.height <= thick))
          thick = (int)Math.min(r.width, r.height);
     
        // Sets the size of the ellipses.
        r.width  -= thick;
        r.height -= thick;
               
        // ’r’ now contains the bounding area of the main ellipse.
     
        // Computes a rectangle to draw the shadow.
        // Copy the variable ’r’, needed for the
        // second ellipse.
        IlvRect shadowRect = new IlvRect(r);
        shadowRect.translate(thick, thick);
     
        // Draws the shadow ellipse
        dst.setColor(getShadowColor());
        dst.fillArc((int)shadowRect.x, 
                    (int)shadowRect.y, 
                    (int)shadowRect.width, 
                    (int)shadowRect.height,
                    0, 360);
     
        // Draws the main ellipse.
        dst.setColor(getColor());
        dst.fillArc((int)r.x, 
                    (int)r.y, 
                    (int)r.width, 
                    (int)r.height,
                    0, 360);
      }
    
draw メソッドは 2 つの楕円を塗りつぶします。矩形領域 drawrect は、実際には両方の楕円を囲みます。
メモ
fillArc などの AWT メソッドでは、すべての座標が整数である必要があります。ただし、Rogue Wave JViews では、グラフィック・オブジェクトのバウンディング・ボックスは float 値で定義されます。座標を float から int に変換する場合は、IlvTransformer クラスの applyFloor および floor メソッドを使用します。同じ技法を使用して、他のオブジェクトがライブラリーに適合するようにする必要があります。

手順 4 - boundingBox メソッドのオーバーライド

  • boundingBox メソッドを定義して、バウンディング・ボックスを変換します。トランスフォーマーが null であっても、矩形 drawrect のコピーを作成します。これにより、返された矩形を Rogue Wave JViews で変更することができます。
     /**
       * Computes the bounding rectangle of the graphic 
       * object when drawn with the specified transformer.
       */
      public IlvRect boundingBox(IlvTransformer t)
      {
        // First copy the definition rectangle
        // so that it is not modified.
        IlvRect rect = new IlvRect(drawrect);
        // Apply the transformer on the rectangle to
        // translate to the correct coordinate system.
        if (t != null) t.apply(rect);
        return rect;
      }
    

手順 5 - applyTransform メソッドのオーバーライド

  • applyTransform メソッドをオーバーライドして、ShadowEllipse 矩形の形状に変換を適用します。
     public void applyTransform(IlvTransformer t)
      {
        // This method is called by method such as IlvGraphic.move
        // IlvGraphic.rotate or IlvGraphic.scale to modify the
        // shape of the object. For example, when this method
        // is called from IlvGraphic.move, the parameter 't' is the
        // corresponding translation.
        // Simply need to apply the transformer to
        // the definition rectangle of the object.
        t.apply(drawrect);
      }
    

手順 6 - copy メソッドのオーバーライド

  • コピー・メソッドをオーバーライドして、新しいインスタンスを作成するため ShadowEllipse コピー・コンストラクターを呼び出します。
     /**
       * Copies the object.
       */
      public IlvGraphic copy()
      {
        // Simply call the copy constructor that is defined above.
        return new ShadowEllipse(this);
      }
    

手順 7 - アクセサーの定義

  • グラフィック・オブジェクトにパブリック・アクセサーを追加します。これらのアクセサーは太さと色を処理します。以下のコード例ではこれらは、太字 体で表示されます。
      /** 
       * Changes the thickness of the shadow ellipse 
       * @param thickness the new thickness
       */ 
      public void setThickness(int thickness) 
      { 
        this.thickness = thickness; 
      } 
     
      /** 
       * Returns the thickness of the shadow ellipse 
       * @return the thickness of the object. 
       */ 
      public int getThickness() 
      { 
        return thickness; 
      } 
     
      /** 
       * Changes the color of the ellipse. 
       * @param color the new color. 
       */ 
      public void setColor(Color color) 
      { 
        this.color = color; 
      } 
     
      /** 
       * Returns the color of the shadow ellipse 
       * @return the color of the object. 
       */ 
      public Color getColor() 
      { 
        return color; 
      } 
     
      /** 
       * Changes the color of the shadow 
       * @param color the new color 
       */ 
      public void setShadowColor(Color color) 
      { 
        this.shadowColor = color; 
      } 
       
      /** 
       * Returns the color of the shadow 
       * @return the color of the shadow 
       */ 
      public Color getShadowColor() 
      { 
        return shadowColor; 
      }