1 package org.glassbox;
2
3 import org.glassbox.gui.*;
4 import javax.swing.*;
5 import javax.swing.border.*;
6 import java.awt.*;
7
8 /***
9 Tools & global properties for the glassbox.
10 The properties are read from the file <code>glassbox.properties</code> in the top level
11 directory of the classpath.
12 */
13 public class SwingFactory {
14 /***
15 This class is never instantiated.
16 */
17 private SwingFactory() {
18
19 }
20
21 private static final void applyToChildren(Container parent,
22 Border border,
23 Color background,
24 Color foreground,
25 Font font) {
26 Component[] ch = parent.getComponents();
27 for (int i=0; i<ch.length; i++) {
28 if (ch[i] instanceof JComponent) ((JComponent)ch[i]).setBorder(border);
29 ch[i].setFont(font);
30 ch[i].setBackground(background);
31 ch[i].setForeground(foreground);
32 if (ch[i] instanceof Container) applyToChildren((Container)ch[i],
33 border,
34 background,
35 foreground,
36 font);
37 }
38 }
39
40 public static final String LINK_BUTTON_THEME_PREFIX = "glassbox.LinkButton";
41
42 /***
43 Creates a button looking like a hyperlink with the theme prefix
44 "glassbox.LinkButton".
45 */
46 public static final JButton createLinkButton(Icon icon, String text) {
47 return createLinkButton(icon, text, LINK_BUTTON_THEME_PREFIX);
48 }
49
50 /***
51 Creates a button looking like a hyperlink with the specified
52 theme prefix. The following properties will be used for configuration:
53 <ul>
54 <li>*.active.color</li>
55 <li>*.visited.color</li>
56 <li>*.over.color</li>
57 <li>*.pressed.color</li>
58 <li>*.insets</li>
59 <li>*.font</li>
60 </ul>
61 */
62 public static final JButton createLinkButton(Icon icon, String text, String themepath) {
63 Color active = Theme.getColor(themepath+".active.color");
64 Color visited = Theme.getColor(themepath+".visited.color");
65 Color over = Theme.getColor(themepath+".over.color");
66 Color pressed = Theme.getColor(themepath+".pressed.color");
67 Insets insets = Theme.getInsets(themepath+".insets");
68 Font font = Theme.getFont(themepath+".font");
69 LinkButton button = null;
70 if (active!=null && visited!=null && over!=null && pressed!=null)
71 button = new LinkButton(text, icon, active, visited, over, pressed);
72 else
73 button = new LinkButton(text, icon);
74 button.setFont(font);
75 button.setBorder(new EmptyBorder(insets));
76 return button;
77 }
78
79 /***
80 Creates a slider froma a configuration in the theme.
81 The specified path must be a prefix (*) to a slider configuration.
82 The following properties will be used for configuration:
83 <ul>
84 <li>*.border.color</li>
85 <li>*.background.color</li>
86 <li>*.font</li>
87 <li>*.text.color</li>
88 </ul>
89 */
90 public static final JSlider createSlider(String themepath) {
91 Color bordercolor = Theme.getColor(themepath+".border.color");
92 Color bgcolor = Theme.getColor(themepath+".background.color");
93 Font font = Theme.getFont(themepath+".font");
94 Color txcolor = Theme.getColor(themepath+".text.color");
95 Border border = border = BorderFactory.createLineBorder(bordercolor, 1);
96 JSlider slide = new JSlider();
97 slide.setBackground(bgcolor);
98 slide.setForeground(txcolor);
99 slide.setFont(font);
100 slide.setBorder(border);
101 if (bgcolor.getTransparency()==Transparency.BITMASK ||
102 bgcolor.getTransparency()==Transparency.TRANSLUCENT)
103 slide.setOpaque(false);
104 else
105 slide.setOpaque(true);
106 applyToChildren(slide, border, bgcolor, txcolor, font);
107 return slide;
108 }
109
110 /***
111 Creates a combo box froma a configuration in the theme.
112 The specified path must be a prefix (*) to a combo box configuration.
113 The following properties will be used for configuration:
114 <ul>
115 <li>*.border.color</li>
116 <li>*.background.color</li>
117 <li>*.insets</li>
118 <li>*.font</li>
119 <li>*.text.color</li>
120 </ul>
121 */
122 public static final JComboBox createComboBox(String themepath) {
123 Color bordercolor = Theme.getColor(themepath+".border.color");
124 Color bgcolor = Theme.getColor(themepath+".background.color");
125 Insets insets = Theme.getInsets(themepath+".insets");
126 Font font = Theme.getFont(themepath+".font");
127 Color txcolor = Theme.getColor(themepath+".text.color");
128 Border border = null;
129 if (insets.top>0 && insets.bottom>0 && insets.left>0 && insets.right>0) {
130 border = BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(bordercolor, 1),
131 BorderFactory.createEmptyBorder(insets.top-1,
132 insets.left-1,
133 insets.bottom-1,
134 insets.right-1));
135 }
136 JComboBox box = new JComboBox();
137 box.setBackground(bgcolor);
138 box.setForeground(txcolor);
139 box.setFont(font);
140 box.setBorder(border);
141 if (bgcolor.getTransparency()==Transparency.BITMASK ||
142 bgcolor.getTransparency()==Transparency.TRANSLUCENT)
143 box.setOpaque(false);
144 else
145 box.setOpaque(true);
146 applyToChildren(box, border, bgcolor, txcolor, font);
147 return box;
148 }
149
150 /***
151 Creates a text area from a configuration in the theme.
152 The specified path must be a prefix (*) to a text area configuration.
153 The following properties will be used for configuration:
154 <ul>
155 <li>*.border.color</li>
156 <li>*.background.color</li>
157 <li>*.insets</li>
158 <li>*.font</li>
159 <li>*.text.color</li>
160 <li>*.size</li>
161 </ul>
162 */
163 public static final JTextArea createTextArea(String themepath) {
164 return styleTextArea(new JTextArea(), themepath);
165 }
166
167 /***
168 Create a AutoResetTextArea with the specified theme prefix.
169 The specified path must be a prefix (*) to a text area configuration.
170 The following properties will be used for configuration:
171 <ul>
172 <li>*.border.color</li>
173 <li>*.background.color</li>
174 <li>*.insets</li>
175 <li>*.font</li>
176 <li>*.text.color</li>
177 <li>*.size</li>
178 </ul>
179 */
180 public static final JTextArea createAutoResetTextArea(AutoResetTextArea.TextProvider provider, String themepath) {
181 return styleTextArea(new AutoResetTextArea(provider), themepath);
182 }
183
184 private static final JTextArea styleTextArea(JTextArea area, String themepath) {
185 Color bordercolor = Theme.getColor(themepath+".border.color");
186 Color bgcolor = Theme.getColor(themepath+".background.color");
187 Font font = Theme.getFont(themepath+".font");
188 Insets insets = Theme.getInsets(themepath+".insets");
189 Color txcolor = Theme.getColor(themepath+".text.color");
190 Dimension size = Theme.getSize(themepath+".size");
191 Border border = null;
192 if (insets.top>0 && insets.bottom>0 && insets.left>0 && insets.right>0) {
193 border = BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(bordercolor, 1),
194 BorderFactory.createEmptyBorder(insets.top-1,
195 insets.left-1,
196 insets.bottom-1,
197 insets.right-1));
198 }
199 area.setRows(size.height);
200 area.setColumns(size.width);
201 area.setBackground(bgcolor);
202 area.setForeground(txcolor);
203 area.setFont(font);
204 area.setBorder(border);
205 if (bgcolor.getTransparency()==Transparency.BITMASK ||
206 bgcolor.getTransparency()==Transparency.TRANSLUCENT)
207 area.setOpaque(false);
208 else
209 area.setOpaque(true);
210 return area;
211 }
212
213 /***
214 Creates an AutoResetTextField from a configuration in the theme.
215 The specified path must be a prefix (*) to a text field configuration.
216 The following properties will be used for configuration:
217 <ul>
218 <li>*.border.color</li>
219 <li>*.background.color</li>
220 <li>*.insets</li>
221 <li>*.font</li>
222 <li>*.text.color</li>
223 <li>*.size (only width will be taken into account)</li>
224 </ul>
225 */
226 public static final JTextField createAutoResetTextField(AutoResetTextField.TextProvider provider, String themepath) {
227 return styleTextField(new AutoResetTextField(provider), themepath);
228 }
229
230 /***
231 Creates a text field from a configuration in the theme.
232 The specified path must be a prefix (*) to a text field configuration.
233 The following properties will be used for configuration:
234 <ul>
235 <li>*.border.color</li>
236 <li>*.background.color</li>
237 <li>*.insets</li>
238 <li>*.font</li>
239 <li>*.text.color</li>
240 <li>*.size (only width will be taken into account)</li>
241 </ul>
242 */
243 public static final JTextField createTextField(String themepath) {
244 return styleTextField(new JTextField(), themepath);
245 }
246
247 private static final JTextField styleTextField(JTextField area, String themepath) {
248 Color bordercolor = Theme.getColor(themepath+".border.color");
249 Color bgcolor = Theme.getColor(themepath+".background.color");
250 Font font = Theme.getFont(themepath+".font");
251 Insets insets = Theme.getInsets(themepath+".insets");
252 Color txcolor = Theme.getColor(themepath+".text.color");
253 Dimension size = Theme.getSize(themepath+".size");
254 Border border = null;
255 if (insets.top>0 && insets.bottom>0 && insets.left>0 && insets.right>0) {
256 border = BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(bordercolor, 1),
257 BorderFactory.createEmptyBorder(insets.top-1,
258 insets.left-1,
259 insets.bottom-1,
260 insets.right-1));
261 }
262 area.setColumns(size.width);
263 area.setBackground(bgcolor);
264 area.setForeground(txcolor);
265 area.setFont(font);
266 area.setBorder(border);
267 if (bgcolor.getTransparency()==Transparency.BITMASK ||
268 bgcolor.getTransparency()==Transparency.TRANSLUCENT)
269 area.setOpaque(false);
270 else
271 area.setOpaque(true);
272 return area;
273 }
274
275 /***
276 Create a button from a configuration in the theme.
277 The specified path must be a prefix (*) to a button configuration.
278 The following properties will be used for configuration:
279 <ul>
280 <li>*.border.color</li>
281 <li>*.background.color</li>
282 <li>*.icon</li>
283 <li>*.insets</li>
284 <li>*.label</li>
285 <li>*.font</li>
286 <li>*.text.color</li>
287 </ul>
288 */
289 public static final JButton createButton(String themepath) {
290 return createButton(themepath, Theme.getIcon(themepath+".icon"));
291 }
292
293 /***
294 Create a button from a configuration in the theme.
295 The specified path must be a prefix (*) to a button configuration.
296 The following properties will be used for configuration:
297 <ul>
298 <li>*.border.color</li>
299 <li>*.background.color</li>
300 <li>*.icon</li>
301 <li>*.insets</li>
302 <li>*.font</li>
303 <li>*.text.color</li>
304 </ul>
305 */
306 public static final JButton createButton(String themepath, String text) {
307 return createButton(themepath, text, Theme.getIcon(themepath+".icon"));
308 }
309
310 /***
311 Create a button from a configuration in the theme.
312 The specified path must be a prefix (*) to a button configuration.
313 The following properties will be used for configuration:
314 <ul>
315 <li>*.border.color</li>
316 <li>*.background.color</li>
317 <li>*.insets</li>
318 <li>*.label</li>
319 <li>*.font</li>
320 <li>*.text.color</li>
321 </ul>
322 */
323 public static final JButton createButton(String themepath, Icon icon) {
324 return createButton(themepath, Theme.getText(themepath+".label"), icon);
325 }
326
327 /***
328 Create a button from a configuration in the theme using the specified icon.
329 The specified path must be a prefix (*) to button configuration.
330 The following properties will be used for configuration:
331 <ul>
332 <li>*.border.color</li>
333 <li>*.background.color</li>
334 <li>*.insets</li>
335 <li>*.font</li>
336 <li>*.text.color</li>
337 </ul>
338 */
339 public static final JButton createButton(String themepath, String text, Icon icon) {
340 return createButton(themepath, text, icon, false);
341 }
342
343 /***
344 Create a button from a configuration in the theme using the specified icon.
345 The specified path must be a prefix (*) to button configuration.
346 The following properties will be used for configuration:
347 <ul>
348 <li>*.border.color</li>
349 <li>*.background.color</li>
350 <li>*.insets</li>
351 <li>*.font</li>
352 <li>*.text.color</li>
353 </ul>
354 */
355 public static final JButton createButton(String themepath, String text, Icon icon, boolean paintfocus) {
356 Color bordercolor = Theme.getColor(themepath+".border.color");
357 Color bgcolor = Theme.getColor(themepath+".background.color");
358 Insets insets = Theme.getInsets(themepath+".insets");
359 Font font = Theme.getFont(themepath+".font");
360 Color txcolor = Theme.getColor(themepath+".text.color");
361 String tx = Theme.getText(themepath+".text");
362 Border border = null;
363 if (insets.top>0 && insets.bottom>0 && insets.left>0 && insets.right>0) {
364 border = BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(bordercolor, 1),
365 BorderFactory.createEmptyBorder(insets.top-1,
366 insets.left-1,
367 insets.bottom-1,
368 insets.right-1));
369 }
370 JButton button = null;
371 if (icon!=null) button = new JButton(tx, icon);
372 else button = new JButton(tx);
373 button.setBackground(bgcolor);
374 button.setForeground(txcolor);
375 button.setFont(font);
376 button.setBorder(border);
377 if (bgcolor.getTransparency()==Transparency.BITMASK ||
378 bgcolor.getTransparency()==Transparency.TRANSLUCENT)
379 button.setOpaque(false);
380 else
381 button.setOpaque(true);
382 button.setFocusPainted(paintfocus);
383 return button;
384 }
385
386 /***
387 Create a panel from a configuration in the theme.
388 The specified path must be a prefix (*) to a panel configuration.
389 The following properties will be used for configuration:
390 <ul>
391 <li>*.border.color</li>
392 <li>*.background.color</li>
393 <li>*.insets</li>
394 */
395 public static final JPanel createPanel(String themepath) {
396 Color bordercolor = Theme.getColor(themepath+".border.color");
397 Color bgcolor = Theme.getColor(themepath+".background.color");
398 Insets insets = Theme.getInsets(themepath+".insets");
399 Border border = null;
400 if (insets.top>0 && insets.bottom>0 && insets.left>0 && insets.right>0) {
401 border = BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(bordercolor, 1),
402 BorderFactory.createEmptyBorder(insets.top-1,
403 insets.left-1,
404 insets.bottom-1,
405 insets.right-1));
406 }
407 JPanel panel = null;
408 if (bgcolor.getAlpha()==0 && bordercolor.getAlpha()==0)
409 panel = new TransparentPanel();
410 else
411 panel = new JPanel();
412 panel.setBorder(border);
413 panel.setBackground(bgcolor);
414 if (bgcolor.getTransparency()==Transparency.BITMASK ||
415 bgcolor.getTransparency()==Transparency.TRANSLUCENT)
416 panel.setOpaque(false);
417 else
418 panel.setOpaque(true);
419 return panel;
420 }
421
422 /***
423 Create a label from a configuration in the theme.
424 The specified path must be a prefix (*) to a label configuration.
425 The following properties will be used for configuration:
426 <ul>
427 <li>*.background.color</li>
428 <li>*.text.color</li>
429 <li>*.font</li>
430 <li>*.insets</li>
431 */
432 public static final JLabel createLabel(String text, String themepath) {
433 JLabel label = createLabel(themepath);
434 label.setText(text);
435 return label;
436 }
437
438 /***
439 Create a label from a configuration in the theme.
440 The specified path must be a prefix (*) to a label configuration.
441 The following properties will be used for configuration:
442 <ul>
443 <li>*.background.color</li>
444 <li>*.text.color</li>
445 <li>*.font</li>
446 <li>*.insets</li>
447 */
448 public static final JLabel createLabel(String themepath) {
449 Color bgcolor = Theme.getColor(themepath+".background.color");
450 Color txcolor = Theme.getColor(themepath+".text.color");
451 Font font = Theme.getFont(themepath+".font");
452 Insets insets = Theme.getInsets(themepath+".insets");
453 Border border = BorderFactory.createEmptyBorder(insets.top,
454 insets.left,
455 insets.bottom,
456 insets.right);
457 JLabel label = new JLabel();
458 label.setForeground(txcolor);
459 label.setFont(font);
460 label.setBorder(border);
461 label.setBackground(bgcolor);
462 if (bgcolor.getTransparency()==Transparency.BITMASK ||
463 bgcolor.getTransparency()==Transparency.TRANSLUCENT)
464 label.setOpaque(false);
465 else
466 label.setOpaque(true);
467 return label;
468 }
469
470 protected static class TransparentPanel extends JPanel {
471 public TransparentPanel() {
472 super();
473 }
474
475 public void paintComponent(Graphics g) {
476 return;
477 }
478
479 public void paintBorder(Graphics g) {
480 return;
481 }
482 }
483 }