Merge commit '8b2627ce767579eb616e262b3f45f810a88ec200'
[fanfix.git] / src / be / nikiroo / utils / 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.JComponent;
12 import javax.swing.JScrollPane;
13 import javax.swing.UIManager;
14 import javax.swing.UnsupportedLookAndFeelException;
15
16 /**
17 * Some Java Swing utilities.
18 *
19 * @author niki
20 */
21 public class UIUtils {
22 /**
23 * Set a fake "native look & feel" for the application if possible
24 * (check for the one currently in use, then try GTK).
25 * <p>
26 * <b>Must</b> be called prior to any GUI work.
27 */
28 static public void setLookAndFeel() {
29 // native look & feel
30 try {
31 String noLF = "javax.swing.plaf.metal.MetalLookAndFeel";
32 String lf = UIManager.getSystemLookAndFeelClassName();
33 if (lf.equals(noLF))
34 lf = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
35 UIManager.setLookAndFeel(lf);
36 } catch (InstantiationException e) {
37 } catch (ClassNotFoundException e) {
38 } catch (UnsupportedLookAndFeelException e) {
39 } catch (IllegalAccessException e) {
40 }
41 }
42
43 /**
44 * Draw a 3D-looking ellipse at the given location, if the given
45 * {@link Graphics} object is compatible (with {@link Graphics2D}); draw a
46 * simple ellipse if not.
47 *
48 * @param g
49 * the {@link Graphics} to draw on
50 * @param color
51 * the base colour
52 * @param x
53 * the X coordinate
54 * @param y
55 * the Y coordinate
56 * @param width
57 * the width radius
58 * @param height
59 * the height radius
60 */
61 static public void drawEllipse3D(Graphics g, Color color, int x, int y,
62 int width, int height) {
63 drawEllipse3D(g, color, x, y, width, height, true);
64 }
65
66 /**
67 * Draw a 3D-looking ellipse at the given location, if the given
68 * {@link Graphics} object is compatible (with {@link Graphics2D}); draw a
69 * simple ellipse if not.
70 *
71 * @param g
72 * the {@link Graphics} to draw on
73 * @param color
74 * the base colour
75 * @param x
76 * the X coordinate
77 * @param y
78 * the Y coordinate
79 * @param width
80 * the width radius
81 * @param height
82 * the height radius
83 * @param fill
84 * fill the content of the ellipse
85 */
86 static public void drawEllipse3D(Graphics g, Color color, int x, int y,
87 int width, int height, boolean fill) {
88 if (g instanceof Graphics2D) {
89 Graphics2D g2 = (Graphics2D) g;
90 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
91 RenderingHints.VALUE_ANTIALIAS_ON);
92
93 // Retains the previous state
94 Paint oldPaint = g2.getPaint();
95
96 // Base shape
97 g2.setColor(color);
98 if (fill) {
99 g2.fillOval(x, y, width, height);
100 } else {
101 g2.drawOval(x, y, width, height);
102 }
103
104 // Compute dark/bright colours
105 Paint p = null;
106 Color dark = color.darker().darker();
107 Color bright = color.brighter().brighter();
108 Color darkEnd = new Color(dark.getRed(), dark.getGreen(),
109 dark.getBlue(), 0);
110 Color darkPartial = new Color(dark.getRed(), dark.getGreen(),
111 dark.getBlue(), 64);
112 Color brightEnd = new Color(bright.getRed(), bright.getGreen(),
113 bright.getBlue(), 0);
114
115 // Adds shadows at the bottom left
116 p = new GradientPaint(0, height, dark, width, 0, darkEnd);
117 g2.setPaint(p);
118 if (fill) {
119 g2.fillOval(x, y, width, height);
120 } else {
121 g2.drawOval(x, y, width, height);
122 }
123 // Adds highlights at the top right
124 p = new GradientPaint(width, 0, bright, 0, height, brightEnd);
125 g2.setPaint(p);
126 if (fill) {
127 g2.fillOval(x, y, width, height);
128 } else {
129 g2.drawOval(x, y, width, height);
130 }
131
132 // Darken the edges
133 p = new RadialGradientPaint(x + width / 2f, y + height / 2f,
134 Math.min(width / 2f, height / 2f), new float[] { 0f, 1f },
135 new Color[] { darkEnd, darkPartial },
136 RadialGradientPaint.CycleMethod.NO_CYCLE);
137 g2.setPaint(p);
138 if (fill) {
139 g2.fillOval(x, y, width, height);
140 } else {
141 g2.drawOval(x, y, width, height);
142 }
143
144 // Adds inner highlight at the top right
145 p = new RadialGradientPaint(x + 3f * width / 4f, y + height / 4f,
146 Math.min(width / 4f, height / 4f),
147 new float[] { 0.0f, 0.8f },
148 new Color[] { bright, brightEnd },
149 RadialGradientPaint.CycleMethod.NO_CYCLE);
150 g2.setPaint(p);
151 if (fill) {
152 g2.fillOval(x * 2, y, width, height);
153 } else {
154 g2.drawOval(x * 2, y, width, height);
155 }
156
157 // Reset original paint
158 g2.setPaint(oldPaint);
159 } else {
160 g.setColor(color);
161 if (fill) {
162 g.fillOval(x, y, width, height);
163 } else {
164 g.drawOval(x, y, width, height);
165 }
166 }
167 }
168
169 /**
170 * Add a {@link JScrollPane} around the given panel and use a sensible (for
171 * me) increment for the mouse wheel.
172 *
173 * @param pane
174 * the panel to wrap in a {@link JScrollPane}
175 * @param allowHorizontal
176 * allow horizontal scrolling (not always desired)
177 *
178 * @return the {@link JScrollPane}
179 */
180 static public JScrollPane scroll(JComponent pane, boolean allowHorizontal) {
181 return scroll(pane, allowHorizontal, true);
182 }
183
184 /**
185 * Add a {@link JScrollPane} around the given panel and use a sensible (for
186 * me) increment for the mouse wheel.
187 *
188 * @param pane
189 * the panel to wrap in a {@link JScrollPane}
190 * @param allowHorizontal
191 * allow horizontal scrolling (not always desired)
192 * @param allowVertical
193 * allow vertical scrolling (usually yes, but sometimes you only
194 * want horizontal)
195 *
196 * @return the {@link JScrollPane}
197 */
198 static public JScrollPane scroll(JComponent pane, boolean allowHorizontal,
199 boolean allowVertical) {
200 JScrollPane scroll = new JScrollPane(pane);
201
202 scroll.getVerticalScrollBar().setUnitIncrement(16);
203 scroll.getHorizontalScrollBar().setUnitIncrement(16);
204
205 if (!allowHorizontal) {
206 scroll.setHorizontalScrollBarPolicy(
207 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
208 }
209 if (!allowVertical) {
210 scroll.setVerticalScrollBarPolicy(
211 JScrollPane.VERTICAL_SCROLLBAR_NEVER);
212 }
213
214 return scroll;
215 }
216 }