程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> JavaSwing也驚艷之一:水晶之戀

JavaSwing也驚艷之一:水晶之戀

編輯:關於JAVA

一、序言

關於“Java做不好桌面”的爭論已經由來已久。雖然Swing和Java2D已經有超 過十年的歷史,也有JIDE、JGoodies、TWaver等不少開源Swing組件,但是用 Java做桌面程序仍然不是一件輕松的事。本《Java也驚艷》系列文章,就是想通 過一些簡單生動的例子,和大家一起認識Java、探索Swing。其實你只需要多一 點創意、多一點耐心,你的Java程序也可以“驚艷”!本文就帶您一起進入Java 的“水晶之戀”。

二、立體水晶效果

受蘋果公司的影響,現在立體水晶風格的界面非常流行。Java也可以嗎?我 們不妨先嘗試一下用Java繪制一個立體水晶風格的按鈕到底有多難。一個立體的 水晶按鈕應當有一個圖標、一個圓角矩形區域、邊框以及一些立體反光效果,如 下圖:

簡單思路如下:先畫矩形區域,然後畫圖標,然後設置clip並畫高亮反光區 域,最後畫外部邊框。

具體實現比較簡單,主要代碼如下:

Color color = TWaverUtil.getRandomColor();
 RoundRectangle2D body = new RoundRectangle2D.Float(x, y, size, size, 

size / 3, size / 3);
//draw body
g2d.setColor(color);
GradientPaint paint = new GradientPaint(x,
                    y,
                    color.darker(),
                    x,
                    y + size,
                    color.brighter().brighter());
g2d.setPaint(paint);
g2d.fill(body);
//draw image
g2d.setClip(body);
Image image = TWaverUtil.getImage("/glass/" + i + 

".png");
g2d.drawImage(image,
               x + (size - image.getWidth(null)) / 2,
               y + (size - image.getHeight(null)) / 2,
               null);
g2d.setClip(null);
//draw highlight.
Shape highlightArea = createHighlightShape(x, y, size, body);
g2d.setColor(new Color(255, 255, 255, 150));
g2d.fill(highlightArea);
//draw outline.
g2d.setColor(color.darkGray);
g2d.draw(body);

其中,對高亮區域的計算,可以用一個圓心在左上方的大圓形和矩形進行剪 切:

private static Shape createHighlightShape(int centerX, int 

centerY, int size, Shape body) {
double myRadius = size * 4;
  double x = centerX - size * 2.3;
  double y = centerY - size * 3.2;
  Ellipse2D.Double circle = new Ellipse2D.Double(x, y, myRadius, 

myRadius);
  Area area = new Area(circle);
  area.intersect(new Area(body));
  return area;
}

運行程序效果如下:

三、更多變化

根據上面例子稍作形狀變換,可以畫出立體水晶球的按鈕。

Color color = TWaverUtil.getRandomColor();
Ellipse2D.Double circle = new Ellipse2D.Double(centerX - radius, 

centerY - radius, radius * 2, radius * 2);
//draw body
g2d.setColor(color);
GradientPaint paint = new GradientPaint(centerX, centerY, color, 

centerX, centerY + radius * 2, color.brighter().brighter());
g2d.setPaint(paint);
g2d.fill(circle);
//draw image
g2d.setClip(circle);
Image image = TWaverUtil.getImage("/glass/" + i + 

".png");
g2d.drawImage(image,
centerX - image.getWidth(null) / 2,
                 centerY - image.getHeight(null) / 2,
                 null);
g2d.setClip(null);
//draw highlight.
Shape highlightArea = createHighlightShape(centerX, centerY, radius);
g2d.setColor(new Color(255, 255, 255, 150));
g2d.fill(highlightArea);

唯一略有不同的部分是,水晶球的高亮區域要用兩個圓形拼切:

private static Shape createHighlightShape(int centerX, int 

centerY, int radius) {
double myRadius = radius * 0.8;
  double x = centerX - myRadius;
  double y1 = centerY - myRadius - myRadius / 5;
  double y2 = centerY - myRadius - myRadius / 5 * 2;
  Ellipse2D.Double circle1 = new Ellipse2D.Double(x, y1, myRadius * 2, 

myRadius * 2);
  Ellipse2D.Double circle2 = new Ellipse2D.Double(x, y2, myRadius * 2, 

myRadius * 2);
  Area area = new Area(circle1);
  area.intersect(new Area(circle2));
  return area;
}

運行效果如下:

如果再來點兒循環、隨機大小、隨機位置、隨機顏色,就可以做出絢麗的“ 吹肥皂泡”的效果

然後,用這些Icon創建一些按鈕並顯示:

四、融入Swing組件

以上例子僅使用了Java2D進行繪圖。在實際使用中,需要將這些效果應用 的Swing組件中,例如按鈕等。一個簡單的方式是:將以上圖形效果在內存中生 成內存圖片並封裝到一個ImageIcon中,然後將ImageIcon圖標作為JButton的圖 標進行顯示。

public static Image createImageIcon(Image phantom, int size) {
BufferedImage bi = new BufferedImage(size, size, 

BufferedImage.TYPE_INT_ARGB);
  Graphics2D g2d = bi.createGraphics();
  g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 

RenderingHints.VALUE_ANTIALIAS_ON);
  int center = size / 2;
  int radius = center;
  //此處進行畫圖
  g2d.dispose();
  return bi;
}

然後,用這些Icon創建一些按鈕並顯示:

public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
  frame.getContentPane().setLayout(new FlowLayout());
  frame.getContentPane().add(new JButton("按鈕1", new 

ImageIcon(createImageIcon(null, 60))));
  frame.getContentPane().add(new JButton("按鈕2", new 

ImageIcon(createImageIcon(null, 60))));
  frame.getContentPane().add(new JButton("按鈕3", new 

ImageIcon(createImageIcon(null, 60))));
  frame.getContentPane().add(new JButton("使用Java2D創建的立體水

晶風格的按鈕", new ImageIcon(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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved