Swing


天行健 君子以自强不息

posts - 69, comments - 215, trackbacks - 0, articles - 16
   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

JavaSwing也惊艳之二:环环相套

Posted on 2009-03-03 22:22 zht 阅读(3002) 评论(10)  编辑  收藏 所属分类: Swing

一、序言

关于“Java做不好桌面”的争论已经由来已久。虽然Swing和Java2D已经有超过十年的历史,也有JIDE、JGoodies、TWaver等不少开源Swing组件,但是用Java做桌面程序仍然不是一件轻松的事。本《Java也惊艳》系列文章,就是想通过一些简单生动的例子,和大家一起认识Java、探索Swing。其实你只需要多一点创意、多一点耐心,你的Java程序也可以“惊艳”!本文就带您一起进入Java的惊艳之旅。

二、立体套管效果

在网络通讯中,经常要表达协议之间的“承载”关系。例如,IP协议作为高层协议可以承载在SDH上,也可以承载在ATM协议上。同样,IP作为协议还可以承载更多的高层协议,例如Voice over IP,甚至电信中Everything over IP的概念。在表现上,用相互嵌套的立体套管来表现协议的“承载”是再合适不过了(如下图)。



具体实现很简单,主要代码如下:

import java.awt.*
import java.awt.geom.*

import javax.swing.*


import twaver.*


public class PipleComponent extends
 JComponent { 

    
public void
 paint(Graphics g) { 
        Graphics2D g2d 
=
 (Graphics2D) g; 
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
        Shape parentHollowShape
=createPiple(g2d,100,100,200,200,TWaverUtil.getRandomColor(),null
); 
        createPiple(g2d,
120,120,280,40
,TWaverUtil.getRandomColor(),parentHollowShape); 
        createPiple(g2d,
130,170,310,40
,TWaverUtil.getRandomColor(),parentHollowShape); 
        createPiple(g2d,
140,220,290,50
,TWaverUtil.getRandomColor(),parentHollowShape); 
        createPiple(g2d,
130,190,300,30
,TWaverUtil.getRandomColor(),parentHollowShape); 
    } 

    
private Shape createPiple(Graphics2D g2d,int x, int y, int width, int
 height,Color color,Shape parentHollowShape) { 
        
if(parentHollowShape!=null
){ 
            Rectangle bounds
=
parentHollowShape.getBounds(); 
            Rectangle rightClip
=new Rectangle(bounds.x+bounds.width/2,bounds.y,3000
,bounds.height); 
            Area clip
=new
 Area(parentHollowShape); 
            clip.add(
new
 Area(rightClip)); 
            g2d.setClip(clip); 
        } 
        
int circleWidth = height/3

        GradientPaint paint 
= new
 GradientPaint(x, 
                                                y, 
                                                color.brighter(), 
                                                x, 
                                                y 
+ (int) (height * 0.65
), 
                                                color.darker(), 
                                                
true
); 
        g2d.setPaint(paint); 
        Ellipse2D.Double leftCircle 
= new Ellipse2D.Double(x - circleWidth / 2
, y, circleWidth, height); 
        Ellipse2D.Double rightCircle 
= new Ellipse2D.Double(x + width - circleWidth / 2
, y, circleWidth, height); 
        
        
int thickness=4

        Ellipse2D.Double rightHollowCircle 
= new Ellipse2D.Double(rightCircle.getX()+
thickness, 
            rightCircle.getY()
+
thickness, 
            rightCircle.getWidth()
-thickness*2

            rightCircle.getHeight()
-thickness*2
); 
        
        Rectangle rect 
= new
 Rectangle(x, y, width, height); 
        Area area 
= new
 Area(leftCircle); 
        area.add(
new
 Area(rect)); 
        area.subtract(
new
 Area(rightCircle)); 
        g2d.fill(area); 
        g2d.setColor(color.darker()); 
        g2d.fill(rightCircle); 
        
        paint 
= new
 GradientPaint(x, 
                                  y, 
                                  Color.darkGray, 
                                  x, 
                                  y 
+ (int) (height * 0.4
), 
                                  Color.lightGray, 
                                  
true
); 

        g2d.setPaint(paint); 
        g2d.fill(rightHollowCircle); 
        
        g2d.setClip(
null
); 
        
        
return
 rightHollowCircle; 
    } 

    
public static void
 main(String[] args) { 
        JFrame frame 
= new
 JFrame(); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.setSize(
800600
); 
        frame.add(
new
 PipleComponent()); 
        frame.setVisible(
true
); 
    } 
}

三、总结

本文知识要点:
 渐变填充:创建GradientPaint并设置“亮-暗-亮”的填充模式;
 使用Clip:类似蒙版/剪切的Java2D技术。看看Graphics的setClip函数即可;
 Area的使用:主要是Area的相交、合并等几个常见图形处理手法。详细请看java.awt.geom.Area类;
 使用随机色:这个就太简单了,如果有twaver.jar,可以直接使用TWaverUtil.getRandomColor();如果没有,就直接new Color就行了,注意使用第四个int参数增加Alpha透明度的变化;

如果大家感兴趣,可以尝试用上述Java2D技巧实现下图效果:


 

六、参考资料

http://java.sun.com/j2se/1.4.2/docs/guide/2d/spec/j2d-bookTOC.html

http://java.sun.com/j2se/1.4.2/docs/guide/2d/spec.html

http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html