一、序言
關(guān)于“Java做不好桌面”的爭(zhēng)論已經(jīng)由來(lái)已久。雖然Swing和Java2D已經(jīng)有超過(guò)十年的歷史,也有JIDE、JGoodies、TWaver等不少開源Swing組件,但是用Java做桌面程序仍然不是一件輕松的事。本《Java也驚艷》系列文章,就是想通過(guò)一些簡(jiǎn)單生動(dòng)的例子,和大家一起認(rèn)識(shí)Java、探索Swing。其實(shí)你只需要多一點(diǎn)創(chuàng)意、多一點(diǎn)耐心,你的Java程序也可以“驚艷”!本文就帶您一起進(jìn)入Java的驚艷之旅。
二、立體套管效果
在網(wǎng)絡(luò)通訊中,經(jīng)常要表達(dá)協(xié)議之間的“承載”關(guān)系。例如,IP協(xié)議作為高層協(xié)議可以承載在SDH上,也可以承載在ATM協(xié)議上。同樣,IP作為協(xié)議還可以承載更多的高層協(xié)議,例如Voice over IP,甚至電信中Everything over IP的概念。在表現(xiàn)上,用相互嵌套的立體套管來(lái)表現(xiàn)協(xié)議的“承載”是再合適不過(guò)了(如下圖)。
具體實(shí)現(xiàn)很簡(jiǎn)單,主要代碼如下:
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(800, 600);
frame.add(new PipleComponent());
frame.setVisible(true);
}
}

三、總結(jié)
本文知識(shí)要點(diǎn):
? 漸變填充:創(chuàng)建GradientPaint并設(shè)置“亮-暗-亮”的填充模式;
? 使用Clip:類似蒙版/剪切的Java2D技術(shù)。看看Graphics的setClip函數(shù)即可;
? Area的使用:主要是Area的相交、合并等幾個(gè)常見圖形處理手法。詳細(xì)請(qǐng)看java.awt.geom.Area類;
? 使用隨機(jī)色:這個(gè)就太簡(jiǎn)單了,如果有twaver.jar,可以直接使用TWaverUtil.getRandomColor();如果沒有,就直接new Color就行了,注意使用第四個(gè)int參數(shù)增加Alpha透明度的變化;
如果大家感興趣,可以嘗試用上述Java2D技巧實(shí)現(xiàn)下圖效果:
六、參考資料
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