Posted on 2011-09-16 15:45 
TWaver 阅读(2608) 
评论(2)  编辑  收藏  
			
			
		 
		TWaver的连线默认支持流动效果,设置连线的流动属性为true,以及流动颜色,方向,宽度等,就可以出现下面间隔颜色的流动效果。
默认连线流动效果 
link流动设置代码:
1
Link flowingLink = new Link(node, node);
2
flowingLink.putLinkFlowing(true);
3
flowingLink.putLinkFlowingColor(Color.BLUE);
4
flowingLink.putLinkFlowingWidth(5);
5
flowingLink.putLinkWidth(5);
6
flowingLink.putLinkAntialias(true); 
 
默认连线流动效果:

定制连线流动效果 
默认的效果总是满足不了客户丰富的实际需求,最近就遇到有客户提这样的需求,link上方出现一排流动的点表示信息流,点之间的间隙代表流动的速度,如下示意图:

分析难点,与默认流动效果相比有三处区别:一是流动的图形是点,而不是色块,二是间距要可设置,三是绘制位置在link上方,而不是和link叠在一起。遇到问题解决问题,程序员的神奇之处就是简单的几行代码,就能让不懂代码的mm对你佩服不已,这个问题的解决也是如此,通过对stroke的设置和sin,cos的使用轻松化解了问题难点。
定义CustomFlowingLink和CustomFlowingLinkUI类 
首先这个问题是需要扩展LinkUI的,按照定制ElementUI的方法,扩展一个CustomFlowingLink类,以及对应的ui类CustomFlowingLinkUI,如下:
 1
public static class CustomFlowingLink extends Link
{
 2
    public CustomFlowingLink()
{
 3
        super();
 4
        this.init();
 5
    }
 6
 7
    public CustomFlowingLink(Object id)
{
 8
        super(id);
 9
        this.init();
10
    }
11
12
    public CustomFlowingLink(Node node1, Node node2) 
{
13
        super(node1, node2);
14
        this.init();
15
    }
16
17
    private void init()
{
18
        this.putLinkFlowing(true);
19
        this.putLinkFlowingColor(Color.RED);
20
        this.putLinkAntialias(true);
21
    }
22
23
    @Override
24
    public String getUIClassID() 
{
25
        return CustomFlowingLinkUI.class.getName();
26
    }
27
}
28
29
public static class CustomFlowingLinkUI extends LinkUI
{
30
    CustomFlowingLink link;
31
    public CustomFlowingLinkUI(TNetwork network, CustomFlowingLink link) 
{
32
        super(network, link);
33
        this.link = link;
34
    }
35
} 
 
上面的代码通过重写Link#public String getUIClassID()方法,使CustomFlowingLink与CustomFlowingLinkUI关联,其中CustomFlowingLink构造寒函数中设置了该连线为流动样式,并设置了流动颜色。注意上面构造函数的重写,例如CustomFlowingLink必须实现不带参数的默认构造函数,以及带id参数的构造函数,这样扩展的连线类型才能够同TDataBox导出导入xml。
增加控制点间距和偏离距离的属性 
接下来我们增加两个属性,flowingGap,flowingOffset分别用来控制点间距和偏离连线的距离,如下:
 1
public static class CustomFlowingLink extends Link
{
 2
    int flowingGap = 10;
 3
    int flowingOffset = 10;
 4
 5
    public int getFlowingGap() 
{
 6
        return flowingGap;
 7
    }
 8
 9
    public void setFlowingGap(int flowingGap) 
{
10
        this.flowingGap = flowingGap;
11
        this.updateUI();
12
    }
13
14
    public int getFlowingOffset() 
{
15
        return flowingOffset;
16
    }
17
18
    public void setFlowingOffset(int flowingOffset) 
{
19
        this.flowingOffset = flowingOffset;
20
        this.updateUI();
21
    }
22
               
23
       } 
 
定制流动绘制逻辑 
下面定制绘制逻辑,这里重写了LinkUI的public void paintBody(Graphics2D g2d)方法,另外在连线的上方绘制了一条点线
重点是stroke的设置,这里我们详细来解释一下参数:
 1
public void paintBody(Graphics2D g2d) 
{
 2
    super.paintBody(g2d);
 3
        if(this.isFlowing())
{
 4
            g2d.setColor(this.getFlowingColor());//流动线颜色
 5
            float[] dashPatten = new float[] 
{0, link.getFlowingGap()};
 6
            Stroke dashStroke = new BasicStroke(
 7
                this.getFlowingWidth(),//画笔参数,如果你需要更改点的大小,可以修改这个参数
 8
                BasicStroke.CAP_ROUND,//线端点样式为圆角,这样一个点就会绘制成一个圆形
 9
                BasicStroke.JOIN_ROUND,//线连接点样式
10
                link.getFlowingGap(),//最小测量单位,这里取点间距
11
                dashPatten,//线样式,{0, link.getFlowingGap()}就表示每间隔link.getFlowingGap()个像素绘制一个点
12
                this.getDashPhase());//起始位置,TWaver内部会定时的修改这个值,使这条线流动起来
13
            g2d.setStroke(dashStroke);
14
            double offset = link.getFlowingOffset();
15
            double tx = Math.sin(this.linkAngle) * offset;
16
            double ty = -Math.cos(this.linkAngle) * offset;
17
            System.out.println(tx + " , " + ty);
18
            g2d.translate(tx, ty);
19
            g2d.draw(this.getPath());
20
            g2d.translate(-tx, -ty);
21
        }
22
} 最终效果 
创建两条连线,看看效果:
 1
public static void main(String[] args) 
{
 2
    TDataBox box = new TDataBox();
 3
 4
    Node node1 = createNode(box, null, 100, 100);
 5
    Node node2 = createNode(box, null, 200, 120);
 6
    Node node3 = createNode(box, null, 100, 200);
 7
    Node node4 = createNode(box, null, 200, 220);
 8
 9
    CustomFlowingLink link1 = new CustomFlowingLink(node1, node2);
10
    CustomFlowingLink link2 = new CustomFlowingLink(node3, node4);
11
    link2.setFlowingGap(20);
12
    link2.setFlowingOffset(15);
13
14
    box.addElement(link1);
15
    box.addElement(link2);
16
17
    showFrame("Custom Flowing Link Demo", new TNetwork(box));
18
} 
 
效果图:
 
 
完整代码请查看这里