TWaver - 专注UI技术

http://twaver.servasoft.com/
posts - 171, comments - 191, trackbacks - 0, articles - 2
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

TWaver定制流动的link

Posted on 2011-09-16 15:45 TWaver 阅读(2499) 评论(2)  编辑  收藏

TWaver的连线默认支持流动效果,设置连线的流动属性为true,以及流动颜色,方向,宽度等,就可以出现下面间隔颜色的流动效果。
默认连线流动效果

link流动设置代码:

1Link flowingLink = new Link(node, node);
2flowingLink.putLinkFlowing(true);
3flowingLink.putLinkFlowingColor(Color.BLUE);
4flowingLink.putLinkFlowingWidth(5);
5flowingLink.putLinkWidth(5);
6flowingLink.putLinkAntialias(true);

 

默认连线流动效果:


定制连线流动效果

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


分析难点,与默认流动效果相比有三处区别:一是流动的图形是点,而不是色块,二是间距要可设置,三是绘制位置在link上方,而不是和link叠在一起。遇到问题解决问题,程序员的神奇之处就是简单的几行代码,就能让不懂代码的mm对你佩服不已,这个问题的解决也是如此,通过对stroke的设置和sin,cos的使用轻松化解了问题难点。

  • 定义CustomFlowingLink和CustomFlowingLinkUI类

    首先这个问题是需要扩展LinkUI的,按照定制ElementUI的方法,扩展一个CustomFlowingLink类,以及对应的ui类CustomFlowingLinkUI,如下:

     1public 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
    29public 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分别用来控制点间距和偏离连线的距离,如下:

     1public 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的设置,这里我们详细来解释一下参数:

     1public 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}
    最终效果

    创建两条连线,看看效果:

     1public static void main(String[] args) {
     2    TDataBox box = new TDataBox();
     3
     4    Node node1 = createNode(box, null100100);
     5    Node node2 = createNode(box, null200120);
     6    Node node3 = createNode(box, null100200);
     7    Node node4 = createNode(box, null200220);
     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}

     

    效果图:

     

    完整代码请查看这里 

     

     

     


  • 评论

    # re: TWaver定制流动的link  回复  更多评论   

    2011-09-17 08:57 by tb
    分析得很不错

    # re: TWaver定制流动的link  回复  更多评论   

    2011-09-22 20:54 by 相信
    cool

    只有注册用户登录后才能发表评论。


    网站导航: