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

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

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

    TWaver - 專注UI技術

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

    UI定制總結

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

    我們從最簡單的說起,TWaver提供了BarChart表示柱狀圖,我們可以把BarChart通過ComponentAttachment掛到Node上,這是最簡單的方式,之所以說它簡單,因為我們不需要使用2D繪制( 其實2D也不難),僅僅需要監聽Node的屬性變化然后更新BarChart即可。

    ComponentAttachment上允許添加任何JComponent組件(JPanel,JButton,JLabel,JCheckbox,etc.),BarChart是JComponent的子類,自然也可以被添加。ComponentAttachment是個抽象類,需要定制一個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);//將三個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         //初始化三個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));//設置Attachment大小
    40         this.setPosition(this.element.getAttachmentPosition());//設置Attachment的位置,提前存入Node的ClientProperty
    41         this.setXOffset(this.element.getAttachmentXOffset());//設置Attachment的X軸偏移量,提前存入Node的ClientProperty
    42     }
    43 
    44     /*
    45      * 監控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中添加一個BarChart,并用三個Node表示chart的三個組,在elementPropertyChange中監控Node屬性變化并同步更新到這三個Node上即可。
    所有的代碼已經加上注釋,就不過多解釋了。
    TWaver還提供了一種IconAttachment,允許我們將一個Icon作為附件掛載在Node上,我們可以在Icon上畫任何內容,所以這也是一種思路(參考了TWaver官方demo,InstrumentDemo,為避免版權糾紛,特此說明 :-D )。我們定制一個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         //計算出柱狀圖中組數和組寬
    19         final int count = PortRateConst.KEYS.length;
    20         final double width = PortRateIconAttachment.WIDTH / count;
    21         //計算坐標和尺寸,繪制三個矩形代表三個組
    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中沒有任何繪制,僅僅與一個PortRateIcon綁定,繪制工作交給PortRateIcon執行,每當PortRateIconAttachment監聽到Node屬性變化時就會重繪Icon

    在paintIcon方法中,我們最終繪制出了我們需要的動態柱狀圖。

    除了Attachment,重寫NodeUI也是一個不錯的選擇。看我們的第三種方法

    我們寫了一個SwitchNode繼承自Node,重寫getUIClassID方法,實際上就是為此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         //計算出柱狀圖中組數和組寬
    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是一致的。
    注意右側的PropertySheet,我們也為其實現了一個Renderer繪制進度條,實際上,通過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中,我們根據傳進Renderer的Value,設置進度條的值和前景色,在paintComponent中就可以使用了。在paintComponent里,首先畫一個矩形當作進度條背景,然后覆蓋一個矩形當作進度,繪制好邊框以后一個進度條就完成了!
    最近論壇上有人提出要實現帶圓角Title的Group,貼子地址:http://twaver.servasoft.com/forum/viewtopic.php?f=4&t=3091。 帖子里的實現過程是這樣的:Group的Label其實是一個LabelAttachment,為Group重新定制了一個LabelAttachment,在LabelAttachment繪制出圓角效果,然后將Group的LabelPosition設置為左上角即可。

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

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

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


    網站導航:
     
    主站蜘蛛池模板: 久久精品国产这里是免费| 亚洲无线码在线一区观看| 国内精品免费视频精选在线观看| 亚洲色图激情文学| 亚洲第一精品在线视频| 亚洲精品成人在线| 国产禁女女网站免费看| 国产在线观看片a免费观看 | 成年美女黄网站18禁免费| 国内精品一级毛片免费看| 日韩免费在线中文字幕| 亚洲精品乱码久久久久蜜桃| 亚洲小说图片视频| 亚洲五月六月丁香激情| 久久精品国产精品亚洲蜜月| 亚洲综合伊人久久综合| 亚洲天堂在线视频| 亚洲国产高清在线一区二区三区| 国产美女a做受大片免费| 亚洲精品动漫免费二区| 免费看国产精品3a黄的视频| 精品国产污污免费网站aⅴ| 免费人妻无码不卡中文字幕系 | 亚洲国产精品lv| 国产aⅴ无码专区亚洲av| 国产亚洲精品精品国产亚洲综合| 免费看一级做a爰片久久| 国产伦精品一区二区三区免费下载| 好男人视频社区精品免费| 成人免费午夜在线观看| 成人无遮挡毛片免费看| 夜夜嘿视频免费看| 日本成人在线免费观看| 国产免费黄色大片| yy6080久久亚洲精品| 亚洲国产天堂久久久久久| 中文字幕亚洲综合久久菠萝蜜| 亚洲精品无码永久在线观看你懂的 | 在线观看免费a∨网站| 全免费a级毛片免费看不卡| 国产精品高清全国免费观看|