最大 2 つの曲折点をもつリンク形状ポリシーの作成

この例では、曲折点がないか、曲折点が 1 つまたは 2 つのリンクを許可するリンク形状ポリシーを作成します。曲折点が 1 つまたは 2 つの場合、リンクは直交形状になります。リンク形状ポリシーでは 3 つ以上の曲折点の作成は禁止されています。
fwadv_linkshape5.gif
曲折点がないか、1 つまたは 2 つの場合のリンク形状ポリシー
原則的に、このリンク形状ポリシーは、クラス IlvOneLinkImage とクラス IlvDoubleLinkImage の機能を組み合わせたものです (『JViews Framework 基本編 』の「リンク 」を参照)。ただし、リンク形状ポリシーを使用することは、柔軟性に優れています。リンク形状ポリシーはリンクで有効または無効にでき、曲折点が 1 つのイメージから曲折点が 2 つのイメージに変更できるからです。
クラス IlvAbstractLinkShapePolicy は、インターフェース IlvLinkShapePolicy のメソッドをすべて空のメソッドとして定義するので、新規リンク形状ポリシーに適した基本クラスです。
public class MyLinkShapePolicy
    extends IlvAbstractLinkShapePolicy
{
    ...
}
オーバーライドする必要があるわずかのメソッドに集中できます。
リンク形状ポリシーを作成するには、以下の手順に従います。
  1. ポリシーに従ってリンクを形状変更する補助メソッドを作成します。曲折点の数および水平と垂直の距離によって、リンクに使用する形状を決定できます。以下に例を示します。
    private void verifyLinkPoints(IlvLinkImage link)
    {
        if (link == null)
          return;
    
        IlvPoint[] pts = link.getLinkPoints(null);
        int n = pts.length;
        if (n <= 2) return;
    
        IlvRect fromrect = link.getFromBoundingBox(null);
        IlvRect torect = link.getToBoundingBox(null);
        float fx = fromrect.x + 0.5f * fromrect.width;
        float fy = fromrect.y + 0.5f * fromrect.height;
        float tx = torect.x + 0.5f * torect.width;
        float ty = torect.y + 0.5f * torect.height;
        float dx = (fx < tx ? 0.5f : -0.5f);
        float dy = (fy < ty ? 0.5f : -0.5f);
    
        if (n == 3) {
          link.movePoint(0, fx + dx * fromrect.width, fy, null);
          link.movePoint(1, tx, fy, null);
          link.movePoint(2, tx, ty - dy * torect.height, null);
          return;
        }
    
        if (Math.abs(fx - tx) > Math.abs(fy - ty)) {
          float middleX = 0.5f * (fx + tx +
                            dx * (fromrect.width - torect.width));
          pts[1].move(middleX, fy);
          pts[2].move(middleX, ty);
          link.movePoint(0, fx + dx * fromrect.width, fy, null);
          link.movePoint(n-1, tx - dx * torect.width, ty, null);
        } else {
          float middleY = 0.5f * (fy + ty +
                            dy * (fromrect.height - torect.height));
          pts[1].move(fx, middleY);
          pts[2].move(tx, middleY);
          link.movePoint(0, fx, fy + dy * fromrect.height, null);
          link.movePoint(n-1, tx, ty - dy * torect.height, null);
        }
    
        link.setIntermediateLinkPoints(pts, 1, 2);
    }
    
  2. リンク・ポリシーがリンクで設定されるか、リンクがグラファーに追加される場合、リンク形状が正しくなるようにする必要があります。リンク形状ポリシーの適切なコールバック・メソッド内部でメソッド verifyLinkPoints を呼び出します。
    リンクがすでにグラファーに存在する場合は、コールバック・メソッド afterAdd が呼び出されます。リンク形状ポリシーでリンクの形状が変更され、また場合によってはリンクのバウンディング・ボックスも変更されることがあるので、メソッド applyToObject を呼び出す必要があります。
    public void afterAdd(IlvLinkImage link)
    {
        if (link.getGraphicBag() != null) {
            link.getGraphicBag().applyToObject(link,
                new IlvApplyObject() {
                    public void apply(IlvGraphic obj, Object arg) {
                        verifyLinkPoints((IlvLinkImage)obj);
                    }
                }, null, true);
            }
            else verifyLinkPoints(link);
        super.afterAdd(link);
    }
    
  3. リンク形状ポリシーを設定する際には、applyToObject を呼び出すユーザーを信頼することができるので、リンク形状ポリシー内部でこのメソッドを再度使用する必要はありません。 このためメソッド onInstall のコードが単純になります。
    public void onInstall(IlvLinkImage link)
    {
        verifyLinkPoints(link);
        super.onInstall(link);
    }
    
  4. リンク形状ポリシーでは、リンクの曲折点の数は 0、1、または 2 とすることができます。リンクの 2 つの終点はリンク基数にカウントされるので、曲折点が 3 つ以上にならないように、4 つを超える点の挿入を禁止するだけです。
    public boolean allowInsertPoint(IlvLinkImage link,
                                    int index,
                                    float x, float y,
                                    IlvTransformer t)
    {
        int n = link.getPointsCardinal();
        if (n >= 4) return false;
        return true;
    }
    
  5. 曲折点が挿入または削除されると、リンクが曲折点の該当数に応じた形状になるように、リンク・ポリシーでリンクを形状変更する必要があります。したがって、afterInsertPointafterRemovePoint、および afterSetIntermediateLinkPoints の各メソッドをオーバーライドして、verifyLinkPoints を呼び出します。 これらのメソッドはすべて、常にメソッド applyToObject 内で呼び出されます。 つまり、onInstall と同様に、コードでは以下のように applyToObject の追加呼び出しを省略することができます。
    public void afterInsertPoint(IlvLinkImage link, int index, 
                                              IlvTransformer t)
    {
        verifyLinkPoints(link);
        super.afterInsertPoint(link, index, t);
    }
    
    public void afterRemovePoint(IlvLinkImage link, int index,
                                             IlvTransformer t)
    {
        verifyLinkPoints(link);
        super.afterRemovePoint(link, index, t);
    }
    
    public void afterSetIntermediateLinkPoints(IlvLinkImage link)
    {
        verifyLinkPoints(link);
        super.afterSetIntermediateLinkPoints(link);
    }
    
  6. 折れ線リンク・イメージの変換を変更すると、通常はリンクの曲折点も変更されます。したがって、ここでリンク点も検証する必要があります。
    public void afterApplyTransform(IlvLinkImage link, IlvTransformer t)
    {
        verifyLinkPoints(link);
        super.afterApplyTransform(link, t);
    }
    
  7. リンクの終了ノードが移動されると、それに応じてリンクの 1 つまたは 2 つの曲折点を調整する必要があります。このため、リンク形状ポリシーの対応するコールバック・メソッドをオーバーライドする必要があります。
    public void afterFromNodeMoved(IlvLinkImage link)
    {
        verifyLinkPoints(link);
        super.afterFromNodeMoved(link);
    }
    
    public void afterToNodeMoved(IlvLinkImage link)
    {
        verifyLinkPoints(link);
        super.afterToNodeMoved(link);
    }
    
  8. リンク形状ポリシーは、曲折点の位置を完全に定義します。したがって、このポリシーにより、曲折点の位置の変更は禁止されています。つまり点を移動することは許可されません。
    public boolean allowMovePoint(IlvLinkImage link,
                                  int index,
                                  float x, float y,
                                  IlvTransformer t)
    {
        return false;
    }
    
リンク形状ポリシーのコールバック・メソッド afterMovePoint は、点の移動後にリンク形状を調整するために使用できます。ただし、このリンク形状ポリシーでは点の移動は許可されないので、メソッド afterMovePoint はオーバーライドする必要はありません。点の移動は実行されないからです。
新規リンク形状ポリシーは、 IlvPolicyAwareLinkImage のすべてのサブクラスに対して機能します。これは、以下のようにリンクで設定できます。
link.setLinkShapePolicy(new MyLinkShapePolicy());
メモ
単純にするため、クラスの例 MyLinkShapePolicy は、リンク・コネクターもフリーのリンク・コネクター ( IlvFreeLinkConnector) もないズーム可能な矩形の終了ノード用に設計されています。これが該当しない場合、現在のトランスフォーマー、終了ノードの形状、およびリンク・コネクターを分析するために、メソッド verifyLinkPoints を調整する必要があります。