1   package org.wcb.gui.component;
2   
3   import javax.swing.*;
4   import java.awt.event.MouseListener;
5   import java.awt.event.MouseEvent;
6   import java.awt.*;
7   import java.awt.geom.Point2D;
8   
9   /**
10   * <small>
11   * Copyright (c)  2006  wbogaardt.
12   * This library is free software; you can redistribute it and/or
13   * modify it under the terms of the GNU Lesser General Public
14   * License as published by the Free Software Foundation; either
15   * version 2.1 of the License, or (at your option) any later version.
16   *
17   * This library is distributed in the hope that it will be useful,
18   * but WITHOUT ANY WARRANTY; without even the implied warranty of
19   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20   * Lesser General Public License for more details.
21   *
22   * You should have received a copy of the GNU Lesser General Public
23   * License along with this library; if not, write to the Free Software
24   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
25   * <p/>
26   * $File:  $ <br>
27   * $Change:  $ submitted by $Author: wbogaardt $ at $DateTime: Mar 29, 2006 4:03:35 PM $ <br>
28   * </small>
29   *
30   * @author wbogaardt
31   * @version 1
32   *          Date: Mar 29, 2006
33   *          Time: 4:03:35 PM
34   */
35  
36  public class VectorButton extends JButton implements MouseListener {
37  
38      protected boolean pressed = false;
39  
40      public VectorButton() {
41          this(null);
42      }
43  
44      public VectorButton(String text) {
45          setText(text);
46          this.addMouseListener(this);
47      }
48  
49      public Dimension getPreferredSize() {
50          String text = getText();
51          FontMetrics fm = this.getFontMetrics(getFont());
52          float scale = (50f / 30f) * this.getFont().getSize2D();
53          int w = fm.stringWidth(text);
54          w += (int) (scale * 1.4f);
55          int h = fm.getHeight();
56          h += (int) (scale * .3f);
57          return new Dimension(w, h);
58      }
59  
60      public void paintComponent(Graphics g)  {
61          Graphics2D g2 = (Graphics2D) g;
62          g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
63          g2.setColor(this.getBackground());
64          g2.fillRect(0, 0, this.getWidth(), this.getHeight());
65  
66          float scale = (50f / 30f) * this.getFont().getSize2D();
67  
68          drawLiquidButton(this.getForeground(), this.getWidth(), this.getHeight(), getText(), scale, g2);
69      }
70  
71      protected void drawLiquidButton(Color base, int width, int height, String text, float scale, Graphics2D g2) {
72  
73          //calculate inset
74          int inset = (int) (scale * 0.04f);
75          int w = width - inset * 2 - 1;
76          int h = height - (int) (scale * 0.1f) - 1;
77  
78          g2.translate(inset, 0);
79  
80          drawDropShadow(w, h, scale, g2);
81  
82          if (pressed) {
83              g2.translate(0, 0.04f * scale);
84          }
85  
86          drawButtonBody(w, h, scale, base, g2);
87          drawText(w, h, scale, text, g2);
88          drawHighlight(w, h, scale, base, g2);
89          drawBorder(w, h, scale, g2);
90  
91          if (pressed) {
92              g2.translate(0, 0.04f * scale);
93          }
94          g2.translate(-inset, 0);
95      }
96  
97      protected void drawDropShadow(int w, int h, float scale, Graphics2D g2) {
98          g2.setColor(new Color(0, 0, 50));
99          fillRoundRect(g2, (-.04f) * scale, (.02f) * scale, w + .08f * scale, h + 0.08f * scale, scale * 1.04f, scale * 1.04f);
100         g2.setColor(new Color(0, 0, 0, 100));
101         fillRoundRect(g2, 0, 0.06f * scale, w, h, scale, scale);
102 
103     }
104 
105     protected void drawButtonBody(int w, int h, float scale, Color base, Graphics2D g2) {
106         Color grad_top = base.brighter();
107         Color grad_bot = base.darker();
108         GradientPaint bg = new GradientPaint(new Point(0, 0), grad_top, new Point(0, h), grad_bot);
109         g2.setPaint(bg);
110         this.fillRoundRect(g2, (0) * scale, (0) * scale, w, h, 1 * scale, 1 * scale);
111         // draw the inner color
112         Color inner = base.brighter();
113         inner = alphaColor(inner, 75);
114         g2.setColor(inner);
115         this.fillRoundRect(g2, scale * (.4f), scale * (.4f), w - scale * .8f, h - scale * .5f, scale * .6f, scale * .4f);
116     }
117 
118     protected static Color alphaColor(Color color, int alpha) {
119         return new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
120     }
121 
122     protected void drawText(int w, int h, float scale, String text, Graphics2D g2) {
123 
124         //calculate the width and height
125         int fw = g2.getFontMetrics().stringWidth(text);
126         int fh = g2.getFontMetrics().getAscent() - g2.getFontMetrics().getDescent();
127 
128         int textx = (w - fw) / 2;
129         int texty = h / 2 + fh / 2;
130 
131         //draw the text
132         g2.setColor(new Color(0, 0, 0, 70));
133         g2.drawString(text, (int) ((float) textx + scale * (0.04f)), (int) ((float) texty + scale * (0.04f)));
134         g2.setColor(Color.BLACK);
135         g2.drawString(text, textx, texty);
136     }
137 
138     protected void drawHighlight(int w, int h, float scale, Color base, Graphics2D g2) {
139         // create the highlight
140         GradientPaint highlight = new GradientPaint(
141             new Point2D.Float(scale * 0.2f, scale * 0.2f),
142             new Color(255, 255, 255, 175),
143             new Point2D.Float(scale * 0.2f, scale * 0.55f),
144             new Color(255, 255, 255, 0)
145             );
146         g2.setPaint(highlight);
147         this.fillRoundRect(g2, scale * 0.2f, scale * 0.1f,
148             w - scale * 0.4f, scale * 0.4f, scale * 0.8f, scale * 0.4f);
149         this.drawRoundRect(g2, scale * 0.2f, scale * 0.1f,
150             w - scale * 0.4f, scale * 0.4f, scale * 0.8f, scale * 0.4f);
151     }
152 
153     protected void drawBorder(int w, int h,
154         float scale, Graphics2D g2) {
155         // draw the border
156         g2.setColor(new Color(0, 0, 0, 150));
157         this.drawRoundRect(g2,
158             scale * (0f),
159             scale * (0f),
160             w, h, scale, scale);
161     }
162 
163     protected static void fillRoundRect(Graphics2D g2, float x, float y, float w, float h, float ax, float ay) {
164         g2.fillRoundRect((int) x, (int) y, (int) w, (int) h, (int) ax, (int) ay);
165     }
166 
167     // float version of draw round rect
168     protected static void drawRoundRect(Graphics2D g2,
169                 float x, float y,
170                 float w, float h,
171                 float ax, float ay) {
172         g2.drawRoundRect(
173             (int) x, (int) y,
174             (int) w, (int) h,
175             (int) ax, (int) ay
176             );
177     }
178 
179      /* mouse listener implementation */
180     public void mouseExited(MouseEvent evt) { }
181     public void mouseEntered(MouseEvent evt) { }
182     public void mouseClicked(MouseEvent evt) { }
183     public void mouseReleased(MouseEvent evt) {
184         pressed = false;
185     }
186     public void mousePressed(MouseEvent evt) {
187         pressed = true;
188     }
189 }