TWaver - 专注UI技术

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

瞧咱办公室的拓扑图

Posted on 2010-09-14 18:41 TWaver 阅读(2290) 评论(3)  编辑  收藏

前几天看了《Swing版小小网管》让我想起前阵子做过的一个企业网管项目。客户是一个工厂,搞生产制造的。人并不多,四、五十人,多数是车间工人。办公室的也就二十多人,网络结构并不复杂:ADSL宽带接入,加上几个AP进行信号扩展;台式机、服务器、笔记本电脑,加上零星的手机上网,仅此而已。大伙知道做企业网管是比较艰难的,工作量大,吃力不讨好,竞争激烈,卖不了几个钱。但是为了能够在项目中多点筹码,界面还是要做的精益求精才行。

先到工厂详细调研了网络结构图,并绘制了一个简单的草图结构:

其中ADSL和几个无线AP是网络主干,各个办公室的结构都是星形结构,通过网线进行汇聚,通过AP进行互联。使用AP的原因是工厂正在进行改造,几个办公室之间距离较远,隔着一个大院子,网线铺设不便。

要在网管里面呈现和监控这个网络,对俺来说不算难事。不过我需要一个好看一点的流量监控的图表。首先通过SNMP获取AP中的iftable中的端口,并获取其实时流量,然后放置在拓扑图的link对象中。为了不给网络造成太多负担,网管默认每5秒钟获取一次数值,并存储连续100个数值,多余的抛弃。

绘制chart的图并不复杂,整个chart呈一个长矩形状,分为三段(老、中、轻),用不同的颜色进行渲染。

 1public void paintIcon(Component c, Graphics g, int x, int y) {
 2    Graphics2D g2d = (Graphics2D) g;
 3
 4    Rectangle bounds = getBounds();
 5
 6    g2d.setColor(background);
 7    g2d.fill(bounds);
 8
 9    Point location = bounds.getLocation();
10    int startX = location.x;
11    int startY = location.y + chartHeight;
12    GeneralPath path = new GeneralPath();
13    path.moveTo(startX, startY);
14
15    int[] values = getChartDataValues();
16
17    for (int i = 0; i < values.length; i++{
18        path.lineTo(startX + i, startY - values[i]);
19    }

20    path.lineTo(startX + chartWidth, startY);
21    path.closePath();
22
23    g2d.setColor(chartColor1);
24    g2d.fill(path);
25
26    //clip center part, paint with color2.
27    Shape oldClip = g2d.getClip();
28    Rectangle clip = new Rectangle(bounds.x + chartWidth / 4, bounds.y, chartWidth / 2, chartHeight);
29    g2d.setClip(clip);
30    g2d.setColor(chartColor2);
31    g2d.fill(path);
32    g2d.setClip(oldClip);
33
34    g2d.setColor(Color.lightGray);
35    g2d.draw(bounds);
36
37    g2d.setColor(Color.darkGray);
38    g2d.setFont(font);
39
40    int textX = location.x + 5;
41    int textY = location.y + chartHeight / 2 + font.getSize() / 2;
42    g2d.drawString("Sum", textX, textY);
43
44    int speed = 100;
45    if (getElementUI().getElement() instanceof MyLink) {
46        speed = ((MyLink) getElementUI().getElement()).getSpeed();
47    }

48    String text = NumberFormat.getInstance().format(speed) + " kbit/s";
49    Rectangle2D textBounds = g2d.getFontMetrics().getStringBounds(text, g2d);
50    textX = (int) (location.x + chartWidth - textBounds.getWidth() - 5);
51    g2d.drawString(text, textX, textY);
52}

53

显示效果如下:

另外,对连线的效果也进行了一些处理。用直线连接无疑太土气了,来点曲线增加一点趣味。曲线用一个对称的抛物线来处理,根据不同的角度进行自动调整:

 1public GeneralPath getPath() {
 2    Point from = this.getFromPoint();
 3    Point to = this.getToPoint();
 4    Point middle = new Point((from.x + to.x) / 2, (from.y + to.y) / 2);
 5    boolean wider = (Math.abs(from.x - to.x) > Math.abs(from.y - to.y));
 6    GeneralPath myPath = new GeneralPath();
 7    myPath.moveTo(from.x, from.y);
 8    if (wider) {
 9        myPath.quadTo(middle.x, from.y, middle.x, middle.y);
10        myPath.quadTo(middle.x, to.y, to.x, to.y);
11    }
 else {
12        myPath.quadTo(from.x, middle.y, middle.x, middle.y);
13        myPath.quadTo(to.x, middle.y, to.x, to.y);
14    }

15
16    return myPath;
17}

18

下图显示了几个这种path的效果:

接下来,再把SNMP获得的数据放入link中的chart呈现。为了避免泄密的麻烦,附件的demo俺去掉了这些业务代码,用一个thread模拟代替了:

 1    Thread thread = new Thread() {
 2
 3        private Vector links = null;
 4
 5        private Vector getLinks() {
 6            if (links == null{
 7                links = new Vector();
 8                Iterator it = network.getDataBox().iterator();
 9                while (it.hasNext()) {
10                    Object o = it.next();
11                    if (o instanceof MyLink) {
12                        MyLink link = (MyLink) o;
13                        links.add(link);
14                    }

15                }

16            }

17            return links;
18        }

19
20        @Override
21        public void run() {
22            while (true{
23                Iterator it = getLinks().iterator();
24                while (it.hasNext()) {
25                    Object o = it.next();
26                    if (o instanceof MyLink) {
27                        MyLink link = (MyLink) o;
28                        createRandomValue(link);
29                        if (TWaverUtil.getRandomInt(10== 1{
30                            link.setSpeed(TWaverUtil.getRandomInt(10000));
31                        }

32                    }

33                }

34                try {
35                    Thread.sleep(100);
36                }
 catch (Exception ex) {
37                    ex.printStackTrace();
38                }

39            }

40        }

41
42        private void createRandomValue(MyLink link) {
43            int value = link.getLastChartValue();
44            int change = TWaverUtil.getRandomInt(3- 1;
45            value = value + change;
46
47            value = Math.min(value, 100);
48            value = Math.max(value, 0);
49
50            link.addChartValue(value);
51        }

52    }
;
53    thread.start();
54}
55

再到google上物色几个清爽的图标。

对了,在结束之际,突然想起一件事:AP上的晃悠悠的电线丝,可不是icon的一部反,而是咱draw上去的!这个小亮点咱得说说:主要思路就是new一个path,模拟其曲线的路径,然后在Swing的paint时候给附加上去。代码如下:

 1@Override
 2public void paintBody(Graphics2D g2d) {
 3    super.paintBody(g2d);
 4
 5    if (((MyNode) getElement()).isWireVisible()) {
 6        Object oldValue = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
 7        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 8        g2d.setColor(wireColor);
 9        g2d.setStroke(TWaverConst.BASIC_STROKE);
10        g2d.draw(createWireShape());
11        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldValue);
12    }

13}

14
15private Shape createWireShape() {
16    Point point = this.getHotspot();
17    int x = point.x - 25;
18    int y = point.y + 23;
19
20    GeneralPath path = new GeneralPath();
21    path.moveTo(x, y);
22    path.curveTo(x + 20, y - 20, x + 50, y - 10, x + 48, y);
23    path.curveTo(x + 48, y + 15, x + 10, y + 10, x + 12, y - 5);
24    path.curveTo(x + 12, y - 20, x + 50, y - 20, x + 53, y);
25    path.quadTo(x + 53, y + 3, x + 51, y + 5);
26    return path;
27}

28

这下终于完整了。看看“晃悠悠的铁丝”效果:

接下来,在程序里面整合一下,整个效果就出来了:

为了和大家共同学习和交流,附上的源代码是从项目中抽取了Swing展示部分,去掉了所有业务逻辑,仅仅为了和大家共享Swing的展示能力,以及拓扑图的制作思路。

在这里可以下载全部源代码、可执行文件、图标资源等内容。


评论

# re: 瞧咱办公室的拓扑图  回复  更多评论   

2010-09-15 09:36 by freeman1984
这文章不知在哪见过

# re: 瞧咱办公室的拓扑图  回复  更多评论   

2010-09-15 16:11 by TWaver
@freeman1984
可能也是我们的TWaver成员发在其他网站上的

# re: 瞧咱办公室的拓扑图  回复  更多评论   

2010-09-19 16:47 by 相信
首页有两个相同的文章啦...不过还是赞一个..很酷.

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


网站导航: