看来我们的JTextField之旅也到了一个阶段,已经很不错了,现在我们来改造JButton,让那个呆板的Swing看起来舒服一些。
还是先放上完成后的效果图:
普通的状态
鼠标滑过
鼠标按下
和代码:
1 /**
2 * @(#)RJButton.java 0.1.0 2007-9-11
3 */
4 package ruislan.rswing;
5
6 import java.awt.AlphaComposite;
7 import java.awt.Color;
8 import java.awt.Font;
9 import java.awt.GradientPaint;
10 import java.awt.Graphics;
11 import java.awt.Graphics2D;
12 import java.awt.RenderingHints;
13 import java.awt.Shape;
14 import java.awt.event.MouseAdapter;
15 import java.awt.event.MouseEvent;
16 import java.awt.geom.RoundRectangle2D;
17
18 import javax.swing.JButton;
19
20 /**
21 * Custom JButton
22 *
23 * @version 0.1.0
24 * @author ruislan <a href="mailto:z17520@126.com"/>
25 */
26 public class RButton extends JButton {
27 private static final long serialVersionUID = 39082560987930759L;
28 public static final Color BUTTON_COLOR1 = new Color(205, 255, 205);
29 public static final Color BUTTON_COLOR2 = new Color(51, 154, 47);
30 // public static final Color BUTTON_COLOR1 = new Color(125, 161, 237);
31 // public static final Color BUTTON_COLOR2 = new Color(91, 118, 173);
32 public static final Color BUTTON_FOREGROUND_COLOR = Color.WHITE;
33 private boolean hover;
34
35 public RButton() {
36 setFont(new Font("system", Font.PLAIN, 12));
37 setBorderPainted(false);
38 setForeground(BUTTON_COLOR2);
39 setFocusPainted(false);
40 setContentAreaFilled(false);
41 addMouseListener(new MouseAdapter() {
42 @Override
43 public void mouseEntered(MouseEvent e) {
44 setForeground(BUTTON_FOREGROUND_COLOR);
45 hover = true;
46 repaint();
47 }
48
49 @Override
50 public void mouseExited(MouseEvent e) {
51 setForeground(BUTTON_COLOR2);
52 hover = false;
53 repaint();
54 }
55 });
56 }
57
58 @Override
59 protected void paintComponent(Graphics g) {
60 Graphics2D g2d = (Graphics2D) g.create();
61 int h = getHeight();
62 int w = getWidth();
63 float tran = 1F;
64 if (!hover) {
65 tran = 0.3F;
66 }
67
68 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
69 RenderingHints.VALUE_ANTIALIAS_ON);
70 GradientPaint p1;
71 GradientPaint p2;
72 if (getModel().isPressed()) {
73 p1 = new GradientPaint(0, 0, new Color(0, 0, 0), 0, h - 1,
74 new Color(100, 100, 100));
75 p2 = new GradientPaint(0, 1, new Color(0, 0, 0, 50), 0, h - 3,
76 new Color(255, 255, 255, 100));
77 } else {
78 p1 = new GradientPaint(0, 0, new Color(100, 100, 100), 0, h - 1,
79 new Color(0, 0, 0));
80 p2 = new GradientPaint(0, 1, new Color(255, 255, 255, 100), 0,
81 h - 3, new Color(0, 0, 0, 50));
82 }
83 g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
84 tran));
85 RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0, w - 1,
86 h - 1, 20, 20);
87 Shape clip = g2d.getClip();
88 g2d.clip(r2d);
89 GradientPaint gp = new GradientPaint(0.0F, 0.0F, BUTTON_COLOR1, 0.0F,
90 h, BUTTON_COLOR2, true);
91 g2d.setPaint(gp);
92 g2d.fillRect(0, 0, w, h);
93 g2d.setClip(clip);
94 g2d.setPaint(p1);
95 g2d.drawRoundRect(0, 0, w - 1, h - 1, 20, 20);
96 g2d.setPaint(p2);
97 g2d.drawRoundRect(1, 1, w - 3, h - 3, 18, 18);
98 g2d.dispose();
99 super.paintComponent(g);
100 }
101 }
102
注意代码中的几个部分:
首先是paintComponent方法中最后一行,我们调用了父类的paintComponent方法,这是因为我们要靠父类来绘制字符,但是父类的这个方法除了绘制字符之外还会绘制其他的,所以我们需要关闭掉其他的(当然我们也可以自己来绘制字符,但是JButton提供了方法为什么不用呢),所以我们在构造方法那里调用了:
setBorderPainted(false);
setFocusPainted(false);
setContentAreaFilled(false);
告诉父类不用绘制边框,不用绘制焦点,不用绘制内容部分,这部分我们自己来搞*o*。
然后就是这一句了g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)告诉绘制API我们需要平滑一点,否则绘制出来会有很多锯齿哟。
接下来的这一句g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,tran))告诉绘图API我们需要绘制一个有透明度的,tran就是透明度(0-1)。
然后就是将边框的边角变直角为圆角,我们绘制一个RoundRectangle2D,这个就是边角都为圆角的方形,然后我们根据这个方形来clip我们的方形,这样方形就被RoundRectangle2D的圆角方形包裹,从而变成了圆角方形。
最后就是绘制外边线和内边线,通过改变内边线和外边线的色变从而造成陷入或者突出效果。
整个JButton改造完毕,如果你能够活用clip的话,你也可以做一个五角星的JButton哟。
整个源代码我连同Eclipse工程文件已经打包成zip放在我的文件里面,下载链接如下:
http://www.blogjava.net/Files/ruislan/rswing-0.1.0.zip
posted on 2007-09-11 12:24
ruislan 阅读(5538)
评论(20) 编辑 收藏