JButton大改造
【IT168技术资讯】看来我们的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哟。