Commit | Line | Data |
---|---|---|
86057589 | 1 | package be.nikiroo.utils.ui; |
8caeb8bd | 2 | |
ef13cd7f NR |
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 | ||
a917f100 NR |
11 | import javax.swing.JComponent; |
12 | import javax.swing.JScrollPane; | |
8caeb8bd NR |
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 | } | |
a917f100 | 42 | |
db0af0d9 NR |
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 | */ | |
a917f100 NR |
61 | static public void drawEllipse3D(Graphics g, Color color, int x, int y, |
62 | int width, int height) { | |
db0af0d9 NR |
63 | drawEllipse3D(g, color, x, y, width, height, true); |
64 | } | |
ef13cd7f NR |
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 | |
a917f100 NR |
83 | * @param fill |
84 | * fill the content of the ellipse | |
ef13cd7f NR |
85 | */ |
86 | static public void drawEllipse3D(Graphics g, Color color, int x, int y, | |
db0af0d9 | 87 | int width, int height, boolean fill) { |
ef13cd7f NR |
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); | |
db0af0d9 NR |
98 | if (fill) { |
99 | g2.fillOval(x, y, width, height); | |
100 | } else { | |
101 | g2.drawOval(x, y, width, height); | |
102 | } | |
a917f100 | 103 | |
ef13cd7f NR |
104 | // Compute dark/bright colours |
105 | Paint p = null; | |
db0af0d9 NR |
106 | Color dark = color.darker().darker(); |
107 | Color bright = color.brighter().brighter(); | |
ef13cd7f NR |
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); | |
db0af0d9 NR |
118 | if (fill) { |
119 | g2.fillOval(x, y, width, height); | |
120 | } else { | |
121 | g2.drawOval(x, y, width, height); | |
122 | } | |
ef13cd7f NR |
123 | // Adds highlights at the top right |
124 | p = new GradientPaint(width, 0, bright, 0, height, brightEnd); | |
125 | g2.setPaint(p); | |
db0af0d9 NR |
126 | if (fill) { |
127 | g2.fillOval(x, y, width, height); | |
128 | } else { | |
129 | g2.drawOval(x, y, width, height); | |
130 | } | |
a917f100 | 131 | |
ef13cd7f NR |
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); | |
db0af0d9 NR |
138 | if (fill) { |
139 | g2.fillOval(x, y, width, height); | |
140 | } else { | |
141 | g2.drawOval(x, y, width, height); | |
142 | } | |
ef13cd7f NR |
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); | |
db0af0d9 NR |
151 | if (fill) { |
152 | g2.fillOval(x * 2, y, width, height); | |
153 | } else { | |
154 | g2.drawOval(x * 2, y, width, height); | |
155 | } | |
ef13cd7f NR |
156 | |
157 | // Reset original paint | |
158 | g2.setPaint(oldPaint); | |
159 | } else { | |
160 | g.setColor(color); | |
db0af0d9 NR |
161 | if (fill) { |
162 | g.fillOval(x, y, width, height); | |
163 | } else { | |
164 | g.drawOval(x, y, width, height); | |
165 | } | |
ef13cd7f NR |
166 | } |
167 | } | |
a917f100 NR |
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 | JScrollPane scroll = new JScrollPane(pane); | |
182 | scroll.getVerticalScrollBar().setUnitIncrement(16); | |
183 | if (!allowHorizontal) { | |
184 | scroll.setHorizontalScrollBarPolicy( | |
185 | JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); | |
186 | } | |
187 | return scroll; | |
188 | } | |
8caeb8bd | 189 | } |