<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    TWaver - 專注UI技術(shù)

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

    UI定制總結(jié)

    Posted on 2012-08-01 09:52 TWaver 閱讀(956) 評論(0)  編輯  收藏
    TWaver本身提供的豐富的設(shè)置選項(xiàng),可以幫助我們快速實(shí)現(xiàn)各種絢麗的效果,但是在某些情況下,我們需要在網(wǎng)元上繪制一些圖形來表示某種狀態(tài)或業(yè)務(wù)信息,沒問題,只需要一點(diǎn)點(diǎn)2D知識(shí)可以很容易實(shí)現(xiàn)這樣的需求。
    假設(shè)一種需求(僅僅是假設(shè)):監(jiān)控交換機(jī)各個(gè)端口的傳輸速度,并用柱狀圖動(dòng)態(tài)顯示。效果圖如下:
    大家可能奇怪,怎么放了三個(gè)一樣的網(wǎng)元呢?答案是:我使用了三種方式來實(shí)現(xiàn)這個(gè)效果!可能還有別的方式可以實(shí)現(xiàn),所謂條條大路通羅馬是也!這也是TWaver的強(qiáng)大之處, 為我們留下了一扇門,門后就是神奇的"納尼亞王國",本文的目的就是把這扇門的鑰匙交給你。

    我們從最簡單的說起,TWaver提供了BarChart表示柱狀圖,我們可以把BarChart通過ComponentAttachment掛到Node上,這是最簡單的方式,之所以說它簡單,因?yàn)槲覀儾恍枰褂?D繪制( 其實(shí)2D也不難),僅僅需要監(jiān)聽Node的屬性變化然后更新BarChart即可。

    ComponentAttachment上允許添加任何JComponent組件(JPanel,JButton,JLabel,JCheckbox,etc.),BarChart是JComponent的子類,自然也可以被添加。ComponentAttachment是個(gè)抽象類,需要定制一個(gè)PortRateAttachment繼承ComponentAttachment

    注冊Attachment
    1 TUIManager.registerAttachment("PortRateAttachment",PortRateAttachment.class);

    1 node1.addAttachment("PortRateAttachment");
    2 node1.putAttachmentPosition(TWaverConst.POSITION_RIGHT);
    3 node1.putAttachmentXOffset(-20);

     1 public class PortRateAttachment extends ComponentAttachment {
     2     Node p1=new Node();
     3     Node p2=new Node();
     4     Node p3=new Node();
     5     private BarChart barChart=new BarChart();
     6     public PortRateAttachment(String name, ElementUI ui) {
     7         super(name, ui);
     8         TDataBox box=new TDataBox();
     9         barChart.setDataBox(box);
    10         barChart.setShadowOffset(0);//取消陰影
    11         barChart.setUpperLimit(100);//刻度最大值
    12         barChart.setLowerLimit(0);//刻度最小值
    13         barChart.setYScaleLineVisible(false);//Y軸刻度線不可見
    14         barChart.setXAxisVisible(false);//X軸不可見
    15         barChart.setYAxisVisible(false);//Y軸不可見
    16         barChart.setBundleSize(3);//將三個(gè)Node放在一塊顯示
    17         barChart.setOpaque(false);//背景透明
    18         barChart.setXGap(0);//X軸Margin為0
    19         barChart.setYGap(0);//Y軸Margin為0
    20         barChart.setValueTextVisible(false);//ChartValue不可見
    21         barChart.getLegendPane().setVisible(false);//隱藏LegendPane
    22 
    23         //初始化三個(gè)Node
    24         p1.putChartValue(0);
    25         p1.putChartColor(PortRateConst.COLORS[0]);
    26         box.addElement(p1);
    27 
    28         p2.putChartValue(0);
    29         p2.putChartColor(PortRateConst.COLORS[1]);
    30         box.addElement(p2);
    31 
    32         p3.putChartValue(0);
    33         p3.putChartColor(PortRateConst.COLORS[2]);
    34         box.addElement(p3);
    35 
    36         this.setComponent(barChart);//將BarChart掛載在Attachment上
    37         this.setBorderVisible(true);//顯示Border
    38         this.setBorderColor(Color.gray);//Border顏色
    39         this.setSize(new Dimension(50,50));//設(shè)置Attachment大小
    40         this.setPosition(this.element.getAttachmentPosition());//設(shè)置Attachment的位置,提前存入Node的ClientProperty
    41         this.setXOffset(this.element.getAttachmentXOffset());//設(shè)置Attachment的X軸偏移量,提前存入Node的ClientProperty
    42     }
    43 
    44     /*
    45      * 監(jiān)控Node Property變化并更新到BarChart上
    46      * @see twaver.network.ui.ComponentAttachment#elementPropertyChange(java.beans.PropertyChangeEvent)
    47      */
    48     @Override
    49     public void elementPropertyChange(PropertyChangeEvent evt) {
    50         super.elementPropertyChange(evt);
    51         if(evt.getNewValue()!=null){
    52             if("UP:p1".equals(evt.getPropertyName())){
    53                 p1.putChartValue(Double.parseDouble(evt.getNewValue().toString().substring(3))*100);
    54             }else if("UP:p2".equals(evt.getPropertyName())){
    55                 p2.putChartValue(Double.parseDouble(evt.getNewValue().toString().substring(3))*100);
    56             }else if("UP:p3".equals(evt.getPropertyName())){
    57                 p3.putChartValue(Double.parseDouble(evt.getNewValue().toString().substring(3))*100);
    58             }
    59         }
    60 
    61     }
    62 }

    在Attachment中添加一個(gè)BarChart,并用三個(gè)Node表示chart的三個(gè)組,在elementPropertyChange中監(jiān)控Node屬性變化并同步更新到這三個(gè)Node上即可。
    所有的代碼已經(jīng)加上注釋,就不過多解釋了。
    TWaver還提供了一種IconAttachment,允許我們將一個(gè)Icon作為附件掛載在Node上,我們可以在Icon上畫任何內(nèi)容,所以這也是一種思路(參考了TWaver官方demo,InstrumentDemo,為避免版權(quán)糾紛,特此說明 :-D )。我們定制一個(gè)PortRateIconAttachment從IconComponentAttachment繼承。

     1 public class PortRateIconAttachment extends IconAttachment {
     2     public final static double WIDTH = 40;
     3     public final static double HEIGHT = 50;
     4 
     5     public PortRateIconAttachment(String name, ElementUI elementUI) {
     6         super(name, elementUI,new PortRateIcon(elementUI.getElement()));
     7     }
     8 
     9 }
    10 class PortRateIcon implements javax.swing.Icon{
    11     private Element element;
    12     public PortRateIcon(Element element){
    13         this.element=element;
    14     }
    15     @Override
    16     public void paintIcon(Component c, Graphics g, int x, int y) {
    17         Graphics2D g2d = (Graphics2D)g;
    18         //計(jì)算出柱狀圖中組數(shù)和組寬
    19         final int count = PortRateConst.KEYS.length;
    20         final double width = PortRateIconAttachment.WIDTH / count;
    21         //計(jì)算坐標(biāo)和尺寸,繪制三個(gè)矩形代表三個(gè)組
    22         for(int i=0; i<count; i++){
    23             double proportion=0;
    24             if(element.getUserProperty(PortRateConst.KEYS[i])!=null)
    25                 proportion =Double.parseDouble(element.getUserProperty(PortRateConst.KEYS[i]).toString().substring(3));
    26             g2d.setColor(PortRateConst.COLORS[i]);
    27             g2d.fillRect((int)(x + i * width),
    28                     (int)(y + PortRateIconAttachment.HEIGHT * (1- proportion)),
    29                     (int)width,(int)(PortRateIconAttachment.HEIGHT * proportion));
    30         }
    31         //繪制邊框
    32         g2d.setColor(Color.GRAY);
    33         g2d.setStroke(TWaverConst.BASIC_STROKE);
    34         g2d.drawRect(x, y-1, (int)PortRateIconAttachment.WIDTH, (int)PortRateIconAttachment.HEIGHT);
    35     }
    36 
    37     @Override
    38     public int getIconWidth() {
    39         return (int) PortRateIconAttachment.WIDTH;
    40     }
    41 
    42     @Override
    43     public int getIconHeight() {
    44         return (int) PortRateIconAttachment.HEIGHT;
    45     }
    46 
    47 }

    在PortRateIconAttachment中沒有任何繪制,僅僅與一個(gè)PortRateIcon綁定,繪制工作交給PortRateIcon執(zhí)行,每當(dāng)PortRateIconAttachment監(jiān)聽到Node屬性變化時(shí)就會(huì)重繪Icon

    在paintIcon方法中,我們最終繪制出了我們需要的動(dòng)態(tài)柱狀圖。

    除了Attachment,重寫NodeUI也是一個(gè)不錯(cuò)的選擇??次覀兊牡谌N方法

    我們寫了一個(gè)SwitchNode繼承自Node,重寫getUIClassID方法,實(shí)際上就是為此Node指定了UI類

    PortNodeUI 
     1 public class PortNodeUI extends NodeUI {
     2     private Rectangle2D rect=null;
     3     public PortNodeUI(TNetwork network, Node node) {
     4         super(network, node);
     5     }
     6     @Override
     7     public void paintBody(Graphics2D g2d){
     8         super.paintBody(g2d);
     9         final int count = PortRateConst.KEYS.length;
    10         //計(jì)算出柱狀圖中組數(shù)和組寬
    11         final double width = 40 / count;
    12         double x=element.getX()+element.getWidth()-20;
    13         double y=element.getY()+20;
    14         //繪制組
    15         for(int i=0; i<count; i++){
    16             double proportion=0;
    17             if(element.getUserProperty(PortRateConst.KEYS[i])!=null)
    18                 proportion =Double.parseDouble(element.getUserProperty(PortRateConst.KEYS[i]).toString().substring(3));
    19             g2d.setColor(PortRateConst.COLORS[i]);
    20             g2d.fillRect((int)(x + i * width),
    21                         (int)(y + 50 * (1- proportion)),
    22                         (int)width, (int)(PortRateIconAttachment.HEIGHT * proportion));
    23         }
    24         //繪制邊框
    25         g2d.setColor(Color.GRAY);
    26         g2d.setStroke(TWaverConst.BASIC_STROKE);
    27         g2d.drawRect((int)x, (int)y, (int)PortRateIconAttachment.WIDTH, (int)PortRateIconAttachment.HEIGHT);
    28     }
    29 }

    注意paintBody方法,幾乎跟前面的paintIcon是一致的。
    注意右側(cè)的PropertySheet,我們也為其實(shí)現(xiàn)了一個(gè)Renderer繪制進(jìn)度條,實(shí)際上,通過Renderer,我們可以在PropertySheet繪制任何圖形或組件。
    通過 ElementAttribute指定Renderer

    1 ElementAttribute&nbsp;att=new&nbsp;ElementAttribute();
    2 att.setRendererClass(PortRateRenderer.class.getName());

    Renderer類

     1 public class PortRateRenderer extends JComponent implements TableCellRenderer {
     2     private Color foreColor;
     3     private double proportion;
     4     @Override
     5     public Component getTableCellRendererComponent(JTable table, Object value,
     6             boolean isSelected, boolean hasFocus, int row, int column) {
     7         if(value!=null){
     8             String strValue=(String)value;
     9             for(int i=0; i<PortRateConst.KEYS.length; i++){
    10                 String key = PortRateConst.KEYS[i];
    11                 if(strValue.startsWith(key)){
    12                     proportion = Double.parseDouble(strValue.substring(key.length() + 1));
    13                     foreColor = PortRateConst.COLORS[i];
    14                 }
    15             }
    16         }
    17         return this;
    18     }
    19     public void paintComponent(Graphics g){
    20         Graphics2D g2d=(Graphics2D)g;
    21         g2d.setColor(new Color(127,92,128));
    22         g2d.drawRect(1, 1, this.getWidth()-2, this.getHeight()-2);
    23         g2d.setColor(new Color(240,240,240));
    24         g2d.fillRect(2, 2, this.getWidth()-3, this.getHeight()-3);
    25         g2d.setColor(foreColor);
    26         g2d.fillRect(2, 2, (int)(this.getWidth() * proportion), this.getHeight()-3);
    27     }
    28 
    29 }

    在getTableCellRendererComponent中,我們根據(jù)傳進(jìn)Renderer的Value,設(shè)置進(jìn)度條的值和前景色,在paintComponent中就可以使用了。在paintComponent里,首先畫一個(gè)矩形當(dāng)作進(jìn)度條背景,然后覆蓋一個(gè)矩形當(dāng)作進(jìn)度,繪制好邊框以后一個(gè)進(jìn)度條就完成了!
    最近論壇上有人提出要實(shí)現(xiàn)帶圓角Title的Group,貼子地址:http://twaver.servasoft.com/forum/viewtopic.php?f=4&t=3091。 帖子里的實(shí)現(xiàn)過程是這樣的:Group的Label其實(shí)是一個(gè)LabelAttachment,為Group重新定制了一個(gè)LabelAttachment,在LabelAttachment繪制出圓角效果,然后將Group的LabelPosition設(shè)置為左上角即可。

    圓角繪制的原理是將一個(gè)圓角矩形和普通矩形通過Area組合,然后用漸變色填充,具體的代碼大家可以去帖子里下載。

    這個(gè)專題終于可以告一段落了,熟悉TWaver架構(gòu)以后,再加上一些2d知識(shí),我們可以發(fā)揮自己的想象力繪制各種令人驚嘆的效果。希望本文能起到拋磚引玉的作用。最后附上文中demo的源代碼見原文最下方

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


    網(wǎng)站導(dǎo)航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 亚洲成年人免费网站| 国产麻豆剧传媒精品国产免费| 亚洲不卡无码av中文字幕| 久久青草免费91线频观看站街| 色屁屁www影院免费观看视频| 亚洲一区二区三区91| 亚洲一区综合在线播放| 久久久久噜噜噜亚洲熟女综合| 在线播放高清国语自产拍免费| 亚洲一区免费视频| 午夜视频在线免费观看| 在线aⅴ亚洲中文字幕| 久久久久亚洲精品天堂| 亚洲精品无码av人在线观看| 亚洲精品无码久久久| 免费人成无码大片在线观看| 免费看少妇作爱视频| 成年女人18级毛片毛片免费观看| 无遮挡国产高潮视频免费观看| 亚洲熟妇av午夜无码不卡| 亚洲中文字幕在线无码一区二区| 亚洲精品免费观看| 在线观看人成网站深夜免费| 黄色永久免费网站| 2021国内精品久久久久精免费| 国产成人精品日本亚洲语音| 亚洲日韩AV无码一区二区三区人 | 日韩久久无码免费毛片软件| 久久精品亚洲日本波多野结衣| 亚洲级αV无码毛片久久精品| 亚洲中文字幕日产乱码高清app| 亚洲AV无码之日韩精品| 亚洲精品国产高清嫩草影院| 亚洲国产成人久久一区WWW| 亚洲国产婷婷综合在线精品 | 香蕉视频免费在线| 国产亚洲福利精品一区二区| 亚洲美女视频免费| 亚洲人成在线观看| 亚洲免费人成视频观看| 久久国产亚洲精品|