Merge branch 'master' into subtree
[nikiroo-utils.git] / ui / UIUtils.java
1 package be.nikiroo.utils.ui;
2
3 import java.awt.Color;
4 import java.awt.GradientPaint;
5 import java.awt.Graphics;
6 import java.awt.Graphics2D;
7 import java.awt.Paint;
8 import java.awt.RadialGradientPaint;
9 import java.awt.RenderingHints;
10
11 import javax.swing.UIManager;
12 import javax.swing.UnsupportedLookAndFeelException;
13
14 /**
15 * Some Java Swing utilities.
16 *
17 * @author niki
18 */
19 public class UIUtils {
20 /**
21 * Set a fake "native look & feel" for the application if possible
22 * (check for the one currently in use, then try GTK).
23 * <p>
24 * <b>Must</b> be called prior to any GUI work.
25 */
26 static public void setLookAndFeel() {
27 // native look & feel
28 try {
29 String noLF = "javax.swing.plaf.metal.MetalLookAndFeel";
30 String lf = UIManager.getSystemLookAndFeelClassName();
31 if (lf.equals(noLF))
32 lf = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
33 UIManager.setLookAndFeel(lf);
34 } catch (InstantiationException e) {
35 } catch (ClassNotFoundException e) {
36 } catch (UnsupportedLookAndFeelException e) {
37 } catch (IllegalAccessException e) {
38 }
39 }
40
41 /**
42 * Draw a 3D-looking ellipse at the given location, if the given
43 * {@link Graphics} object is compatible (with {@link Graphics2D}); draw a
44 * simple ellipse if not.
45 *
46 * @param g
47 * the {@link Graphics} to draw on
48 * @param color
49 * the base colour
50 * @param x
51 * the X coordinate
52 * @param y
53 * the Y coordinate
54 * @param width
55 * the width radius
56 * @param height
57 * the height radius
58 */
59 static public void drawEllipse3D(Graphics g, Color color, int x, int y, int width, int height) {
60 drawEllipse3D(g, color, x, y, width, height, true);
61 }
62
63 /**
64 * Draw a 3D-looking ellipse at the given location, if the given
65 * {@link Graphics} object is compatible (with {@link Graphics2D}); draw a
66 * simple ellipse if not.
67 *
68 * @param g
69 * the {@link Graphics} to draw on
70 * @param color
71 * the base colour
72 * @param x
73 * the X coordinate
74 * @param y
75 * the Y coordinate
76 * @param width
77 * the width radius
78 * @param height
79 * the height radius
80 * @param fill
81 * fill the content of the ellipse
82 */
83 static public void drawEllipse3D(Graphics g, Color color, int x, int y,
84 int width, int height, boolean fill) {
85 if (g instanceof Graphics2D) {
86 Graphics2D g2 = (Graphics2D) g;
87 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
88 RenderingHints.VALUE_ANTIALIAS_ON);
89
90 // Retains the previous state
91 Paint oldPaint = g2.getPaint();
92
93 // Base shape
94 g2.setColor(color);
95 if (fill) {
96 g2.fillOval(x, y, width, height);
97 } else {
98 g2.drawOval(x, y, width, height);
99 }
100
101 // Compute dark/bright colours
102 Paint p = null;
103 Color dark = color.darker().darker();
104 Color bright = color.brighter().brighter();
105 Color darkEnd = new Color(dark.getRed(), dark.getGreen(),
106 dark.getBlue(), 0);
107 Color darkPartial = new Color(dark.getRed(), dark.getGreen(),
108 dark.getBlue(), 64);
109 Color brightEnd = new Color(bright.getRed(), bright.getGreen(),
110 bright.getBlue(), 0);
111
112 // Adds shadows at the bottom left
113 p = new GradientPaint(0, height, dark, width, 0, darkEnd);
114 g2.setPaint(p);
115 if (fill) {
116 g2.fillOval(x, y, width, height);
117 } else {
118 g2.drawOval(x, y, width, height);
119 }
120 // Adds highlights at the top right
121 p = new GradientPaint(width, 0, bright, 0, height, brightEnd);
122 g2.setPaint(p);
123 if (fill) {
124 g2.fillOval(x, y, width, height);
125 } else {
126 g2.drawOval(x, y, width, height);
127 }
128
129 // Darken the edges
130 p = new RadialGradientPaint(x + width / 2f, y + height / 2f,
131 Math.min(width / 2f, height / 2f), new float[] { 0f, 1f },
132 new Color[] { darkEnd, darkPartial },
133 RadialGradientPaint.CycleMethod.NO_CYCLE);
134 g2.setPaint(p);
135 if (fill) {
136 g2.fillOval(x, y, width, height);
137 } else {
138 g2.drawOval(x, y, width, height);
139 }
140
141 // Adds inner highlight at the top right
142 p = new RadialGradientPaint(x + 3f * width / 4f, y + height / 4f,
143 Math.min(width / 4f, height / 4f),
144 new float[] { 0.0f, 0.8f },
145 new Color[] { bright, brightEnd },
146 RadialGradientPaint.CycleMethod.NO_CYCLE);
147 g2.setPaint(p);
148 if (fill) {
149 g2.fillOval(x * 2, y, width, height);
150 } else {
151 g2.drawOval(x * 2, y, width, height);
152 }
153
154 // Reset original paint
155 g2.setPaint(oldPaint);
156 } else {
157 g.setColor(color);
158 if (fill) {
159 g.fillOval(x, y, width, height);
160 } else {
161 g.drawOval(x, y, width, height);
162 }
163 }
164 }
165 }