一序言
關於Java做不好桌面的爭論已經由來已久雖然Swing和JavaD已經有超過十年的歷史也有JIDEJGoodiesTWaver等不少開源Swing組件但是用Java做桌面程序仍然不是一件輕松的事本《Java也驚艷》系列文章就是想通過一些簡單生動的例子和大家一起認識Java探索Swing其實你只需要多一點創意多一點耐心你的Java程序也可以驚艷!本文就帶您一起進入Java的水晶之戀
二立體水晶效果
受蘋果公司的影響現在立體水晶風格的界面非常流行Java也可以嗎?我們不妨先嘗試一下用Java繪制一個立體水晶風格的按鈕到底有多難一個立體的水晶按鈕應當有一個圖標一個圓角矩形區域邊框以及一些立體反光效果如下圖
簡單思路如下先畫矩形區域然後畫圖標然後設置clip並畫高亮反光區域最後畫外部邊框
具體實現比較簡單主要代碼如下
Color color = TWaverUtilgetRandomColor();
RoundRectangleD body = new RoundRectangleDFloat(x y size size size / size / );
//draw body
gdsetColor(color);
GradientPaint paint = new GradientPaint(x
y
colordarker()
x
y + size
colorbrighter()brighter());
gdsetPaint(paint);
gdfill(body);
//draw image
gdsetClip(body);
Image image = TWaverUtilgetImage(/glass/ + i + png);
gddrawImage(image
x + (size imagegetWidth(null)) /
y + (size imagegetHeight(null)) /
null);
gdsetClip(null);
//draw highlight
Shape highlightArea = createHighlightShape(x y size body);
gdsetColor(new Color( ));
gdfill(highlightArea);
//draw outline
gdsetColor(colordarkGray);
gddraw(body);
其中對高亮區域的計算可以用一個圓心在左上方的大圓形和矩形進行剪切
private static Shape createHighlightShape(int centerX int centerY int size Shape body) {
double myRadius = size * ;
double x = centerX size * ;
double y = centerY size * ;
EllipseDDouble circle = new EllipseDDouble(x y myRadius myRadius);
Area area = new Area(circle);
areaintersect(new Area(body));
return area;
}
運行程序效果如下
三更多變化
根據上面例子稍作形狀變換可以畫出立體水晶球的按鈕
Color color = TWaverUtilgetRandomColor();
EllipseDDouble circle = new EllipseDDouble(centerX radius centerY radius radius * radius * );
//draw body
gdsetColor(color);
GradientPaint paint = new GradientPaint(centerX centerY color centerX centerY + radius * colorbrighter()brighter());
gdsetPaint(paint);
gdfill(circle);
//draw image
gdsetClip(circle);
Image image = TWaverUtilgetImage(/glass/ + i + png);
gddrawImage(image
centerX imagegetWidth(null) /
centerY imagegetHeight(null) /
null);
gdsetClip(null);
//draw highlight
Shape highlightArea = createHighlightShape(centerX centerY radius);
gdsetColor(new Color( ));
gdfill(highlightArea);
唯一略有不同的部分是水晶球的高亮區域要用兩個圓形拼切
private static Shape createHighlightShape(int centerX int centerY int radius) {
double myRadius = radius * ;
double x = centerX myRadius;
double y = centerY myRadius myRadius / ;
double y = centerY myRadius myRadius / * ;
EllipseDDouble circle = new EllipseDDouble(x y myRadius * myRadius * );
EllipseDDouble circle = new EllipseDDouble(x y myRadius * myRadius * );
Area area = new Area(circle);
areaintersect(new Area(circle));
return area;
}
運行效果如下
如果再來點兒循環隨機大小隨機位置隨機顏色就可以做出絢麗的吹肥皂泡的效果
四融入Swing組件
以上例子僅使用了JavaD進行繪圖在實際使用中需要將這些效果應用的Swing組件中例如按鈕等一個簡單的方式是將以上圖形效果在內存中生成內存圖片並封裝到一個ImageIcon中然後將ImageIcon圖標作為JButton的圖標進行顯示
public static Image createImageIcon(Image phantom int size) {
BufferedImage bi = new BufferedImage(size size BufferedImageTYPE_INT_ARGB);
GraphicsD gd = bicreateGraphics();
gdsetRenderingHint(RenderingHintsKEY_ANTIALIASING RenderingHintsVALUE_ANTIALIAS_ON);
int center = size / ;
int radius = center;
//此處進行畫圖
gddispose();
return bi;
}
然後用這些Icon創建一些按鈕並顯示
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
framegetContentPane()setLayout(new FlowLayout());
framegetContentPane()add(new JButton(按鈕 new ImageIcon(createImageIcon(null ))));
framegetContentPane()add(new JButton(按鈕 new ImageIcon(createImageIcon(null ))));
framegetContentPane()add(new JButton(按鈕 new ImageIcon(createImageIcon(null ))));
framegetContentPane()add(new JButton(使用JavaD創建的立體水晶風格的按鈕 new ImageIcon(createImageIcon(null ))));
framesetSize( );
framesetTitle(Java也驚艷);
framesetDefaultCloseOperation(JFrameEXIT_ON_CLOSE);
TWaverUtilcenterWindow(frame);
framesetVisible(true);
}
效果如下圖
本例子沒有使用Look And Feel你也可以使用JGoodies來美化一下效果肯定更好
五總結
可以看出畫出這類立體水晶效果並不難只需仔細觀察這些效果的光學細節並用JavaD的API來實現即可這些例子稍作改進就可以用來繪制JButton等Swing組件並用在實際項目中或者也可以應用這些技巧來做一些復雜圖形界面如在TWaver中做出的網絡拓撲圖效果
本文知識要點
■ 漸變填充這個使用GradientPaint就行了
■ 使用Clip類似蒙版/剪切的JavaD技術看看Graphics的setClip函數就明白了
■ Area的使用主要是Area的相交合並等幾個常見圖形處理手法詳細請看javaawtgeomArea類
■ 生成內存圖片主要是BufferedImage類的使用
如果大家感興趣可以嘗試用上述JavaD技巧實現下圖效果
六參考資料
l
~hall/java/l
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26754.html