1 package org.wcb.gui.component;
2
3 import java.awt.Color;
4 import java.awt.Component;
5 import java.awt.Dimension;
6 import java.awt.GradientPaint;
7 import java.awt.Graphics;
8 import java.awt.Graphics2D;
9 import java.awt.Insets;
10 import java.awt.Paint;
11 import java.awt.Rectangle;
12 import java.awt.RenderingHints;
13 import java.awt.geom.Area;
14 import java.awt.geom.CubicCurve2D;
15 import java.awt.geom.GeneralPath;
16 import java.awt.geom.Rectangle2D;
17
18 import javax.swing.AbstractButton;
19 import javax.swing.ButtonModel;
20 import javax.swing.JButton;
21 import javax.swing.JComponent;
22 import javax.swing.border.AbstractBorder;
23 import javax.swing.border.CompoundBorder;
24 import javax.swing.plaf.basic.BasicBorders;
25 import javax.swing.plaf.ComponentUI;
26 import javax.swing.plaf.UIResource;
27 import javax.swing.plaf.metal.MetalButtonUI;
28 import javax.swing.plaf.metal.MetalLookAndFeel;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class WaveButtonUI extends MetalButtonUI {
57
58 private static final WaveButtonUI INSTANCE = new WaveButtonUI();
59
60 public static ComponentUI createUI(JComponent b) {
61 return INSTANCE;
62 }
63
64 public void installUI(JComponent c) {
65 super.installUI(c);
66 c.setBorder(new CompoundBorder(new WaveButtonBorder(), new BasicBorders.MarginBorder()));
67 }
68
69 protected Color getSelectColor() {
70 return new Color(0x005092);
71
72 }
73
74 protected void paintButtonPressed(Graphics g, AbstractButton b) {
75 if (b.isContentAreaFilled()) {
76 Graphics2D g2 = (Graphics2D) g;
77 g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
78 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
79 g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
80
81 Dimension size = b.getSize();
82 g2.setColor(getSelectColor());
83 g2.fillRect(0, 0, size.width, size.height);
84 }
85 }
86
87 public void update(Graphics g, JComponent c) {
88 AbstractButton b = (AbstractButton) c;
89 if (c.isOpaque() && b.isContentAreaFilled()) {
90 int width = b.getWidth();
91 int height = b.getHeight();
92
93 g.setColor(b.getBackground());
94 g.fillRect(0, 0, width, height);
95
96 if (!b.getModel().isArmed() && !b.getModel().isPressed()) {
97 Graphics2D g2 = (Graphics2D) g;
98 g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
99 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
100 g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
101
102 CubicCurve2D curve = new CubicCurve2D.Double(0, height, 4, -2, width - 4, height + 2, width, 0);
103 GeneralPath path = new GeneralPath(curve);
104 path.lineTo(width, height);
105 path.lineTo(0, height);
106
107 Rectangle2D fillArea = new Rectangle2D.Double(0, 0, width, height);
108 Area area = new Area(fillArea);
109 area.subtract(new Area(path));
110
111 Paint oldPaint = g2.getPaint();
112
113 Paint p;
114
115 if (b.getModel().isEnabled()) {
116
117 p = new GradientPaint(0, 0, new Color(150, 183, 210), 0, height, new Color(124, 165, 199));
118 g2.setPaint(p);
119 }
120 else {
121 g2.setColor(new Color(245, 245, 245));
122 }
123 g2.fill(area);
124
125 if (b.getModel().isEnabled()) {
126
127 p = new GradientPaint(0, 0, new Color(92, 143, 185), 0, height, new Color(51, 115, 168));
128 g2.setPaint(p);
129 }
130 else {
131 g2.setColor(new Color(227, 227, 227));
132 }
133 g2.fill(path);
134
135 g2.setPaint(oldPaint);
136 }
137 }
138 paint(g, c);
139 }
140
141 protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
142 }
143
144
145
146
147 private static class WaveButtonBorder extends AbstractBorder implements UIResource {
148 protected static final Insets INSETS = new Insets(2, 2, 2, 2);
149
150 public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
151 AbstractButton button = (AbstractButton) c;
152 ButtonModel model = button.getModel();
153
154 if (!model.isEnabled()) {
155 drawDisabledButtonBorder(g, x, y, w, h);
156 return;
157 }
158
159 boolean isPressed = model.isPressed() && model.isArmed();
160 boolean isDefault = button instanceof JButton
161 && ((JButton) button).isDefaultButton();
162 boolean isFocused = button.isFocusPainted() && button.hasFocus();
163
164 if (isPressed) {
165 drawPressedButtonBorder(g, x, y, w, h);
166 }
167 else if (isFocused) {
168 drawFocusedButtonBorder(g, x, y, w, h);
169 }
170 else if (isDefault) {
171 drawDefaultButtonBorder(g, x, y, w, h);
172 }
173 else {
174 drawPlainButtonBorder(g, x, y, w, h);
175 }
176 }
177
178 private void drawPlainButtonBorder(Graphics g, int x, int y, int w, int h) {
179 drawButtonBorder(g, x, y, w, h,
180 MetalLookAndFeel.getControl(),
181 MetalLookAndFeel.getControlDarkShadow(),
182 getSlightlyBrighter(
183 MetalLookAndFeel.getControlDarkShadow(),
184 1.25f)
185 );
186 }
187
188 private void drawPressedButtonBorder(Graphics g, int x, int y, int w, int h) {
189 drawPlainButtonBorder(g, x, y, w, h);
190 Color darkColor =
191 translucentColor(MetalLookAndFeel.getControlDarkShadow(),
192 128);
193 Color lightColor =
194 translucentColor(MetalLookAndFeel.getControlHighlight(),
195 80);
196 g.translate(x, y);
197 g.setColor(darkColor);
198 g.fillRect(2, 1, w - 4, 1);
199
200 g.setColor(lightColor);
201 g.fillRect(2, h - 2, w - 4, 1);
202 g.translate(-x, -y);
203 }
204
205 private void drawDefaultButtonBorder(Graphics g, int x, int y, int w, int h) {
206 drawPlainButtonBorder(g, x, y, w, h);
207 drawInnerButtonDecoration(g, x, y, w, h,
208 new Color(215, 215, 215));
209 }
210
211 private void drawFocusedButtonBorder(Graphics g, int x, int y, int w, int h) {
212 drawPlainButtonBorder(g, x, y, w, h);
213
214 drawInnerButtonDecoration(g, x, y, w, h,
215 new Color(187, 200, 211));
216 }
217
218 private void drawRect(Graphics g, int x, int y, int w, int h) {
219 g.fillRect(x, y, w + 1, 1);
220 g.fillRect(x, y + 1, 1, h);
221 g.fillRect(x + 1, y + h, w, 1);
222 g.fillRect(x + w, y + 1, 1, h);
223 }
224
225 private void drawDisabledButtonBorder(Graphics g, int x, int y, int w, int h) {
226 drawButtonBorder(g, x, y, w, h,
227 MetalLookAndFeel.getControl(),
228 new Color(215, 215, 215),
229 getSlightlyBrighter(new Color(215, 215, 215)));
230 }
231
232 private Color getSlightlyBrighter(Color color) {
233 return getSlightlyBrighter(color, 1.1f);
234 }
235
236 private Color getSlightlyBrighter(Color color, float factor) {
237 float[] hsbValues = new float[3];
238 Color.RGBtoHSB(
239 color.getRed(),
240 color.getGreen(),
241 color.getBlue(),
242 hsbValues);
243 float hue = hsbValues[0];
244 float saturation = hsbValues[1];
245 float brightness = hsbValues[2];
246 float newBrightness = Math.min(brightness * factor, 1.0f);
247 return Color.getHSBColor(hue, saturation, newBrightness);
248 }
249
250 private void drawButtonBorder(
251 Graphics g,
252 int x, int y, int w, int h,
253 Color backgroundColor,
254 Color edgeColor,
255 Color cornerColor) {
256 g.translate(x, y);
257
258 g.setColor(edgeColor);
259 drawRect(g, 0, 0, w - 1, h - 1);
260
261
262 g.setColor(cornerColor);
263 g.fillRect(0, 0, 2, 2);
264 g.fillRect(0, h - 2, 2, 2);
265 g.fillRect(w - 2, 0, 2, 2);
266 g.fillRect(w - 2, h - 2, 2, 2);
267
268
269 g.setColor(backgroundColor);
270 g.fillRect(0, 0, 1, 1);
271 g.fillRect(0, h - 1, 1, 1);
272 g.fillRect(w - 1, 0, 1, 1);
273 g.fillRect(w - 1, h - 1, 1, 1);
274
275 g.translate(-x, -y);
276 }
277
278 private void drawInnerButtonDecoration(
279 Graphics g,
280 int x, int y, int w, int h,
281 Color baseColor) {
282
283 Color lightColor = translucentColor(baseColor, 90);
284 Color mediumColor = translucentColor(baseColor, 120);
285 Color darkColor = translucentColor(baseColor, 200);
286
287 g.translate(x, y);
288 g.setColor(lightColor);
289 g.fillRect(2, 1, w - 4, 1);
290
291 g.setColor(mediumColor);
292 g.fillRect(1, 2, 1, h - 4);
293 g.fillRect(w - 2, 2, 1, h - 4);
294 drawRect(g, 2, 2, w - 5, h - 5);
295
296 g.setColor(darkColor);
297 g.fillRect(2, h - 2, w - 4, 1);
298 g.translate(-x, -y);
299 }
300
301 private static Color translucentColor(Color baseColor, int alpha) {
302 return new Color(baseColor.getRed(),
303 baseColor.getGreen(),
304 baseColor.getBlue(),
305 alpha);
306 }
307
308 public Insets getBorderInsets(Component c) { return INSETS; }
309
310 public Insets getBorderInsets(Component c, Insets newInsets) {
311 newInsets.top = INSETS.top;
312 newInsets.left = INSETS.left;
313 newInsets.bottom = INSETS.bottom;
314 newInsets.right = INSETS.right;
315 return newInsets;
316 }
317 }
318 }