TWaver - 專注UI技術

          http://twaver.servasoft.com/
          posts - 171, comments - 191, trackbacks - 0, articles - 2
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

           linkUML圖大家都看過,可能大家也比較熟悉,有時候也希望能通過UML圖形的方式展示一些網管業務邏輯,比如以下邏輯

          下面通過一系列的功能點講解,教大家如何使用TWaver實現UML效果,最終效果圖如下

          Step1, 如何實現UML圖形的節點,效果如下:

          功能點介紹
          Step1.1 如何實現文字換行居中
          TWaver中網元的Label默認就已經提供了對于html的支持,所以可以通過如下代碼實現文字換行居中效果

          1node.putLabelPosition(TWaverConst.POSITION_CENTER);
          2node.setDisplayName("<html><center>網絡資源<br>(Resource)</center></html>");

          Step1.2 如何讓網元顯示成UML流程節點形狀
          這個主要有兩個功能點
          a:平時開發過程中,一般的網元都顯示成圖標的形式以代表業務邏輯,其實TWaver默認提供了一組CustomDraw的圖形,可以將網元顯示成不同的形狀,如下圖所示:

          通過設置CustomDraw的屬性就可以達到矩形的效果
          Step1.3 如何在節點下面繪制幾條分割線,這個功能很好的體現了TWaver中MVC的架構,對Swing熟悉一些的開發人員都知道,像JButton,JTextField等Swing組件都會有一些對應的UI類,比如ButtonUI,TextFieldUI進行繪制,開發人員可以很方便的通過LookAndFeel切換UI進行換膚操作。TWaver中網元渲染原理類似,像Node,Link都有對應的UI,NodeUI、LinkUI進行渲染,通過很方便的重載這些UI實現效果定制,比如TWaveDemo中的Custom Link Demo和Instrument Demo,如下圖所示

          UMLNode的實現也類似,首先定義了一個UMLNode類,在里面設置了一些列的CustomDraw屬性(參考Step1.2),然后繼承ResizableNodeUI實現了一個UMLNodeUI,在里面繪制了幾條分割線,代碼如下

           1public class UmlNode extends ResizableNode {
           2
           3    public UmlNode() {
           4        super();
           5        initNode();
           6    }

           7
           8    public UmlNode(Object id) {
           9        super(id);
          10        initNode();
          11    }

          12
          13    private void initNode() {
          14        this.putCustomDraw(true);
          15        this.putCustomDrawGradient(true);
          16        this.putCustomDrawGradientFactory(TWaverConst.GRADIENT_LINE_N);
          17        this.putCustomDrawFillColor(new Color(255200100150));
          18        this.putCustomDrawShapeFactory(TWaverConst.SHAPE_RECTANGLE);
          19        this.putCustomDrawOutlineColor(new Color(2000200));
          20
          21        this.putLabelPosition(TWaverConst.POSITION_CENTER);
          22        this.putLabelFont(TUIManager.getDefaultPlainFont());
          23        this.setSize(22060);
          24    }

          25
          26    //重載UI
          27    public String getUIClassID() {
          28        return UmlNodeUI.class.getName();
          29    }

          30
          31}

          32
          33public class UmlNodeUI extends ResizableNodeUI {
          34
          35    public UmlNodeUI(TNetwork network, ResizableNode node) {
          36        super(network, node);
          37    }

          38
          39    //想怎么畫就怎么畫
          40    protected void paintCustomDraw(Graphics2D g2d) {
          41        super.paintCustomDraw(g2d);
          42        Rectangle bounds = this.getUIBounds();
          43
          44        g2d.drawLine(bounds.x+2, bounds.y+bounds.height-6, bounds.x+bounds.width-2, bounds.y+bounds.height-6);
          45        g2d.drawLine(bounds.x+2, bounds.y+bounds.height-12, bounds.x+bounds.width-2, bounds.y+bounds.height-12);
          46    }

          47}

          通過以上處理,就可以達到UML節點的效果了

          Step2,如何實現UML的折線子環效果
          TWaver中的Link默認有自環環效果,效果如下

          但這個顯然不是我們想要的,因為它默認只有圓形效果,這個時候我們就想到了另外一種Link,ShapeLink,顧名思義,這個Link是由一個Shape形狀來表示的,那么我們能不能通過ShapeLink來實現折線子環的效果呢,答案是肯定的,只需要小小的定制即可,代碼如下

           1public class LoopLink extends ShapeLink {
           2
           3    public LoopLink(Node node) {
           4        super();
           5        initLink();
           6    }

           7
           8    public LoopLink(Object id, Node node) {
           9        super(id);
          10        this.setFrom(node);
          11        this.setTo(node);
          12        initLink();
          13    }

          14
          15    private double wExtend = 0.5;
          16    private double hExtend = 0.5;
          17
          18    private void initLink() {
          19        this.putLinkFromPosition(TWaverConst.POSITION_RIGHT);
          20        this.putLinkToPosition(TWaverConst.POSITION_BOTTOM);
          21        this.setLinkType(TWaverConst.LINK_TYPE_YSPLIT);
          22        this.putLinkOutlineWidth(0);
          23        this.putLinkWidth(1);
          24        this.putRenderColor(Color.BLUE);
          25        this.putLinkToArrow(true);
          26        this.putLinkToArrowStyle(TWaverConst.ARROW_DELTA_GREAT);
          27        this.putLinkToArrowOutlineColor(Color.RED);
          28        this.putLinkToArrowColor(Color.WHITE);
          29
          30        Node node = this.getFrom();
          31               //注意此處,因為默認ShapeLink上的點是不會跟隨Node移動的,所以為了實現跟隨效果,這里通過監聽Node的屬性變化進行了更新處理
          32        node.addPropertyChangeListener(new PropertyChangeListener() {
          33            public void propertyChange(PropertyChangeEvent evt) {
          34                if (TWaverConst.PROPERTYNAME_LOCATION.equals(evt.getPropertyName())) {
          35                    validatePoints();
          36                }

          37            }

          38        }
          );
          39        validatePoints();
          40    }

          41
          42    private void validatePoints() {
          43        this.clear();
          44        Node node = this.getFrom();
          45        Rectangle bounds = node.getBounds();
          46        Point2D p1 = new Point2D.Double(bounds.getCenterX() + bounds.getWidth() / 2, bounds.getCenterY());
          47        this.addPoint(p1);
          48        Point2D p2 = new Point2D.Double(bounds.getCenterX() + bounds.getWidth() / 2 + bounds.getWidth() * wExtend, bounds.getCenterY());
          49        this.addPoint(p2);
          50        Point2D p3 = new Point2D.Double(bounds.getCenterX() + bounds.getWidth() / 2 + bounds.getWidth() * wExtend, bounds.getCenterY() + bounds.getHeight() / 2
          51                + bounds.getHeight() * hExtend);
          52        this.addPoint(p3);
          53        Point2D p4 = new Point2D.Double(bounds.getCenterX(), bounds.getCenterY() + bounds.getHeight() / 2 + bounds.getHeight() * hExtend);
          54        this.addPoint(p4);
          55    }

          56
          57}

          通過這樣就可以達到折線自環的效果了,效果圖如下

          Step3 如何實現Link折線效果和From/To端文字標注
          Step 3.1 如何實現Link折線效果,其實這個很簡單,不過可能大多數人都會忽略TWaver默認提供的這個功能,通過設置不同的LinkType,Link可以顯示成各種樣式,如下圖所示

          通過如下代碼即可達到UML圖中的連線效果

           1private void initLink() {
           2        this.setLinkType(TWaverConst.LINK_TYPE_YSPLIT);
           3        this.putLinkOutlineWidth(0);
           4        this.putLinkWidth(1);
           5        this.putRenderColor(Color.BLUE);
           6        this.putLinkToArrow(true);
           7        this.putLinkToArrowStyle(TWaverConst.ARROW_DELTA_GREAT);
           8        this.putLinkToArrowOutlineColor(Color.RED);
           9        this.putLinkToArrowColor(Color.WHITE);
          10    }

          Step3.2 如何在Link的From/To端進行標注
          效果如下

          實現原理:這個借助了TWaver中Attachment的概念,顧名思義,Attachment即附件,它的主要功能就是附加一些信息到網元上,Attachment有很多種,簡單點的可以顯示一串文字,復雜點的可以顯示一些組件在界面上,想TWaverDemo的AttachmentDemo,如下圖所示

          文字標注也可以通過這種方式進行處理,TWaver內部對于Link的From和To兩個位置都有對應的定義

          1TWaverConst.POSITION_LINK_FROM_ANCHOR
          2TWaverConst.POSITION_LINK_TO_ANCHOR
          既然有了這個實現起來就很簡單了,我們只需要自定義一個Label的Attachment,然后將其放到From或To的Postion既可以了,見如下代碼
           1public class LinkLabelAttachment extends ComponentAttachment {
           2
           3    public final static String LINKFROMLABEL = "linklabelattachment.linkfromlabel";
           4
           5    public LinkLabelAttachment(String name, ElementUI ui) {
           6        super(name, ui);
           7        initLabel();
           8    }

           9
          10    public LinkLabelAttachment(String name, ElementUI ui, boolean minimized, boolean shrinked) {
          11        super(name, ui, minimized, shrinked);
          12        initLabel();
          13    }

          14
          15    private JLabel label = new JLabel() {
          16        {
          17            this.setHorizontalAlignment(SwingConstants.CENTER);
          18            this.setDoubleBuffered(false);
          19        }

          20    }
          ;
          21
          22    private void initLabel() {
          23        label.setFont(LinkLabelDemo.USECUSTOMERFONT);
          24        label.setForeground(LinkLabelDemo.LABELCOLOR);
          25
          26        setLabelText();
          27        this.setPosition(TWaverConst.POSITION_LINK_FROM_ANCHOR);
          28        this.setComponent(label);
          29    }

          30
          31    private void setLabelText() {
          32        Object obj = element.getClientProperty(LINKFROMLABEL);
          33        if (obj != null{
          34            label.setText(obj.toString());
          35        }

          36        else {
          37            label.setText("");
          38        }

          39        //可以調整此參數設置文字的偏移
          40        this.setXOffset(30);
          41        this.setWidth(label.getPreferredSize().width + 2);
          42        this.setHeight(label.getPreferredSize().height + 2);
          43    }

          44
          45    public void elementPropertyChange(PropertyChangeEvent evt) {
          46        super.elementPropertyChange(evt);
          47        if (LINKFROMLABEL.equals(TWaverUtil.getPropertyName(evt))) {
          48            setLabelText();
          49        }

          50    }

          51
          52}

          Link添加以上Attachment以后就會自動出現在Link的from端
          至于另外一端的標簽,我們可以通過TWaver內置的一個Attachment,即Message來實現,代碼如下

           1public void setToLabel(String label) {
           2        this.putMessageContent(label);
           3        if (!this.containsAttachment(TWaverConst.ATTACHMENT_MESSAGE)) {
           4            this.addAttachment(TWaverConst.ATTACHMENT_MESSAGE);
           5            this.putMessageStyle(TWaverConst.MESSAGE_COMPONENT_LABEL);
           6            this.putMessageBorderVisible(false);
           7            this.putMessageOpaque(false);
           8            this.putMessagePosition(TWaverConst.POSITION_LINK_TO_ANCHOR);
           9            this.putMessageShadowVisible(false);
          10            this.putMessageFont(LinkLabelDemo.USECUSTOMERFONT);
          11            this.putMessageForeground(LinkLabelDemo.LABELCOLOR);
          12            JLabel label2 = new JLabel();
          13            label2.setText(this.getMessageContent());
          14            label2.setFont(LinkLabelDemo.USECUSTOMERFONT);
          15            //可以設置以下參數設置Message的偏移
          16            this.putMessageXOffset(30);
          17        }

          18    }

          通過以上代碼就可以實現在Link兩端添加標簽的效果了

          源碼請到此處下載:twaver.servasoft.com


          評論

          # re: 一步一步教你使用TWaver實現UML圖—網元篇  回復  更多評論   

          2011-08-18 21:38 by nomad2
          請問,UML中的序列圖,例如:http://www.aygfsteel.com/pengpenglin/archive/2008/03/25/188498.html 應該如何實現呢?謝謝

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 玉树县| 临夏县| 金秀| 扎兰屯市| 合川市| 望谟县| 颍上县| 若羌县| 南城县| 蒲城县| 双辽市| 阆中市| 察隅县| 五寨县| 营口市| 微山县| 诸城市| 云霄县| 荆州市| 广州市| 宜昌市| 蒙城县| 靖宇县| 白沙| 怀集县| 九寨沟县| 新野县| 阿拉善左旗| 泰顺县| 渭南市| 梁平县| 靖安县| 大港区| 佛冈县| 彭阳县| 古田县| 江门市| 黔东| 额尔古纳市| 奎屯市| 定襄县|