JavaSwing也惊艳之一:水晶之恋

一、序言

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

二、立体水晶效果

受苹果公司的影响,现在立体水晶风格的界面非常流行。Java也可以吗?我们不妨先尝试一下用Java绘制一个立体水晶风格的按钮到底有多难。一个立体的水晶按钮应当有一个图标、一个圆角矩形区域、边框以及一些立体反光效果,如下图:

简单思路如下:先画矩形区域,然后画图标,然后设置clip并画高亮反光区域,最后画外部边框。

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

Colorcolor=TWaverUtil.getRandomColor();
RoundRectangle2Dbody=newRoundRectangle2D.Float(x,y,size,size,size/3,size/3);

//drawbody
g2d.setColor(color);
GradientPaintpaint=newGradientPaint(x,
y,
color.darker(),
x,
y+size,
color.brighter().brighter());
g2d.setPaint(paint);
g2d.fill(body);

//drawimage
g2d.setClip(body);
Imageimage=TWaverUtil.getImage("/glass/"+i+".png");
g2d.drawImage(image,
x+(size-image.getWidth(null))/2,
y+(size-image.getHeight(null))/2,
null);
g2d.setClip(null);

//drawhighlight.
ShapehighlightArea=createHighlightShape(x,y,size,body);
g2d.setColor(newColor(255,255,255,150));
g2d.fill(highlightArea);

//drawoutline.
g2d.setColor(color.darkGray);
g2d.draw(body);

其中,对高亮区域的计算,可以用一个圆心在左上方的大圆形和矩形进行剪切:
privatestaticShapecreateHighlightShape(intcenterX,intcenterY,intsize,Shapebody){
doublemyRadius=size*4;
doublex=centerX-size*2.3;
doubley=centerY-size*3.2;
Ellipse2D.Doublecircle=newEllipse2D.Double(x,y,myRadius,myRadius);
Areaarea=newArea(circle);
area.intersect(newArea(body));
returnarea;
}

运行程序效果如下:


三、更多变化

根据上面例子稍作形状变换,可以画出立体水晶球的按钮。
Colorcolor=TWaverUtil.getRandomColor();

Ellipse2D.Doublecircle=newEllipse2D.Double(centerX-radius,centerY-radius,radius*2,radius*2);

//drawbody
g2d.setColor(color);
GradientPaintpaint=newGradientPaint(centerX,centerY,color,centerX,centerY+radius*2,color.brighter().brighter());
g2d.setPaint(paint);
g2d.fill(circle);

//drawimage
g2d.setClip(circle);
Imageimage=TWaverUtil.getImage("/glass/"+i+".png");
g2d.drawImage(image,
centerX-image.getWidth(null)/2,
centerY-image.getHeight(null)/2,
null);
g2d.setClip(null);

//drawhighlight.
ShapehighlightArea=createHighlightShape(centerX,centerY,radius);
g2d.setColor(newColor(255,255,255,150));
g2d.fill(highlightArea);

唯一略有不同的部分是,水晶球的高亮区域要用两个圆形拼切:

privatestaticShapecreateHighlightShape(intcenterX,intcenterY,intradius){
doublemyRadius=radius*0.8;
doublex=centerX-myRadius;
doubley1=centerY-myRadius-myRadius/5;
doubley2=centerY-myRadius-myRadius/5*2;

Ellipse2D.Doublecircle1=newEllipse2D.Double(x,y1,myRadius*2,myRadius*2);
Ellipse2D.Doublecircle2=newEllipse2D.Double(x,y2,myRadius*2,myRadius*2);

Areaarea=newArea(circle1);
area.intersect(newArea(circle2));
returnarea;
}

运行效果如下:


如果再来点儿循环、随机大小、随机位置、随机颜色,就可以做出绚丽的“吹肥皂泡”的效果


四、融入Swing组件

以上例子仅使用了Java2D进行绘图。在实际使用中,需要将这些效果应用的Swing组件中,例如按钮等。一个简单的方式是:将以上图形效果在内存中生成内存图片并封装到一个ImageIcon中,然后将ImageIcon图标作为JButton的图标进行显示。

publicstaticImagecreateImageIcon(Imagephantom,intsize){
BufferedImagebi=newBufferedImage(size,size,BufferedImage.TYPE_INT_ARGB);
Graphics2Dg2d=bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

intcenter=size/2;
intradius=center;

//此处进行画图

g2d.dispose();
returnbi;
}

然后,用这些Icon创建一些按钮并显示:

publicstaticvoidmain(String[]args)throwsException{
JFrameframe=newJFrame();
frame.getContentPane().setLayout(newFlowLayout());
frame.getContentPane().add(newJButton("按钮1",newImageIcon(createImageIcon(null,60))));
frame.getContentPane().add(newJButton("按钮2",newImageIcon(createImageIcon(null,60))));
frame.getContentPane().add(newJButton("按钮3",newImageIcon(createImageIcon(null,60))));
frame.getContentPane().add(newJButton("使用Java2D创建的立体水晶风格的按钮",newImageIcon(createImageIcon(null,30))));
frame.setSize(500,300);
frame.setTitle("Java也惊艳");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TWaverUtil.centerWindow(frame);
frame.setVisible(true);
}

效果如下图:

本例子没有使用Look And Feel。你也可以使用JGoodies来美化一下,效果肯定更好。

五、总结

可以看出,画出这类立体水晶效果并不难,只需仔细观察这些效果的光学细节,并用Java2D的API来实现即可。这些例子稍作改进,就可以用来绘制JButton等Swing组件,并用在实际项目中。或者,也可以应用这些技巧来做一些复杂图形界面,如在TWaver中做出的网络拓扑图效果:

本文知识要点:

n 渐变填充:这个使用GradientPaint就行了;

n 使用Clip:类似蒙版/剪切的Java2D技术。看看Graphics的setClip函数就明白了;

n Area的使用:主要是Area的相交、合并等几个常见图形处理手法。详细请看java.awt.geom.Area类;

n 生成内存图片:主要是BufferedImage类的使用;

如果大家感兴趣,可以尝试用上述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



From:http://www.blogjava.net/Swing/archive/2009/02/22/255676.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值