001 /* MetalIconFactory.java --
002 Copyright (C) 2005, 2006, Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038
039 package javax.swing.plaf.metal;
040
041 import java.awt.Color;
042 import java.awt.Component;
043 import java.awt.Graphics;
044 import java.io.Serializable;
045
046 import javax.swing.AbstractButton;
047 import javax.swing.Icon;
048 import javax.swing.JCheckBox;
049 import javax.swing.JCheckBoxMenuItem;
050 import javax.swing.JFileChooser;
051 import javax.swing.JInternalFrame;
052 import javax.swing.JRadioButton;
053 import javax.swing.JRadioButtonMenuItem;
054 import javax.swing.JSlider;
055 import javax.swing.SwingConstants;
056 import javax.swing.UIManager;
057 import javax.swing.plaf.UIResource;
058
059
060 /**
061 * Creates icons for the {@link MetalLookAndFeel}.
062 */
063 public class MetalIconFactory implements Serializable
064 {
065
066 /** A constant representing "dark". */
067 public static final boolean DARK = false;
068
069 /** A constant representing "light". */
070 public static final boolean LIGHT = true;
071
072 /** A shared instance of the MenuArrowIcon. */
073 private static Icon menuArrow;
074
075 /** A shared instance of the MenuItemArrowIcon. */
076 private static Icon menuItemArrow;
077
078 /**
079 * An icon displayed for {@link JCheckBoxMenuItem} components.
080 */
081 private static class CheckBoxMenuItemIcon
082 implements Icon, UIResource, Serializable
083 {
084 /**
085 * Creates a new icon instance.
086 */
087 public CheckBoxMenuItemIcon()
088 {
089 // Nothing to do here.
090 }
091
092 /**
093 * Returns the width of the icon, in pixels.
094 *
095 * @return The width of the icon (10 pixels).
096 */
097 public int getIconWidth()
098 {
099 return 10;
100 }
101
102 /**
103 * Returns the height of the icon, in pixels.
104 *
105 * @return The height of the icon (10 pixels).
106 */
107 public int getIconHeight()
108 {
109 return 10;
110 }
111
112 /**
113 * Paints the icon.
114 *
115 * @param c the component.
116 * @param g the graphics device.
117 * @param x the x-coordinate.
118 * @param y the y-coordinate.
119 */
120 public void paintIcon(Component c, Graphics g, int x, int y)
121 {
122 JCheckBoxMenuItem item = (JCheckBoxMenuItem) c;
123
124 if (item.isArmed())
125 g.setColor(MetalLookAndFeel.getBlack());
126 else
127 g.setColor(MetalLookAndFeel.getControlDarkShadow());
128 g.drawLine(x, y, x + 8, y);
129 g.drawLine(x, y + 1, x, y + 8);
130 g.drawLine(x + 2, y + 8, x + 8, y + 8);
131 g.drawLine(x + 8, y + 2, x + 8, y + 7);
132
133 g.setColor(MetalLookAndFeel.getWhite());
134 g.drawLine(x + 1, y + 1, x + 7, y + 1);
135 g.drawLine(x + 1, y + 2, x + 1, y + 7);
136 g.drawLine(x + 1, y + 9, x + 9, y + 9);
137 g.drawLine(x + 9, y + 1, x + 9, y + 8);
138
139 // if the item is selected, we should draw a tick
140 if (item.isSelected())
141 {
142 g.setColor(MetalLookAndFeel.getBlack());
143 g.fillRect(x + 2, y + 2, 2, 5);
144 for (int i = 0; i < 6; i++)
145 g.drawLine(x + 8 - i, y + i, x + 9 - i, y + i);
146 }
147
148 }
149 }
150
151 /**
152 * An icon used for the "detail view" button on a {@link JFileChooser} under
153 * the {@link MetalLookAndFeel}.
154 *
155 * @see MetalIconFactory#getFileChooserDetailViewIcon()
156 */
157 private static class FileChooserDetailViewIcon
158 implements Icon, UIResource, Serializable
159 {
160
161 /**
162 * Creates a new icon.
163 */
164 public FileChooserDetailViewIcon()
165 {
166 // Nothing to do here.
167 }
168
169 /**
170 * Returns the width of the icon, in pixels.
171 *
172 * @return The width of the icon.
173 */
174 public int getIconWidth()
175 {
176 return 18;
177 }
178
179 /**
180 * Returns the height of the icon, in pixels.
181 *
182 * @return The height of the icon.
183 */
184 public int getIconHeight()
185 {
186 return 18;
187 }
188
189 /**
190 * Paints the icon using colors from the {@link MetalLookAndFeel}.
191 *
192 * @param c the component (ignored).
193 * @param g the graphics device.
194 * @param x the x-coordinate for the top-left of the icon.
195 * @param y the y-coordinate for the top-left of the icon.
196 */
197 public void paintIcon(Component c, Graphics g, int x, int y)
198 {
199 Color savedColor = g.getColor();
200 g.setColor(MetalLookAndFeel.getBlack());
201
202 // file 1 outline
203 g.drawLine(x + 2, y + 2, x + 5, y + 2);
204 g.drawLine(x + 6, y + 3, x + 6, y + 7);
205 g.drawLine(x + 2, y + 7, x + 6, y + 7);
206 g.drawLine(x + 2, y + 2, x + 2, y + 7);
207
208 // file 2 outline
209 g.drawLine(x + 2, y + 10, x + 5, y + 10);
210 g.drawLine(x + 6, y + 11, x + 6, y + 15);
211 g.drawLine(x + 2, y + 15, x + 6, y + 15);
212 g.drawLine(x + 2, y + 10, x + 2, y + 15);
213
214 // detail lines
215 g.drawLine(x + 8, y + 5, x + 15, y + 5);
216 g.drawLine(x + 8, y + 13, x + 15, y + 13);
217
218 // fill files
219 g.setColor(MetalLookAndFeel.getPrimaryControl());
220 g.fillRect(x + 3, y + 3, 3, 4);
221 g.fillRect(x + 3, y + 11, 3, 4);
222
223 // highlight files
224 g.setColor(MetalLookAndFeel.getPrimaryControlHighlight());
225 g.drawLine(x + 4, y + 4, x + 4, y + 5);
226 g.drawLine(x + 4, y + 12, x + 4, y + 13);
227
228 g.setColor(savedColor);
229 }
230 }
231
232 /**
233 * An icon used for the "home folder" button on a {@link JFileChooser} under
234 * the {@link MetalLookAndFeel}.
235 *
236 * @see MetalIconFactory#getFileChooserHomeFolderIcon()
237 */
238 private static class FileChooserHomeFolderIcon
239 implements Icon, UIResource, Serializable
240 {
241
242 /**
243 * Creates a new icon.
244 */
245 public FileChooserHomeFolderIcon()
246 {
247 // Nothing to do here.
248 }
249
250 /**
251 * Returns the width of the icon, in pixels.
252 *
253 * @return The width of the icon.
254 */
255 public int getIconWidth()
256 {
257 return 18;
258 }
259
260 /**
261 * Returns the height of the icon, in pixels.
262 *
263 * @return The height of the icon.
264 */
265 public int getIconHeight()
266 {
267 return 18;
268 }
269
270 /**
271 * Paints the icon using colors from the {@link MetalLookAndFeel}.
272 *
273 * @param c the component (ignored).
274 * @param g the graphics device.
275 * @param x the x-coordinate for the top-left of the icon.
276 * @param y the y-coordinate for the top-left of the icon.
277 */
278 public void paintIcon(Component c, Graphics g, int x, int y)
279 {
280 Color savedColor = g.getColor();
281 g.setColor(MetalLookAndFeel.getBlack());
282
283 // roof
284 g.drawLine(x + 1, y + 8, x + 8, y + 1);
285 g.drawLine(x + 8, y + 1, x + 15, y + 8);
286
287 // base of house
288 g.drawLine(x + 3, y + 6, x + 3, y + 15);
289 g.drawLine(x + 3, y + 15, x + 13, y + 15);
290 g.drawLine(x + 13, y + 6, x + 13, y + 15);
291
292 // door frame
293 g.drawLine(x + 6, y + 9, x + 6, y + 15);
294 g.drawLine(x + 6, y + 9, x + 10, y + 9);
295 g.drawLine(x + 10, y + 9, x + 10, y + 15);
296
297 // chimney
298 g.drawLine(x + 11, y + 2, x + 11, y + 4);
299 g.drawLine(x + 12, y + 2, x + 12, y + 5);
300
301 g.setColor(MetalLookAndFeel.getControlDarkShadow());
302
303 // roof paint
304 int xx = x + 8;
305 for (int i = 0; i < 4; i++)
306 g.drawLine(xx - i, y + 2 + i, xx + i, y + 2 + i);
307 g.fillRect(x + 4, y + 6, 9, 2);
308
309 // door knob
310 g.drawLine(x + 9, y + 12, x + 9, y + 12);
311
312 // house paint
313 g.setColor(MetalLookAndFeel.getPrimaryControl());
314 g.drawLine(x + 4, y + 8, x + 12, y + 8);
315 g.fillRect(x + 4, y + 9, 2, 6);
316 g.fillRect(x + 11, y + 9, 2, 6);
317
318 g.setColor(savedColor);
319 }
320 }
321
322 /**
323 * An icon used for the "list view" button on a {@link JFileChooser} under
324 * the {@link MetalLookAndFeel}.
325 *
326 * @see MetalIconFactory#getFileChooserListViewIcon()
327 */
328 private static class FileChooserListViewIcon
329 implements Icon, UIResource, Serializable
330 {
331 /**
332 * Creates a new icon.
333 */
334 public FileChooserListViewIcon()
335 {
336 // Nothing to do here.
337 }
338
339 /**
340 * Returns the width of the icon, in pixels.
341 *
342 * @return The width of the icon.
343 */
344 public int getIconWidth()
345 {
346 return 18;
347 }
348
349 /**
350 * Returns the height of the icon, in pixels.
351 *
352 * @return The height of the icon.
353 */
354 public int getIconHeight()
355 {
356 return 18;
357 }
358
359 /**
360 * Paints the icon using colors from the {@link MetalLookAndFeel}.
361 *
362 * @param c the component (ignored).
363 * @param g the graphics device.
364 * @param x the x-coordinate for the top-left of the icon.
365 * @param y the y-coordinate for the top-left of the icon.
366 */
367 public void paintIcon(Component c, Graphics g, int x, int y)
368 {
369 Color savedColor = g.getColor();
370 g.setColor(MetalLookAndFeel.getBlack());
371
372 // file 1 outline
373 g.drawLine(x + 2, y + 2, x + 5, y + 2);
374 g.drawLine(x + 6, y + 3, x + 6, y + 7);
375 g.drawLine(x + 2, y + 7, x + 6, y + 7);
376 g.drawLine(x + 2, y + 2, x + 2, y + 7);
377
378 // file 2 outline
379 g.drawLine(x + 2, y + 10, x + 5, y + 10);
380 g.drawLine(x + 6, y + 11, x + 6, y + 15);
381 g.drawLine(x + 2, y + 15, x + 6, y + 15);
382 g.drawLine(x + 2, y + 10, x + 2, y + 15);
383
384 // file 3 outline
385 g.drawLine(x + 10, y + 2, x + 13, y + 2);
386 g.drawLine(x + 14, y + 3, x + 14, y + 7);
387 g.drawLine(x + 10, y + 7, x + 14, y + 7);
388 g.drawLine(x + 10, y + 2, x + 10, y + 7);
389
390 // file 4 outline
391 g.drawLine(x + 10, y + 10, x + 13, y + 10);
392 g.drawLine(x + 14, y + 11, x + 14, y + 15);
393 g.drawLine(x + 10, y + 15, x + 14, y + 15);
394 g.drawLine(x + 10, y + 10, x + 10, y + 15);
395
396 g.drawLine(x + 8, y + 5, x + 8, y + 5);
397 g.drawLine(x + 8, y + 13, x + 8, y + 13);
398 g.drawLine(x + 16, y + 5, x + 16, y + 5);
399 g.drawLine(x + 16, y + 13, x + 16, y + 13);
400
401 // fill files
402 g.setColor(MetalLookAndFeel.getPrimaryControl());
403 g.fillRect(x + 3, y + 3, 3, 4);
404 g.fillRect(x + 3, y + 11, 3, 4);
405 g.fillRect(x + 11, y + 3, 3, 4);
406 g.fillRect(x + 11, y + 11, 3, 4);
407
408 // highlight files
409 g.setColor(MetalLookAndFeel.getPrimaryControlHighlight());
410 g.drawLine(x + 4, y + 4, x + 4, y + 5);
411 g.drawLine(x + 4, y + 12, x + 4, y + 13);
412 g.drawLine(x + 12, y + 4, x + 12, y + 5);
413 g.drawLine(x + 12, y + 12, x + 12, y + 13);
414
415 g.setColor(savedColor);
416 }
417 }
418
419 /**
420 * An icon used for the "new folder" button on a {@link JFileChooser} under
421 * the {@link MetalLookAndFeel}.
422 *
423 * @see MetalIconFactory#getFileChooserNewFolderIcon()
424 */
425 private static class FileChooserNewFolderIcon
426 implements Icon, UIResource, Serializable
427 {
428 /**
429 * Creates a new icon.
430 */
431 public FileChooserNewFolderIcon()
432 {
433 // Nothing to do here.
434 }
435
436 /**
437 * Returns the width of the icon, in pixels.
438 *
439 * @return The width of the icon.
440 */
441 public int getIconWidth()
442 {
443 return 18;
444 }
445
446 /**
447 * Returns the height of the icon, in pixels.
448 *
449 * @return The height of the icon.
450 */
451 public int getIconHeight()
452 {
453 return 18;
454 }
455
456 /**
457 * Paints the icon using colors from the {@link MetalLookAndFeel}.
458 *
459 * @param c the component (ignored).
460 * @param g the graphics device.
461 * @param x the x-coordinate for the top-left of the icon.
462 * @param y the y-coordinate for the top-left of the icon.
463 */
464 public void paintIcon(Component c, Graphics g, int x, int y)
465 {
466 Color savedColor = g.getColor();
467 g.setColor(MetalLookAndFeel.getBlack());
468
469 g.drawLine(x + 2, y + 5, x + 9, y + 5);
470 g.drawLine(x + 10, y + 6, x + 15, y + 6);
471 g.drawLine(x + 15, y + 5, x + 15, y + 14);
472 g.drawLine(x + 2, y + 14, x + 15, y + 14);
473 g.drawLine(x + 1, y + 6, x + 1, y + 14);
474
475 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
476 g.drawLine(x + 11, y + 3, x + 15, y + 3);
477 g.drawLine(x + 10, y + 4, x + 15, y + 4);
478
479 g.setColor(MetalLookAndFeel.getPrimaryControl());
480 g.fillRect(x + 3, y + 7, 7, 7);
481 g.fillRect(x + 10, y + 8, 5, 6);
482 g.drawLine(x + 10, y + 5, x + 14, y + 5);
483
484 g.setColor(MetalLookAndFeel.getPrimaryControlHighlight());
485 g.drawLine(x + 10, y + 7, x + 14, y + 7);
486 g.drawLine(x + 2, y + 6, x + 9, y + 6);
487 g.drawLine(x + 2, y + 6, x + 2, y + 13);
488 g.setColor(savedColor);
489 }
490 }
491
492 /**
493 * An icon used for the "up folder" button on a {@link JFileChooser} under
494 * the {@link MetalLookAndFeel}.
495 *
496 * @see MetalIconFactory#getFileChooserNewFolderIcon()
497 */
498 private static class FileChooserUpFolderIcon extends FileChooserNewFolderIcon
499 {
500 /**
501 * Creates a new icon.
502 */
503 public FileChooserUpFolderIcon()
504 {
505 // Nothing to do here.
506 }
507
508 /**
509 * Paints the icon using colors from the {@link MetalLookAndFeel}.
510 *
511 * @param c the component (ignored).
512 * @param g the graphics device.
513 * @param x the x-coordinate for the top-left of the icon.
514 * @param y the y-coordinate for the top-left of the icon.
515 */
516 public void paintIcon(Component c, Graphics g, int x, int y)
517 {
518 Color savedColor = g.getColor();
519
520 // draw the folder
521 super.paintIcon(c, g, x, y);
522
523 // now draw the up arrow
524 g.setColor(MetalLookAndFeel.getBlack());
525 g.drawLine(x + 8, y + 9, x + 8, y + 16);
526 int xx = x + 8;
527 for (int i = 0; i < 4; i++)
528 g.drawLine(xx - i, y + 9 + i, xx + i, y + 9 + i);
529 g.setColor(savedColor);
530 }
531 }
532
533 /**
534 * An icon representing a file (drawn as a piece of paper with the top-right
535 * corner turned down).
536 */
537 public static class FileIcon16 implements Icon, Serializable
538 {
539 /**
540 * Returns the width of the icon, in pixels.
541 *
542 * @return The width of the icon.
543 */
544 public int getIconWidth()
545 {
546 return 16;
547 }
548
549 /**
550 * Returns the height of the icon, in pixels. The height returned is
551 * <code>16</code> plus the value returned by
552 * {@link #getAdditionalHeight()}.
553 *
554 * @return The height of the icon.
555 */
556 public int getIconHeight()
557 {
558 return 16 + getAdditionalHeight();
559 }
560
561 /**
562 * Paints the icon at the location (x, y).
563 *
564 * @param c the component.
565 * @param g the graphics context.
566 * @param x the x coordinate.
567 * @param y the y coordinate.
568 */
569 public void paintIcon(Component c, Graphics g, int x, int y)
570 {
571 y = y + getShift();
572 g.setColor(MetalLookAndFeel.getBlack());
573 g.drawLine(x, y, x + 9, y);
574 g.drawLine(x, y + 1, x, y + 15);
575 g.drawLine(x, y + 15, x + 12, y + 15);
576 g.drawLine(x + 12, y + 15, x + 12, y + 6);
577 g.drawLine(x + 12, y + 6, x + 9, y);
578
579 g.drawLine(x + 7, y + 2, x + 11, y + 6);
580 g.drawLine(x + 8, y + 1, x + 9, y + 1);
581
582 g.setColor(MetalLookAndFeel.getPrimaryControl());
583 g.drawLine(x + 1, y + 1, x + 7, y + 1);
584 g.drawLine(x + 1, y + 1, x + 1, y + 14);
585 g.drawLine(x + 1, y + 14, x + 11, y + 14);
586 g.drawLine(x + 11, y + 14, x + 11, y + 7);
587 g.drawLine(x + 8, y + 2, x + 10, y + 4);
588 }
589
590 /**
591 * Returns the additional height for the icon. The
592 * {@link #getIconHeight()} method adds this value to the icon height it
593 * returns. Subclasses can override this method to adjust the icon height.
594 *
595 * @return The additional height (<code>0</code> unless overridden).
596 */
597 public int getAdditionalHeight()
598 {
599 return 0;
600 }
601
602 /**
603 * Returns the vertical shift, in pixels, applied when painting the icon.
604 * The default value is zero, but subclasses may override this (for
605 * example, see {@link TreeLeafIcon}).
606 *
607 * @return The shift.
608 */
609 public int getShift()
610 {
611 return 0;
612 }
613
614 }
615
616 /**
617 * An icon representing a folder.
618 */
619 public static class FolderIcon16 implements Icon, Serializable
620 {
621 /**
622 * Returns the width of the icon, in pixels.
623 *
624 * @return The width of the icon.
625 */
626 public int getIconWidth()
627 {
628 return 16;
629 }
630
631 /**
632 * Returns the height of the icon, in pixels. The height returned is
633 * <code>16</code> plus the value returned by
634 * {@link #getAdditionalHeight()}.
635 *
636 * @return The height of the icon.
637 */
638 public int getIconHeight()
639 {
640 return 16 + getAdditionalHeight();
641 }
642
643 /**
644 * Paints the icon at the location (x, y).
645 *
646 * @param c the component.
647 * @param g the graphics device.
648 * @param x the x coordinate.
649 * @param y the y coordinate.
650 */
651 public void paintIcon(Component c, Graphics g, int x, int y)
652 {
653 y = y + getShift();
654 g.setColor(MetalLookAndFeel.getBlack());
655 g.drawLine(x, y + 6, x, y + 15);
656 g.drawLine(x, y + 15, x + 15, y + 15);
657 g.drawLine(x + 15, y + 15, x + 15, y + 5);
658 g.drawLine(x + 14, y + 6, x + 9, y + 6);
659 g.drawLine(x + 8, y + 5, x + 1, y + 5);
660 g.setColor(MetalLookAndFeel.getPrimaryControl());
661 g.fillRect(x + 2, y + 7, 7, 8);
662 g.fillRect(x + 9, y + 8, 6, 7);
663 g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
664 g.drawLine(x + 9, y + 5, x + 14, y + 5);
665 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
666 g.drawLine(x + 9, y + 4, x + 15, y + 4);
667 g.drawLine(x + 10, y + 3, x + 15, y + 3);
668 }
669
670 /**
671 * Returns the additional height for the icon. The
672 * {@link #getIconHeight()} method adds this value to the icon height it
673 * returns. Subclasses can override this method to adjust the icon height.
674 *
675 * @return The additional height (<code>0</code> unless overridden).
676 */
677 public int getAdditionalHeight()
678 {
679 return 0;
680 }
681
682 /**
683 * Returns the vertical shift, in pixels, applied when painting the icon.
684 * The default value is zero, but subclasses may override this (for
685 * example, see {@link TreeFolderIcon}).
686 *
687 * @return The shift.
688 */
689 public int getShift()
690 {
691 return 0;
692 }
693
694 }
695
696 /**
697 * An icon used by the {@link MetalInternalFrameUI} class when the frame
698 * is displayed as a palette.
699 *
700 * @since 1.3
701 */
702 public static class PaletteCloseIcon
703 implements Icon, Serializable, UIResource
704 {
705 /**
706 * Returns the width of the icon, in pixels.
707 *
708 * @return The width of the icon.
709 */
710 public int getIconWidth()
711 {
712 return 7;
713 }
714
715 /**
716 * Returns the height of the icon, in pixels.
717 *
718 * @return The height of the icon.
719 */
720 public int getIconHeight()
721 {
722 return 7;
723 }
724
725 /**
726 * Paints the icon using colors from the {@link MetalLookAndFeel}.
727 *
728 * @param c the component (ignored).
729 * @param g the graphics device.
730 * @param x the x-coordinate for the top-left of the icon.
731 * @param y the y-coordinate for the top-left of the icon.
732 */
733 public void paintIcon(Component c, Graphics g, int x, int y)
734 {
735 Color savedColor = g.getColor();
736 AbstractButton button = (AbstractButton) c;
737 if (button.getModel().isPressed())
738 g.setColor(MetalLookAndFeel.getBlack());
739 else
740 g.setColor(MetalLookAndFeel.getControlDarkShadow());
741 g.fillRect(x + 2, y + 2, 3, 3);
742 g.drawLine(x + 1, y, x + 1, y + 2);
743 g.drawLine(x, y + 1, x + 2, y + 1);
744 g.drawLine(x + 5, y, x + 5, y + 2);
745 g.drawLine(x + 4, y + 1, x + 6, y + 1);
746 g.drawLine(x + 1, y + 4, x + 1, y + 6);
747 g.drawLine(x, y + 5, x + 2, y + 5);
748 g.drawLine(x + 5, y + 4, x + 5, y + 6);
749 g.drawLine(x + 4, y + 5, x + 6, y + 5);
750 g.setColor(MetalLookAndFeel.getControlHighlight());
751 g.drawLine(x + 2, y + 6, x + 3, y + 5);
752 g.drawLine(x + 5, y + 3, x + 6, y + 2);
753 g.drawLine(x + 6, y + 6, x + 6, y + 6);
754 g.setColor(savedColor);
755 }
756 }
757
758 /**
759 * An {@link Icon} implementation for {@link JCheckBox}es in the
760 * Metal Look & Feel.
761 *
762 * @author Roman Kennke (roman@kennke.org)
763 */
764 static class RadioButtonIcon implements Icon, UIResource, Serializable
765 {
766
767 /**
768 * This is used as a mask when painting the gradient. See
769 * {@link MetalUtils#paintGradient(java.awt.Graphics, int, int, int, int,
770 * float, float, java.awt.Color, java.awt.Color, java.awt.Color, int,
771 * int[][])} for details.
772 */
773 private static int[][] gradientMask = new int[][] {{3, 7}, {1, 9}, {1, 9},
774 {0, 10}, {0, 10}, {0, 10},
775 {0, 10}, {1, 9}, {1, 9},
776 {3, 7}};
777
778 /**
779 * Returns the width of the icon in pixels.
780 *
781 * @return the width of the icon in pixels
782 */
783 public int getIconWidth()
784 {
785 return 13;
786 }
787
788 /**
789 * Returns the height of the icon in pixels.
790 *
791 * @return the height of the icon in pixels
792 */
793 public int getIconHeight()
794 {
795 return 13;
796 }
797
798 /**
799 * Paints the icon, taking into account whether or not the component is
800 * enabled, selected and/or armed.
801 *
802 * @param c the Component to draw on (must be an instance of
803 * {@link JRadioButton})
804 * @param g the Graphics context to draw with
805 * @param x the X position
806 * @param y the Y position
807 */
808 public void paintIcon(Component c, Graphics g, int x, int y)
809 {
810 if (UIManager.get("RadioButton.gradient") != null)
811 MetalUtils.paintGradient(g, x + 2, y + 2, 8, 8,
812 SwingConstants.VERTICAL, "RadioButton.gradient",
813 gradientMask);
814
815 Color savedColor = g.getColor();
816 JRadioButton b = (JRadioButton) c;
817
818 // draw outer circle
819 if (b.isEnabled())
820 g.setColor(MetalLookAndFeel.getControlDarkShadow());
821 else
822 g.setColor(MetalLookAndFeel.getControlDisabled());
823 g.drawLine(x + 2, y + 1, x + 3, y + 1);
824 g.drawLine(x + 4, y, x + 7, y);
825 g.drawLine(x + 8, y + 1, x + 9, y + 1);
826 g.drawLine(x + 10, y + 2, x + 10, y + 3);
827 g.drawLine(x + 11, y + 4, x + 11, y + 7);
828 g.drawLine(x + 10, y + 8, x + 10, y + 9);
829 g.drawLine(x + 8, y + 10, x + 9, y + 10);
830 g.drawLine(x + 4, y + 11, x + 7, y + 11);
831 g.drawLine(x + 2, y + 10, x + 3, y + 10);
832 g.drawLine(x + 1, y + 9, x + 1, y + 8);
833 g.drawLine(x, y + 7, x, y + 4);
834 g.drawLine(x + 1, y + 2, x + 1, y + 3);
835
836 if (b.getModel().isArmed())
837 {
838 g.setColor(MetalLookAndFeel.getControlShadow());
839 g.drawLine(x + 4, y + 1, x + 7, y + 1);
840 g.drawLine(x + 4, y + 10, x + 7, y + 10);
841 g.drawLine(x + 1, y + 4, x + 1, y + 7);
842 g.drawLine(x + 10, y + 4, x + 10, y + 7);
843 g.fillRect(x + 2, y + 2, 8, 8);
844 }
845 else
846 {
847 // only draw inner highlight if not filled
848 if (b.isEnabled())
849 {
850 g.setColor(MetalLookAndFeel.getWhite());
851
852 g.drawLine(x + 2, y + 8, x + 2, y + 9);
853 g.drawLine(x + 1, y + 4, x + 1, y + 7);
854 g.drawLine(x + 2, y + 2, x + 2, y + 3);
855 g.drawLine(x + 3, y + 2, x + 3, y + 2);
856 g.drawLine(x + 4, y + 1, x + 7, y + 1);
857 g.drawLine(x + 8, y + 2, x + 9, y + 2);
858 }
859 }
860
861 // draw outer highlight
862 if (b.isEnabled())
863 {
864 g.setColor(MetalLookAndFeel.getWhite());
865
866 // outer
867 g.drawLine(x + 10, y + 1, x + 10, y + 1);
868 g.drawLine(x + 11, y + 2, x + 11, y + 3);
869 g.drawLine(x + 12, y + 4, x + 12, y + 7);
870 g.drawLine(x + 11, y + 8, x + 11, y + 9);
871 g.drawLine(x + 10, y + 10, x + 10, y + 10);
872 g.drawLine(x + 8, y + 11, x + 9, y + 11);
873 g.drawLine(x + 4, y + 12, x + 7, y + 12);
874 g.drawLine(x + 2, y + 11, x + 3, y + 11);
875 }
876
877 if (b.isSelected())
878 {
879 if (b.isEnabled())
880 g.setColor(MetalLookAndFeel.getBlack());
881 else
882 g.setColor(MetalLookAndFeel.getControlDisabled());
883 g.drawLine(x + 4, y + 3, x + 7, y + 3);
884 g.fillRect(x + 3, y + 4, 6, 4);
885 g.drawLine(x + 4, y + 8, x + 7, y + 8);
886 }
887 g.setColor(savedColor);
888 }
889 }
890
891 /**
892 * An icon displayed for {@link JRadioButtonMenuItem} components.
893 */
894 private static class RadioButtonMenuItemIcon
895 implements Icon, UIResource, Serializable
896 {
897 /**
898 * Creates a new icon instance.
899 */
900 public RadioButtonMenuItemIcon()
901 {
902 // Nothing to do here.
903 }
904
905 /**
906 * Returns the width of the icon, in pixels.
907 *
908 * @return The width of the icon.
909 */
910 public int getIconWidth()
911 {
912 return 10;
913 }
914
915 /**
916 * Returns the height of the icon, in pixels.
917 *
918 * @return The height of the icon.
919 */
920 public int getIconHeight()
921 {
922 return 10;
923 }
924
925 /**
926 * Paints the icon.
927 *
928 * @param c the component.
929 * @param g the graphics device.
930 * @param x the x-coordinate.
931 * @param y the y-coordinate.
932 */
933 public void paintIcon(Component c, Graphics g, int x, int y)
934 {
935 Color savedColor = g.getColor();
936 JRadioButtonMenuItem item = (JRadioButtonMenuItem) c;
937 g.setColor(MetalLookAndFeel.getBlack());
938 g.drawLine(x + 2, y, x + 6, y);
939 g.drawLine(x + 7, y + 1, x + 7, y + 1);
940 g.drawLine(x + 8, y + 2, x + 8, y + 6);
941 g.drawLine(x + 7, y + 7, x + 7, y + 7);
942 g.drawLine(x + 2, y + 8, x + 6, y + 8);
943 g.drawLine(x + 1, y + 7, x + 1, y + 7);
944 g.drawLine(x, y + 2, x, y + 6);
945 g.drawLine(x + 1, y + 1, x + 1, y + 1);
946
947 if (item.isSelected())
948 {
949 g.drawLine(x + 3, y + 2, x + 5, y + 2);
950 g.fillRect(x + 2, y + 3, 5, 3);
951 g.drawLine(x + 3, y + 6, x + 5, y + 6);
952 }
953
954 // highlight
955 g.setColor(MetalLookAndFeel.getControlHighlight());
956 g.drawLine(x + 3, y + 1, x + 6, y + 1);
957 g.drawLine(x + 8, y + 1, x + 8, y + 1);
958 g.drawLine(x + 9, y + 2, x + 9, y + 7);
959 g.drawLine(x + 8, y + 8, x + 8, y + 8);
960 g.drawLine(x + 2, y + 9, x + 7, y + 9);
961 g.drawLine(x + 1, y + 8, x + 1, y + 8);
962 g.drawLine(x + 1, y + 3, x + 1, y + 6);
963 g.drawLine(x + 2, y + 2, x + 2, y + 2);
964 g.setColor(savedColor);
965 }
966 }
967
968 /**
969 * The icon used to display the thumb control on a horizontally oriented
970 * {@link JSlider} component.
971 */
972 private static class HorizontalSliderThumbIcon
973 implements Icon, UIResource, Serializable
974 {
975
976 /**
977 * This mask is used to paint the gradient in the shape of the thumb.
978 */
979 int[][] gradientMask = new int[][] { {0, 12}, {0, 12}, {0, 12}, {0, 12},
980 {0, 12}, {0, 12}, {0, 12}, {1, 11},
981 {2, 10}, {3, 9}, {4, 8}, {5, 7},
982 {6, 6}};
983
984 /**
985 * Creates a new instance.
986 */
987 public HorizontalSliderThumbIcon()
988 {
989 // Nothing to do here.
990 }
991
992 /**
993 * Returns the width of the icon, in pixels.
994 *
995 * @return The width of the icon.
996 */
997 public int getIconWidth()
998 {
999 return 15;
1000 }
1001
1002 /**
1003 * Returns the height of the icon, in pixels.
1004 *
1005 * @return The height of the icon.
1006 */
1007 public int getIconHeight()
1008 {
1009 return 16;
1010 }
1011
1012 /**
1013 * Paints the icon, taking into account whether or not the component has
1014 * the focus.
1015 *
1016 * @param c the component.
1017 * @param g the graphics device.
1018 * @param x the x-coordinate.
1019 * @param y the y-coordinate.
1020 */
1021 public void paintIcon(Component c, Graphics g, int x, int y)
1022 {
1023 boolean enabled = false;
1024 boolean focus = false;
1025 if (c != null)
1026 {
1027 enabled = c.isEnabled();
1028 focus = c.hasFocus();
1029 }
1030
1031 // draw the outline
1032 if (enabled)
1033 g.setColor(MetalLookAndFeel.getBlack());
1034 else
1035 g.setColor(MetalLookAndFeel.getControlDarkShadow());
1036 g.drawLine(x + 1, y, x + 13, y);
1037 g.drawLine(x + 14, y + 1, x + 14, y + 7);
1038 g.drawLine(x + 14, y + 8, x + 7, y + 15);
1039 g.drawLine(x + 6, y + 14, x, y + 8);
1040 g.drawLine(x, y + 7, x, y + 1);
1041
1042 // The following is commented out until the masking for the gradient painting
1043 // is working correctly
1044 // // Fill the icon.
1045 // if (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme
1046 // && enabled)
1047 // {
1048 // String gradient;
1049 // if (focus)
1050 // gradient = "Slider.focusGradient";
1051 // else
1052 // gradient = "Slider.gradient";
1053 // MetalUtils.paintGradient(g, x + 1, y + 2, 12, 13,
1054 // SwingConstants.VERTICAL, gradient,
1055 // gradientMask);
1056 // }
1057 // else
1058 {
1059 if (focus)
1060 g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1061 else
1062 g.setColor(MetalLookAndFeel.getControl());
1063 g.fillRect(x + 1, y + 2, 13, 7);
1064 g.drawLine(x + 2, y + 9, x + 12, y + 9);
1065 g.drawLine(x + 3, y + 10, x + 11, y + 10);
1066 g.drawLine(x + 4, y + 11, x + 10, y + 11);
1067 g.drawLine(x + 5, y + 12, x + 9, y + 12);
1068 g.drawLine(x + 6, y + 13, x + 8, y + 13);
1069 g.drawLine(x + 7, y + 14, x + 7, y + 14);
1070 }
1071
1072 // If the slider is enabled, draw dots and highlights.
1073 if (c.isEnabled()
1074 && !(MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme))
1075 {
1076 if (focus)
1077 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1078 else
1079 g.setColor(MetalLookAndFeel.getBlack());
1080 g.drawLine(x + 3, y + 3, x + 3, y + 3);
1081 g.drawLine(x + 7, y + 3, x + 7, y + 3);
1082 g.drawLine(x + 11, y + 3, x + 11, y + 3);
1083
1084 g.drawLine(x + 5, y + 5, x + 5, y + 5);
1085 g.drawLine(x + 9, y + 5, x + 9, y + 5);
1086
1087 g.drawLine(x + 3, y + 7, x + 3, y + 7);
1088 g.drawLine(x + 7, y + 7, x + 7, y + 7);
1089 g.drawLine(x + 11, y + 7, x + 11, y + 7);
1090
1091 // Draw highlights
1092 if (focus)
1093 g.setColor(MetalLookAndFeel.getPrimaryControl());
1094 else
1095 g.setColor(MetalLookAndFeel.getWhite());
1096 g.drawLine(x + 1, y + 1, x + 13, y + 1);
1097 g.drawLine(x + 1, y + 2, x + 1, y + 8);
1098 g.drawLine(x + 2, y + 2, x + 2, y + 2);
1099 g.drawLine(x + 6, y + 2, x + 6, y + 2);
1100 g.drawLine(x + 10, y + 2, x + 10, y + 2);
1101
1102 g.drawLine(x + 4, y + 4, x + 4, y + 4);
1103 g.drawLine(x + 8, y + 4, x + 8, y + 4);
1104
1105 g.drawLine(x + 2, y + 6, x + 2, y + 6);
1106 g.drawLine(x + 6, y + 6, x + 6, y + 6);
1107 g.drawLine(x + 10, y + 6, x + 10, y + 6);
1108 }
1109
1110 }
1111 }
1112
1113 /**
1114 * An icon used for the 'close' button in the title frame of a
1115 * {@link JInternalFrame}.
1116 */
1117 private static class InternalFrameCloseIcon
1118 implements Icon, UIResource, Serializable
1119 {
1120 /** The icon size in pixels. */
1121 private int size;
1122
1123 /**
1124 * Creates a new icon.
1125 *
1126 * @param size the icon size (width and height) in pixels.
1127 */
1128 public InternalFrameCloseIcon(int size)
1129 {
1130 this.size = size;
1131 }
1132
1133 /**
1134 * Returns the width of the icon, in pixels.
1135 *
1136 * @return The width of the icon.
1137 */
1138 public int getIconWidth()
1139 {
1140 return size;
1141 }
1142
1143 /**
1144 * Returns the height of the icon, in pixels.
1145 *
1146 * @return The height of the icon.
1147 */
1148 public int getIconHeight()
1149 {
1150 return size;
1151 }
1152
1153 /**
1154 * Paints the icon.
1155 *
1156 * @param c the component (an {@link JInternalFrame} is expected).
1157 * @param g the graphics device.
1158 * @param x the x-coordinate.
1159 * @param y the y-coordinate.
1160 */
1161 public void paintIcon(Component c, Graphics g, int x, int y)
1162 {
1163 Color savedColor = g.getColor();
1164 AbstractButton b = (AbstractButton) c;
1165
1166 // fill the interior
1167 if (b.getModel().isPressed())
1168 // FIXME: also need to take into account whether the internal frame is
1169 // selected
1170 g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1171 else
1172 g.setColor(MetalLookAndFeel.getPrimaryControl());
1173 g.fillRect(x + 2, y + 2, 10, 10);
1174
1175 // draw the outline box and the cross
1176 if (b.getModel().isPressed())
1177 g.setColor(MetalLookAndFeel.getBlack());
1178 else
1179 {
1180 // FIXME: also need to take into account whether the internal frame is
1181 // selected
1182 boolean selected = true;
1183 if (selected)
1184 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1185 else
1186 g.setColor(MetalLookAndFeel.getControlDarkShadow());
1187 }
1188 g.drawLine(x + 1, y + 1, x + 13, y + 1);
1189 g.drawLine(x + 1, y + 2, x + 1, y + 12);
1190 g.drawLine(x + 1, y + 13, x + 13, y + 13);
1191 g.drawLine(x + 13, y + 2, x + 13, y + 12);
1192 g.drawLine(x + 2, y + 12, x + 2, y + 12);
1193 g.drawLine(x + 12, y + 2, x + 12, y + 2);
1194
1195 g.fillRect(x + 4, y + 4, 2, 2);
1196 g.fillRect(x + 5, y + 5, 4, 4);
1197 g.drawLine(x + 9, y + 4, x + 10, y + 4);
1198 g.drawLine(x + 9, y + 4, x + 9, y + 5);
1199 g.drawLine(x + 4, y + 9, x + 4, y + 10);
1200 g.drawLine(x + 4, y + 9, x + 5, y + 9);
1201 g.drawLine(x + 9, y + 8, x + 9, y + 10);
1202 g.drawLine(x + 8, y + 9, x + 10, y + 9);
1203
1204 g.setColor(MetalLookAndFeel.getBlack());
1205 g.drawLine(x, y, x + 13, y);
1206 g.drawLine(x, y + 1, x, y + 13);
1207 g.drawLine(x + 3, y + 4, x + 4, y + 3);
1208 g.drawLine(x + 3, y + 9, x + 5, y + 7);
1209 g.drawLine(x + 7, y + 5, x + 9, y + 3);
1210
1211 g.drawLine(x + 12, y + 3, x + 12, y + 11);
1212 g.drawLine(x + 3, y + 12, x + 12, y + 12);
1213
1214 g.setColor(MetalLookAndFeel.getWhite());
1215 g.drawLine(x + 1, y + 14, x + 14, y + 14);
1216 g.drawLine(x + 14, y + 1, x + 14, y + 14);
1217
1218 if (!b.getModel().isPressed())
1219 {
1220 g.drawLine(x + 5, y + 10, x + 5, y + 10);
1221 g.drawLine(x + 6, y + 9, x + 7, y + 9);
1222 g.drawLine(x + 10, y + 5, x + 10, y + 5);
1223 g.drawLine(x + 9, y + 6, x + 9, y + 7);
1224 g.drawLine(x + 10, y + 10, x + 11, y + 10);
1225 g.drawLine(x + 10, y + 11, x + 10, y + 11);
1226 }
1227 g.setColor(savedColor);
1228 }
1229 }
1230
1231 /**
1232 * The icon displayed at the top-left corner of a {@link JInternalFrame}.
1233 */
1234 private static class InternalFrameDefaultMenuIcon
1235 implements Icon, UIResource, Serializable
1236 {
1237
1238 /**
1239 * Creates a new instance.
1240 */
1241 public InternalFrameDefaultMenuIcon()
1242 {
1243 // Nothing to do here.
1244 }
1245
1246 /**
1247 * Returns the width of the icon, in pixels.
1248 *
1249 * @return The width of the icon.
1250 */
1251 public int getIconWidth()
1252 {
1253 return 16;
1254 }
1255
1256 /**
1257 * Returns the height of the icon, in pixels.
1258 *
1259 * @return The height of the icon.
1260 */
1261 public int getIconHeight()
1262 {
1263 return 16;
1264 }
1265
1266 /**
1267 * Paints the icon at the specified location.
1268 *
1269 * @param c the component.
1270 * @param g the graphics device.
1271 * @param x the x coordinate.
1272 * @param y the y coordinate.
1273 */
1274 public void paintIcon(Component c, Graphics g, int x, int y)
1275 {
1276 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1277 g.fillRect(x + 1, y, 14, 2);
1278 g.fillRect(x, y + 1, 2, 14);
1279 g.fillRect(x + 1, y + 14, 14, 2);
1280 g.fillRect(x + 14, y + 1, 2, 14);
1281 g.drawLine(x + 2, y + 5, x + 14, y + 5);
1282
1283 g.setColor(MetalLookAndFeel.getPrimaryControl());
1284 g.fillRect(x + 2, y + 2, 12, 3);
1285
1286 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1287 g.drawLine(x + 3, y + 3, x + 3, y + 3);
1288 g.drawLine(x + 6, y + 3, x + 6, y + 3);
1289 g.drawLine(x + 9, y + 3, x + 9, y + 3);
1290 g.drawLine(x + 12, y + 3, x + 12, y + 3);
1291
1292 g.setColor(MetalLookAndFeel.getWhite());
1293 g.fillRect(x + 2, y + 6, 12, 8);
1294 g.drawLine(x + 2, y + 2, x + 2, y + 2);
1295 g.drawLine(x + 5, y + 2, x + 5, y + 2);
1296 g.drawLine(x + 8, y + 2, x + 8, y + 2);
1297 g.drawLine(x + 11, y + 2, x + 11, y + 2);
1298 }
1299 }
1300
1301 /**
1302 * An icon used in the title frame of a {@link JInternalFrame}. When you
1303 * maximise an internal frame, this icon will replace the 'maximise' icon to
1304 * provide a 'restore' option.
1305 */
1306 private static class InternalFrameAltMaximizeIcon
1307 implements Icon, UIResource, Serializable
1308 {
1309 /** The icon size in pixels. */
1310 private int size;
1311
1312 /**
1313 * Creates a new icon.
1314 *
1315 * @param size the icon size in pixels.
1316 */
1317 public InternalFrameAltMaximizeIcon(int size)
1318 {
1319 this.size = size;
1320 }
1321
1322 /**
1323 * Returns the width of the icon, in pixels.
1324 *
1325 * @return The width of the icon.
1326 */
1327 public int getIconWidth()
1328 {
1329 return size;
1330 }
1331
1332 /**
1333 * Returns the height of the icon, in pixels.
1334 *
1335 * @return The height of the icon.
1336 */
1337 public int getIconHeight()
1338 {
1339 return size;
1340 }
1341
1342 /**
1343 * Paints the icon at the specified location.
1344 *
1345 * @param c the component.
1346 * @param g the graphics device.
1347 * @param x the x coordinate.
1348 * @param y the y coordinate.
1349 */
1350 public void paintIcon(Component c, Graphics g, int x, int y)
1351 {
1352 Color savedColor = g.getColor();
1353
1354 AbstractButton b = (AbstractButton) c;
1355
1356 // fill the small box interior
1357 if (b.getModel().isPressed())
1358 g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1359 else
1360 g.setColor(MetalLookAndFeel.getPrimaryControl());
1361 g.fillRect(x + 2, y + 6, 7, 7);
1362
1363
1364 if (b.getModel().isPressed())
1365 g.setColor(MetalLookAndFeel.getBlack());
1366 else
1367 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1368
1369 g.drawLine(x + 12, y + 1, x + 13, y + 1);
1370 g.drawLine(x + 11, y + 2, x + 12, y + 2);
1371 g.drawLine(x + 10, y + 3, x + 11, y + 3);
1372 g.drawLine(x + 8, y + 2, x + 8, y + 3);
1373 g.fillRect(x + 8, y + 4, 3, 3);
1374 g.drawLine(x + 11, y + 6, x + 12, y + 6);
1375
1376 g.drawLine(x + 1, y + 5, x + 5, y + 5);
1377 g.drawLine(x + 1, y + 6, x + 1, y + 12);
1378 g.drawLine(x + 9, y + 9, x + 9, y + 12);
1379 g.drawLine(x + 1, y + 13, x + 9, y + 13);
1380
1381 g.drawLine(x + 2, y + 12, x + 2, y + 12);
1382
1383 g.setColor(MetalLookAndFeel.getBlack());
1384 g.drawLine(x + 12, y, x + 9, y + 3);
1385 g.drawLine(x + 7, y + 1, x + 8, y + 1);
1386 g.drawLine(x + 7, y + 2, x + 7, y + 6);
1387 g.drawLine(x + 11, y + 5, x + 12, y + 5);
1388 g.drawLine(x, y + 4, x + 5, y + 4);
1389 g.drawLine(x, y + 5, x, y + 13);
1390 g.drawLine(x + 3, y + 12, x + 8, y + 12);
1391 g.drawLine(x + 8, y + 8, x + 8, y + 11);
1392 g.drawLine(x + 9, y + 8, x + 9, y + 8);
1393
1394 g.setColor(MetalLookAndFeel.getWhite());
1395 g.drawLine(x + 9, y + 2, x + 9, y + 2);
1396 g.drawLine(x + 11, y + 4, x + 13, y + 2);
1397 g.drawLine(x + 13, y + 6, x + 13, y + 6);
1398 g.drawLine(x + 8, y + 7, x + 13, y + 7);
1399 g.drawLine(x + 6, y + 5, x + 6, y + 5);
1400 g.drawLine(x + 10, y + 8, x + 10, y + 13);
1401 g.drawLine(x + 1, y + 14, x + 10, y + 14);
1402
1403 if (!b.getModel().isPressed())
1404 {
1405 g.drawLine(x + 2, y + 6, x + 6, y + 6);
1406 g.drawLine(x + 2, y + 6, x + 2, y + 11);
1407 }
1408
1409 g.setColor(savedColor);
1410 }
1411 }
1412
1413 /**
1414 * An icon used for the 'maximize' button in the title frame of a
1415 * {@link JInternalFrame}.
1416 */
1417 private static class InternalFrameMaximizeIcon
1418 implements Icon, UIResource, Serializable
1419 {
1420
1421 /**
1422 * Creates a new instance.
1423 */
1424 public InternalFrameMaximizeIcon()
1425 {
1426 // Nothing to do here.
1427 }
1428
1429 /**
1430 * Returns the width of the icon, in pixels.
1431 *
1432 * @return The width of the icon.
1433 */
1434 public int getIconWidth()
1435 {
1436 return 16;
1437 }
1438
1439 /**
1440 * Returns the height of the icon, in pixels.
1441 *
1442 * @return The height of the icon.
1443 */
1444 public int getIconHeight()
1445 {
1446 return 16;
1447 }
1448
1449 /**
1450 * Paints the icon at the specified location.
1451 *
1452 * @param c the component.
1453 * @param g the graphics device.
1454 * @param x the x coordinate.
1455 * @param y the y coordinate.
1456 */
1457 public void paintIcon(Component c, Graphics g, int x, int y)
1458 {
1459 Color savedColor = g.getColor();
1460
1461 AbstractButton b = (AbstractButton) c;
1462
1463 // fill the interior
1464 if (b.getModel().isPressed())
1465 g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1466 else
1467 g.setColor(MetalLookAndFeel.getPrimaryControl());
1468 g.fillRect(x + 2, y + 6, 7, 7);
1469
1470 if (b.getModel().isPressed())
1471 g.setColor(MetalLookAndFeel.getBlack());
1472 else
1473 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1474
1475 g.drawLine(x + 9, y + 1, x + 10, y + 1);
1476 g.fillRect(x + 11, y + 1, 3, 3);
1477 g.fillRect(x + 12, y + 4, 2, 2);
1478 g.drawLine(x + 10, y + 3, x + 10, y + 3);
1479 g.drawLine(x + 9, y + 4, x + 10, y + 4);
1480 g.drawLine(x + 1, y + 5, x + 9, y + 5);
1481 g.drawLine(x + 1, y + 6, x + 1, y + 12);
1482 g.drawLine(x + 9, y + 6, x + 9, y + 12);
1483 g.drawLine(x + 1, y + 13, x + 9, y + 13);
1484
1485 // fill
1486 g.drawLine(x + 7, y + 6, x + 8, y + 6);
1487 g.drawLine(x + 6, y + 7, x + 8, y + 7);
1488 g.drawLine(x + 5, y + 8, x + 6, y + 8);
1489 g.drawLine(x + 4, y + 9, x + 5, y + 9);
1490 g.drawLine(x + 3, y + 10, x + 4, y + 10);
1491 g.drawLine(x + 2, y + 11, x + 3, y + 11);
1492 g.drawLine(x + 2, y + 12, x + 4, y + 12);
1493 g.drawLine(x + 8, y + 8, x + 8, y + 8);
1494
1495 // draw black
1496 g.setColor(MetalLookAndFeel.getBlack());
1497 g.drawLine(x + 8, y, x + 13, y);
1498 g.drawLine(x + 8, y + 1, x + 8, y + 1);
1499 g.drawLine(x + 10, y + 2, x + 9, y + 3);
1500 g.drawLine(x, y + 4, x + 8, y + 4);
1501 g.drawLine(x, y + 5, x, y + 13);
1502
1503 g.drawLine(x + 2, y + 10, x + 6, y + 6);
1504 g.drawLine(x + 8, y + 9, x + 8, y + 11);
1505 g.drawLine(x + 5, y + 12, x + 8, y + 12);
1506
1507 // draw white
1508 g.setColor(MetalLookAndFeel.getWhite());
1509 if (!b.getModel().isPressed())
1510 {
1511 g.drawLine(x + 2, y + 6, x + 5, y + 6);
1512 g.drawLine(x + 2, y + 7, x + 2, y + 9);
1513 g.drawLine(x + 4, y + 11, x + 7, y + 8);
1514 }
1515
1516 g.drawLine(x + 1, y + 14, x + 10, y + 14);
1517 g.drawLine(x + 10, y + 5, x + 10, y + 13);
1518
1519 g.drawLine(x + 9, y + 2, x + 9, y + 2);
1520 g.drawLine(x + 11, y + 4, x + 11, y + 5);
1521 g.drawLine(x + 13, y + 6, x + 14, y + 6);
1522 g.drawLine(x + 14, y + 1, x + 14, y + 5);
1523 g.setColor(savedColor);
1524 }
1525 }
1526
1527 /**
1528 * An icon used in the title frame of a {@link JInternalFrame}.
1529 */
1530 private static class InternalFrameMinimizeIcon
1531 implements Icon, UIResource, Serializable
1532 {
1533
1534 /**
1535 * Creates a new instance.
1536 */
1537 public InternalFrameMinimizeIcon()
1538 {
1539 // Nothing to do here.
1540 }
1541
1542 /**
1543 * Returns the width of the icon, in pixels.
1544 *
1545 * @return The width of the icon.
1546 */
1547 public int getIconWidth()
1548 {
1549 return 16;
1550 }
1551
1552 /**
1553 * Returns the height of the icon, in pixels.
1554 *
1555 * @return The height of the icon.
1556 */
1557 public int getIconHeight()
1558 {
1559 return 16;
1560 }
1561
1562 /**
1563 * Paints the icon at the specified location.
1564 *
1565 * @param c the component.
1566 * @param g the graphics device.
1567 * @param x the x coordinate.
1568 * @param y the y coordinate.
1569 */
1570 public void paintIcon(Component c, Graphics g, int x, int y)
1571 {
1572 Color savedColor = g.getColor();
1573
1574 AbstractButton b = (AbstractButton) c;
1575
1576 if (b.getModel().isPressed())
1577 g.setColor(MetalLookAndFeel.getBlack());
1578 else
1579 // FIXME: here the color depends on whether or not the internal frame
1580 // is selected
1581 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1582
1583 g.drawLine(x + 12, y + 1, x + 13, y + 1);
1584 g.drawLine(x + 11, y + 2, x + 12, y + 2);
1585 g.drawLine(x + 10, y + 3, x + 11, y + 3);
1586 g.drawLine(x + 8, y + 2, x + 8, y + 3);
1587 g.fillRect(x + 8, y + 4, 3, 3);
1588 g.drawLine(x + 11, y + 6, x + 12, y + 6);
1589
1590 g.drawLine(x + 1, y + 8, x + 6, y + 8);
1591 g.drawLine(x + 1, y + 9, x + 1, y + 12);
1592 g.drawLine(x + 6, y + 9, x + 6, y + 12);
1593 g.drawLine(x + 1, y + 13, x + 6, y + 13);
1594
1595 g.drawLine(x + 5, y + 9, x + 5, y + 9);
1596 g.drawLine(x + 2, y + 12, x + 2, y + 12);
1597
1598 g.setColor(MetalLookAndFeel.getBlack());
1599 g.drawLine(x + 12, y, x + 9, y + 3);
1600 g.drawLine(x + 7, y + 1, x + 8, y + 1);
1601 g.drawLine(x + 7, y + 2, x + 7, y + 6);
1602 g.drawLine(x, y + 7, x + 6, y + 7);
1603 g.drawLine(x, y + 8, x, y + 13);
1604 g.drawLine(x + 3, y + 12, x + 5, y + 12);
1605 g.drawLine(x + 5, y + 10, x + 5, y + 11);
1606 g.drawLine(x + 11, y + 5, x + 12, y + 5);
1607
1608 g.setColor(MetalLookAndFeel.getWhite());
1609 g.drawLine(x + 9, y + 2, x + 9, y + 2);
1610 g.drawLine(x + 11, y + 4, x + 13, y + 2);
1611 g.drawLine(x + 13, y + 6, x + 13, y + 6);
1612 g.drawLine(x + 8, y + 7, x + 13, y + 7);
1613 g.drawLine(x + 7, y + 9, x + 7, y + 13);
1614 g.drawLine(x + 1, y + 14, x + 7, y + 14);
1615
1616 if (b.getModel().isPressed())
1617 {
1618 g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1619 g.fillRect(x + 2, y + 9, 3, 3);
1620 }
1621 else
1622 {
1623 g.drawLine(x + 2, y + 9, x + 4, y + 9);
1624 g.drawLine(x + 2, y + 10, x + 2, y + 11);
1625 }
1626
1627 g.setColor(savedColor);
1628 }
1629 }
1630
1631 /**
1632 * The icon used to display the thumb control on a horizontally oriented
1633 * {@link JSlider} component.
1634 */
1635 private static class VerticalSliderThumbIcon
1636 implements Icon, UIResource, Serializable
1637 {
1638 /**
1639 * This mask is used to paint the gradient in the shape of the thumb.
1640 */
1641 int[][] gradientMask = new int[][] { {0, 12}, {0, 12}, {0, 12}, {0, 12},
1642 {0, 12}, {0, 12}, {0, 12}, {1, 11},
1643 {2, 10}, {3, 9}, {4, 8}, {5, 7},
1644 {6, 6}};
1645
1646 /**
1647 * Creates a new instance.
1648 */
1649 public VerticalSliderThumbIcon()
1650 {
1651 // Nothing to do here.
1652 }
1653
1654 /**
1655 * Returns the width of the icon, in pixels.
1656 *
1657 * @return The width of the icon.
1658 */
1659 public int getIconWidth()
1660 {
1661 return 16;
1662 }
1663
1664 /**
1665 * Returns the height of the icon, in pixels.
1666 *
1667 * @return The height of the icon.
1668 */
1669 public int getIconHeight()
1670 {
1671 return 15;
1672 }
1673
1674 /**
1675 * Paints the icon taking into account whether the slider control has the
1676 * focus or not.
1677 *
1678 * @param c the slider (must be a non-<code>null</code> instance of
1679 * {@link JSlider}.
1680 * @param g the graphics device.
1681 * @param x the x-coordinate.
1682 * @param y the y-coordinate.
1683 */
1684 public void paintIcon(Component c, Graphics g, int x, int y)
1685 {
1686 boolean enabled = false;
1687 boolean focus = false;
1688 if (c != null)
1689 {
1690 enabled = c.isEnabled();
1691 focus = c.hasFocus();
1692 }
1693
1694 // draw the outline
1695 if (enabled)
1696 g.setColor(MetalLookAndFeel.getBlack());
1697 else
1698 g.setColor(MetalLookAndFeel.getControlDarkShadow());
1699 g.drawLine(x + 1, y, x + 7, y);
1700 g.drawLine(x + 8, y, x + 15, y + 7);
1701 g.drawLine(x + 14, y + 8, x + 8, y + 14);
1702 g.drawLine(x + 8, y + 14, x + 1, y + 14);
1703 g.drawLine(x, y + 13, x, y + 1);
1704
1705 // The following is commented out until the masking for the gradient painting
1706 // is working correctly
1707 // // Fill the icon.
1708 // if (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme
1709 // && enabled)
1710 // {
1711 // String gradient;
1712 // if (focus)
1713 // gradient = "Slider.focusGradient";
1714 // else
1715 // gradient = "Slider.gradient";
1716 // MetalUtils.paintGradient(g, x + 2, y + 1, 13, 12,
1717 // SwingConstants.HORIZONTAL, gradient,
1718 // gradientMask);
1719 // }
1720 // else
1721 {
1722 if (focus)
1723 g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1724 else
1725 g.setColor(MetalLookAndFeel.getControl());
1726 g.fillRect(x + 2, y + 1, 7, 13);
1727 g.drawLine(x + 9, y + 2, x + 9, y + 12);
1728 g.drawLine(x + 10, y + 3, x + 10, y + 11);
1729 g.drawLine(x + 11, y + 4, x + 11, y + 10);
1730 g.drawLine(x + 12, y + 5, x + 12, y + 9);
1731 g.drawLine(x + 13, y + 6, x + 13, y + 8);
1732 g.drawLine(x + 14, y + 7, x + 14, y + 7);
1733 }
1734
1735 // if the slider is enabled, draw dots and highlights
1736 if (enabled
1737 && ! (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme))
1738 {
1739 if (focus)
1740 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1741 else
1742 g.setColor(MetalLookAndFeel.getBlack());
1743 g.drawLine(x + 3, y + 3, x + 3, y + 3);
1744 g.drawLine(x + 3, y + 7, x + 3, y + 7);
1745 g.drawLine(x + 3, y + 11, x + 3, y + 11);
1746
1747 g.drawLine(x + 5, y + 5, x + 5, y + 5);
1748 g.drawLine(x + 5, y + 9, x + 5, y + 9);
1749
1750 g.drawLine(x + 7, y + 3, x + 7, y + 3);
1751 g.drawLine(x + 7, y + 7, x + 7, y + 7);
1752 g.drawLine(x + 7, y + 11, x + 7, y + 11);
1753
1754 // draw highlights
1755 if (focus)
1756 g.setColor(MetalLookAndFeel.getPrimaryControl());
1757 else
1758 g.setColor(MetalLookAndFeel.getWhite());
1759 g.drawLine(x + 1, y + 1, x + 8, y + 1);
1760 g.drawLine(x + 1, y + 2, x + 1, y + 13);
1761 g.drawLine(x + 2, y + 2, x + 2, y + 2);
1762 g.drawLine(x + 2, y + 6, x + 2, y + 6);
1763 g.drawLine(x + 2, y + 10, x + 2, y + 10);
1764
1765 g.drawLine(x + 4, y + 4, x + 4, y + 4);
1766 g.drawLine(x + 4, y + 8, x + 4, y + 8);
1767
1768 g.drawLine(x + 6, y + 2, x + 6, y + 2);
1769 g.drawLine(x + 6, y + 6, x + 6, y + 6);
1770 g.drawLine(x + 6, y + 10, x + 6, y + 10);
1771
1772 }
1773 }
1774 }
1775
1776 /**
1777 * A tree control icon. This icon can be in one of two states: expanded and
1778 * collapsed.
1779 */
1780 public static class TreeControlIcon implements Icon, Serializable
1781 {
1782
1783 /** ???. */
1784 protected boolean isLight;
1785
1786 /** A flag that controls whether or not the icon is collapsed. */
1787 private boolean collapsed;
1788
1789 /**
1790 * Creates a new icon.
1791 *
1792 * @param isCollapsed a flag that controls whether the icon is in the
1793 * collapsed state or the expanded state.
1794 */
1795 public TreeControlIcon(boolean isCollapsed)
1796 {
1797 collapsed = isCollapsed;
1798 }
1799
1800 /**
1801 * Returns the width of the icon, in pixels.
1802 *
1803 * @return The width of the icon.
1804 */
1805 public int getIconWidth()
1806 {
1807 return 18;
1808 }
1809 /**
1810 * Returns the height of the icon, in pixels.
1811 *
1812 * @return The height of the icon.
1813 */
1814 public int getIconHeight()
1815 {
1816 return 18;
1817 }
1818
1819 /**
1820 * Paints the icon at the location (x, y).
1821 *
1822 * @param c the component.
1823 * @param g the graphics device.
1824 * @param x the x coordinate.
1825 * @param y the y coordinate.
1826 */
1827 public void paintIcon(Component c, Graphics g, int x, int y)
1828 {
1829 // TODO: pick up appropriate UI colors
1830 Color dark = new Color(99, 130, 191);
1831 Color light = new Color(163, 184, 204);
1832 Color white = Color.white;
1833
1834 x += 8;
1835 y += 6;
1836
1837 final int w = 6;
1838 final int wHalf = (w >> 2);
1839 g.setColor(light);
1840 g.drawOval(x, y, w, w);
1841 g.setColor(dark);
1842 g.fillOval(x + 1, y + 1, w - 1, w - 1);
1843
1844 if (collapsed)
1845 g.fillRect(x + w, y + wHalf + 1, w, 2);
1846 else
1847 g.fillRect(x + wHalf + 1, y + w, 2, w);
1848
1849 g.setColor(white);
1850 g.fillRect(x + wHalf + 1, y + wHalf + 1, 2, 2);
1851
1852 }
1853
1854 /**
1855 * Simply calls {@link #paintIcon(Component, Graphics, int, int)}.
1856 *
1857 * @param c the component.
1858 * @param g the graphics device.
1859 * @param x the x coordinate.
1860 * @param y the y coordinate.
1861 */
1862 public void paintMe(Component c, Graphics g, int x, int y)
1863 {
1864 paintIcon(c, g, x, y);
1865 }
1866 }
1867
1868 /**
1869 * A tree folder icon.
1870 */
1871 public static class TreeFolderIcon extends FolderIcon16
1872 {
1873 /**
1874 * Creates a new instance.
1875 */
1876 public TreeFolderIcon()
1877 {
1878 // Nothing to do here.
1879 }
1880
1881 /**
1882 * Returns the additional height for this icon, in this case <code>2</code>
1883 * pixels.
1884 *
1885 * @return <code>2</code>.
1886 */
1887 public int getAdditionalHeight()
1888 {
1889 return 2;
1890 }
1891
1892 /**
1893 * Returns the vertical shift, in pixels, applied when painting the icon.
1894 * This overridden method returns <code>-1</code>.
1895 *
1896 * @return The shift.
1897 */
1898 public int getShift()
1899 {
1900 return -1;
1901 }
1902 }
1903
1904 /**
1905 * A tree leaf icon.
1906 */
1907 public static class TreeLeafIcon extends FileIcon16
1908 {
1909 /**
1910 * Creates a new instance.
1911 */
1912 public TreeLeafIcon()
1913 {
1914 // Nothing to do here.
1915 }
1916
1917 /**
1918 * Returns the additional height for this icon, in this case <code>4</code>
1919 * pixels.
1920 *
1921 * @return <code>4</code>.
1922 */
1923 public int getAdditionalHeight()
1924 {
1925 return 4;
1926 }
1927
1928 /**
1929 * Returns the vertical shift, in pixels, applied when painting the icon.
1930 * This overridden method returns <code>2</code>.
1931 *
1932 * @return The shift.
1933 */
1934 public int getShift()
1935 {
1936 return 2;
1937 }
1938 }
1939
1940 /**
1941 * An icon representing a hard disk.
1942 *
1943 * @see MetalIconFactory#getTreeHardDriveIcon()
1944 */
1945 private static class TreeHardDriveIcon
1946 implements Icon, UIResource, Serializable
1947 {
1948
1949 /**
1950 * Creates a new icon instance.
1951 */
1952 public TreeHardDriveIcon()
1953 {
1954 // Nothing to do here.
1955 }
1956
1957 /**
1958 * Returns the width of the icon, in pixels.
1959 *
1960 * @return <code>16</code>.
1961 */
1962 public int getIconWidth()
1963 {
1964 return 16;
1965 }
1966
1967 /**
1968 * Returns the height of the icon, in pixels.
1969 *
1970 * @return <code>16</code>.
1971 */
1972 public int getIconHeight()
1973 {
1974 return 16;
1975 }
1976
1977 /**
1978 * Paints the icon at the specified location, using colors from the
1979 * current theme.
1980 *
1981 * @param c the component (ignored).
1982 * @param g the graphics device.
1983 * @param x the x-coordinate for the top-left of the icon.
1984 * @param y the y-coordinate for the top-left of the icon.
1985 */
1986 public void paintIcon(Component c, Graphics g, int x, int y)
1987 {
1988 Color saved = g.getColor();
1989 g.setColor(MetalLookAndFeel.getBlack());
1990 g.drawLine(x + 1, y + 4, x + 1, y + 5);
1991 g.drawLine(x + 14, y + 4, x + 14, y + 5);
1992 g.drawLine(x + 1, y + 7, x + 1, y + 8);
1993 g.drawLine(x + 14, y + 7, x + 14, y + 8);
1994 g.drawLine(x + 1, y + 10, x + 1, y + 11);
1995 g.drawLine(x + 14, y + 10, x + 14, y + 11);
1996
1997 g.drawLine(x + 2, y + 3, x + 3, y + 3);
1998 g.drawLine(x + 12, y + 3, x + 13, y + 3);
1999 g.drawLine(x + 2, y + 6, x + 3, y + 6);
2000 g.drawLine(x + 12, y + 6, x + 13, y + 6);
2001 g.drawLine(x + 2, y + 9, x + 3, y + 9);
2002 g.drawLine(x + 12, y + 9, x + 13, y + 9);
2003 g.drawLine(x + 2, y + 12, x + 3, y + 12);
2004 g.drawLine(x + 12, y + 12, x + 13, y + 12);
2005
2006 g.drawLine(x + 4, y + 2, x + 11, y + 2);
2007 g.drawLine(x + 4, y + 7, x + 11, y + 7);
2008 g.drawLine(x + 4, y + 10, x + 11, y + 10);
2009 g.drawLine(x + 4, y + 13, x + 11, y + 13);
2010
2011 g.setColor(MetalLookAndFeel.getWhite());
2012 g.fillRect(x + 4, y + 3, 2, 2);
2013 g.drawLine(x + 6, y + 4, x + 6, y + 4);
2014 g.drawLine(x + 7, y + 3, x + 9, y + 3);
2015 g.drawLine(x + 8, y + 4, x + 8, y + 4);
2016 g.drawLine(x + 11, y + 3, x + 11, y + 3);
2017 g.fillRect(x + 2, y + 4, 2, 2);
2018 g.fillRect(x + 2, y + 7, 2, 2);
2019 g.fillRect(x + 2, y + 10, 2, 2);
2020 g.drawLine(x + 4, y + 6, x + 4, y + 6);
2021 g.drawLine(x + 4, y + 9, x + 4, y + 9);
2022 g.drawLine(x + 4, y + 12, x + 4, y + 12);
2023
2024 g.setColor(MetalLookAndFeel.getControlShadow());
2025 g.drawLine(x + 13, y + 4, x + 13, y + 4);
2026 g.drawLine(x + 12, y + 5, x + 13, y + 5);
2027 g.drawLine(x + 13, y + 7, x + 13, y + 7);
2028 g.drawLine(x + 12, y + 8, x + 13, y + 8);
2029 g.drawLine(x + 13, y + 10, x + 13, y + 10);
2030 g.drawLine(x + 12, y + 11, x + 13, y + 11);
2031
2032 g.drawLine(x + 10, y + 5, x + 10, y + 5);
2033 g.drawLine(x + 7, y + 6, x + 7, y + 6);
2034 g.drawLine(x + 9, y + 6, x + 9, y + 6);
2035 g.drawLine(x + 11, y + 6, x + 11, y + 6);
2036
2037 g.drawLine(x + 10, y + 8, x + 10, y + 8);
2038 g.drawLine(x + 7, y + 9, x + 7, y + 9);
2039 g.drawLine(x + 9, y + 9, x + 9, y + 9);
2040 g.drawLine(x + 11, y + 9, x + 11, y + 9);
2041
2042 g.drawLine(x + 10, y + 11, x + 10, y + 11);
2043 g.drawLine(x + 7, y + 12, x + 7, y + 12);
2044 g.drawLine(x + 9, y + 12, x + 9, y + 12);
2045 g.drawLine(x + 11, y + 12, x + 11, y + 12);
2046
2047 g.setColor(saved);
2048 }
2049 }
2050
2051 /**
2052 * An icon representing a floppy disk.
2053 *
2054 * @see MetalIconFactory#getTreeFloppyDriveIcon()
2055 */
2056 private static class TreeFloppyDriveIcon
2057 implements Icon, UIResource, Serializable
2058 {
2059
2060 /**
2061 * Creates a new icon instance.
2062 */
2063 public TreeFloppyDriveIcon()
2064 {
2065 // Nothing to do here.
2066 }
2067
2068 /**
2069 * Returns the width of the icon, in pixels.
2070 *
2071 * @return <code>16</code>.
2072 */
2073 public int getIconWidth()
2074 {
2075 return 16;
2076 }
2077
2078 /**
2079 * Returns the height of the icon, in pixels.
2080 *
2081 * @return <code>16</code>.
2082 */
2083 public int getIconHeight()
2084 {
2085 return 16;
2086 }
2087
2088 /**
2089 * Paints the icon at the specified location, using colors from the
2090 * current theme.
2091 *
2092 * @param c the component (ignored).
2093 * @param g the graphics device.
2094 * @param x the x-coordinate for the top-left of the icon.
2095 * @param y the y-coordinate for the top-left of the icon.
2096 */
2097 public void paintIcon(Component c, Graphics g, int x, int y)
2098 {
2099 Color saved = g.getColor();
2100
2101 g.setColor(MetalLookAndFeel.getBlack());
2102 g.drawLine(x + 1, y + 1, x + 13, y + 1);
2103 g.drawLine(x + 1, y + 1, x + 1, y + 14);
2104 g.drawLine(x + 1, y + 14, x + 14, y + 14);
2105 g.drawLine(x + 14, y + 2, x + 14, y + 14);
2106
2107 g.setColor(MetalLookAndFeel.getPrimaryControl());
2108 g.fillRect(x + 2, y + 2, 12, 12);
2109
2110 g.setColor(MetalLookAndFeel.getControlShadow());
2111 g.fillRect(x + 5, y + 2, 6, 5);
2112 g.drawLine(x + 4, y + 8, x + 11, y + 8);
2113 g.drawLine(x + 3, y + 9, x + 3, y + 13);
2114 g.drawLine(x + 12, y + 9, x + 12, y + 13);
2115
2116 g.setColor(MetalLookAndFeel.getWhite());
2117 g.fillRect(x + 8, y + 3, 2, 3);
2118 g.fillRect(x + 4, y + 9, 8, 5);
2119
2120 g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
2121 g.drawLine(x + 5, y + 10, x + 9, y + 10);
2122 g.drawLine(x + 5, y + 12, x + 8, y + 12);
2123
2124 g.setColor(saved);
2125 }
2126 }
2127
2128 /**
2129 * An icon representing a computer.
2130 *
2131 * @see MetalIconFactory#getTreeComputerIcon()
2132 */
2133 private static class TreeComputerIcon
2134 implements Icon, UIResource, Serializable
2135 {
2136
2137 /**
2138 * Creates a new icon instance.
2139 */
2140 public TreeComputerIcon()
2141 {
2142 // Nothing to do here.
2143 }
2144
2145 /**
2146 * Returns the width of the icon, in pixels.
2147 *
2148 * @return <code>16</code>.
2149 */
2150 public int getIconWidth()
2151 {
2152 return 16;
2153 }
2154
2155 /**
2156 * Returns the height of the icon, in pixels.
2157 *
2158 * @return <code>16</code>.
2159 */
2160 public int getIconHeight()
2161 {
2162 return 16;
2163 }
2164
2165 /**
2166 * Paints the icon at the specified location, using colors from the
2167 * current theme.
2168 *
2169 * @param c the component (ignored).
2170 * @param g the graphics device.
2171 * @param x the x-coordinate for the top-left of the icon.
2172 * @param y the y-coordinate for the top-left of the icon.
2173 */
2174 public void paintIcon(Component c, Graphics g, int x, int y)
2175 {
2176 Color saved = g.getColor();
2177
2178 g.setColor(MetalLookAndFeel.getBlack());
2179 g.drawLine(x + 3, y + 1, x + 12, y + 1);
2180 g.drawLine(x + 2, y + 2, x + 2, y + 8);
2181 g.drawLine(x + 13, y + 2, x + 13, y + 8);
2182 g.drawLine(x + 3, y + 9, x + 3, y + 9);
2183 g.drawLine(x + 12, y + 9, x + 12, y + 9);
2184 g.drawRect(x + 1, y + 10, 13, 4);
2185 g.drawLine(x + 5, y + 3, x + 10, y + 3);
2186 g.drawLine(x + 5, y + 8, x + 10, y + 8);
2187 g.drawLine(x + 4, y + 4, x + 4, y + 7);
2188 g.drawLine(x + 11, y + 4, x + 11, y + 7);
2189
2190 g.setColor(MetalLookAndFeel.getPrimaryControl());
2191 g.fillRect(x + 5, y + 4, 6, 4);
2192
2193 g.setColor(MetalLookAndFeel.getControlShadow());
2194 g.drawLine(x + 6, y + 12, x + 8, y + 12);
2195 g.drawLine(x + 10, y + 12, x + 12, y + 12);
2196 g.setColor(saved);
2197 }
2198 }
2199
2200 /** The icon returned by {@link #getCheckBoxIcon()}. */
2201 private static Icon checkBoxIcon;
2202
2203 /** The icon returned by {@link #getCheckBoxMenuItemIcon()}. */
2204 private static Icon checkBoxMenuItemIcon;
2205
2206 /** The icon returned by {@link #getFileChooserDetailViewIcon()}. */
2207 private static Icon fileChooserDetailViewIcon;
2208
2209 /** The icon returned by {@link #getFileChooserHomeFolderIcon()}. */
2210 private static Icon fileChooserHomeFolderIcon;
2211
2212 /** The icon returned by {@link #getFileChooserListViewIcon()}. */
2213 private static Icon fileChooserListViewIcon;
2214
2215 /** The icon returned by {@link #getFileChooserNewFolderIcon()}. */
2216 private static Icon fileChooserNewFolderIcon;
2217
2218 /** The icon returned by {@link #getFileChooserUpFolderIcon()}. */
2219 private static Icon fileChooserUpFolderIcon;
2220
2221 /** The cached RadioButtonIcon instance. */
2222 private static RadioButtonIcon radioButtonIcon;
2223
2224 /** The icon returned by {@link #getRadioButtonMenuItemIcon()}. */
2225 private static Icon radioButtonMenuItemIcon;
2226
2227 /** The icon returned by {@link #getInternalFrameDefaultMenuIcon()}. */
2228 private static Icon internalFrameDefaultMenuIcon;
2229
2230 /** The icon returned by {@link #getTreeComputerIcon()}. */
2231 private static Icon treeComputerIcon;
2232
2233 /** The icon instance returned by {@link #getTreeFloppyDriveIcon()}. */
2234 private static Icon treeFloppyDriveIcon;
2235
2236 /** The icon instance returned by {@link #getTreeHardDriveIcon()}. */
2237 private static Icon treeHardDriveIcon;
2238
2239 /** The icon instance returned by {@link #getHorizontalSliderThumbIcon()}. */
2240 private static Icon horizontalSliderThumbIcon;
2241
2242 /** The icon instance returned by {@link #getVerticalSliderThumbIcon()}. */
2243 private static Icon verticalSliderThumbIcon;
2244
2245 /**
2246 * Creates a new instance. All the methods are static, so creating an
2247 * instance isn't necessary.
2248 */
2249 public MetalIconFactory()
2250 {
2251 // Nothing to do here.
2252 }
2253
2254 /**
2255 * Returns an icon for use when rendering the {@link JCheckBox} component.
2256 *
2257 * @return A check box icon.
2258 *
2259 * @since 1.3
2260 */
2261 public static Icon getCheckBoxIcon()
2262 {
2263 if (checkBoxIcon == null)
2264 checkBoxIcon = new MetalCheckBoxIcon();
2265 return checkBoxIcon;
2266 }
2267
2268 /**
2269 * Returns an icon for use when rendering the {@link JCheckBoxMenuItem}
2270 * component.
2271 *
2272 * @return An icon.
2273 */
2274 public static Icon getCheckBoxMenuItemIcon()
2275 {
2276 if (checkBoxMenuItemIcon == null)
2277 checkBoxMenuItemIcon = new CheckBoxMenuItemIcon();
2278 return checkBoxMenuItemIcon;
2279 }
2280
2281 /**
2282 * Returns an icon for use by the {@link JFileChooser} component.
2283 *
2284 * @return An icon.
2285 */
2286 public static Icon getFileChooserDetailViewIcon()
2287 {
2288 if (fileChooserDetailViewIcon == null)
2289 fileChooserDetailViewIcon = new FileChooserDetailViewIcon();
2290 return fileChooserDetailViewIcon;
2291 }
2292
2293 /**
2294 * Returns an icon for use by the {@link JFileChooser} component.
2295 *
2296 * @return An icon.
2297 */
2298 public static Icon getFileChooserHomeFolderIcon()
2299 {
2300 if (fileChooserHomeFolderIcon == null)
2301 fileChooserHomeFolderIcon = new FileChooserHomeFolderIcon();
2302 return fileChooserHomeFolderIcon;
2303 }
2304
2305 /**
2306 * Returns an icon for use by the {@link JFileChooser} component.
2307 *
2308 * @return An icon.
2309 */
2310 public static Icon getFileChooserListViewIcon()
2311 {
2312 if (fileChooserListViewIcon == null)
2313 fileChooserListViewIcon = new FileChooserListViewIcon();
2314 return fileChooserListViewIcon;
2315 }
2316
2317 /**
2318 * Returns an icon for use by the {@link JFileChooser} component.
2319 *
2320 * @return An icon.
2321 */
2322 public static Icon getFileChooserNewFolderIcon()
2323 {
2324 if (fileChooserNewFolderIcon == null)
2325 fileChooserNewFolderIcon = new FileChooserNewFolderIcon();
2326 return fileChooserNewFolderIcon;
2327 }
2328
2329 /**
2330 * Returns an icon for use by the {@link JFileChooser} component.
2331 *
2332 * @return An icon.
2333 */
2334 public static Icon getFileChooserUpFolderIcon()
2335 {
2336 if (fileChooserUpFolderIcon == null)
2337 fileChooserUpFolderIcon = new FileChooserUpFolderIcon();
2338 return fileChooserUpFolderIcon;
2339 }
2340
2341 /**
2342 * Returns an icon for RadioButtons in the Metal L&F.
2343 *
2344 * @return an icon for RadioButtons in the Metal L&F
2345 */
2346 public static Icon getRadioButtonIcon()
2347 {
2348 if (radioButtonIcon == null)
2349 radioButtonIcon = new RadioButtonIcon();
2350 return radioButtonIcon;
2351 }
2352
2353 /**
2354 * Creates a new instance of the icon used in a {@link JRadioButtonMenuItem}.
2355 *
2356 * @return A new icon instance.
2357 */
2358 public static Icon getRadioButtonMenuItemIcon()
2359 {
2360 if (radioButtonMenuItemIcon == null)
2361 radioButtonMenuItemIcon = new RadioButtonMenuItemIcon();
2362 return radioButtonMenuItemIcon;
2363 }
2364
2365 /**
2366 * Returns the icon used to display the thumb for a horizontally oriented
2367 * {@link JSlider}.
2368 *
2369 * @return The icon.
2370 */
2371 public static Icon getHorizontalSliderThumbIcon()
2372 {
2373 if (horizontalSliderThumbIcon == null)
2374 horizontalSliderThumbIcon = new HorizontalSliderThumbIcon();
2375 return horizontalSliderThumbIcon;
2376 }
2377
2378 /**
2379 * Creates a new icon used to represent the 'close' button in the title
2380 * pane of a {@link JInternalFrame}.
2381 *
2382 * @param size the icon size.
2383 *
2384 * @return A close icon.
2385 */
2386 public static Icon getInternalFrameCloseIcon(int size)
2387 {
2388 return new InternalFrameCloseIcon(size);
2389 }
2390
2391 /**
2392 * Creates a new icon for the menu in a {@link JInternalFrame}. This is the
2393 * icon displayed at the top left of the frame.
2394 *
2395 * @return A menu icon.
2396 */
2397 public static Icon getInternalFrameDefaultMenuIcon()
2398 {
2399 if (internalFrameDefaultMenuIcon == null)
2400 internalFrameDefaultMenuIcon = new InternalFrameDefaultMenuIcon();
2401 return internalFrameDefaultMenuIcon;
2402 }
2403
2404 /**
2405 * Creates a new icon for the 'maximize' button in a {@link JInternalFrame}.
2406 *
2407 * @param size the icon size in pixels.
2408 *
2409 * @return The icon.
2410 *
2411 * @see #getInternalFrameAltMaximizeIcon(int)
2412 */
2413 public static Icon getInternalFrameMaximizeIcon(int size)
2414 {
2415 return new InternalFrameMaximizeIcon();
2416 }
2417
2418 /**
2419 * Returns the icon used for the minimize button in the frame title for a
2420 * {@link JInternalFrame}.
2421 *
2422 * @param size the icon size in pixels (ignored by this implementation).
2423 *
2424 * @return The icon.
2425 */
2426 public static Icon getInternalFrameMinimizeIcon(int size)
2427 {
2428 return new InternalFrameMinimizeIcon();
2429 }
2430
2431 /**
2432 * Creates a new icon for the 'restore' button in a {@link JInternalFrame}
2433 * that has been maximised.
2434 *
2435 * @param size the icon size in pixels.
2436 *
2437 * @return The icon.
2438 *
2439 * @see #getInternalFrameMaximizeIcon(int)
2440 */
2441 public static Icon getInternalFrameAltMaximizeIcon(int size)
2442 {
2443 return new InternalFrameAltMaximizeIcon(size);
2444 }
2445
2446 /**
2447 * Returns the icon used to display the thumb for a vertically oriented
2448 * {@link JSlider}.
2449 *
2450 * @return The icon.
2451 */
2452 public static Icon getVerticalSliderThumbIcon()
2453 {
2454 if (verticalSliderThumbIcon == null)
2455 verticalSliderThumbIcon = new VerticalSliderThumbIcon();
2456 return verticalSliderThumbIcon;
2457 }
2458
2459 /**
2460 * Creates and returns a new tree folder icon.
2461 *
2462 * @return A new tree folder icon.
2463 */
2464 public static Icon getTreeFolderIcon()
2465 {
2466 return new TreeFolderIcon();
2467 }
2468
2469 /**
2470 * Creates and returns a new tree leaf icon.
2471 *
2472 * @return A new tree leaf icon.
2473 */
2474 public static Icon getTreeLeafIcon()
2475 {
2476 return new TreeLeafIcon();
2477 }
2478
2479 /**
2480 * Creates and returns a tree control icon.
2481 *
2482 * @param isCollapsed a flag that controls whether the icon is in the
2483 * collapsed or expanded state.
2484 *
2485 * @return A tree control icon.
2486 */
2487 public static Icon getTreeControlIcon(boolean isCollapsed)
2488 {
2489 return new TreeControlIcon(isCollapsed);
2490 }
2491
2492 /**
2493 * Returns a <code>16x16</code> icon representing a computer.
2494 *
2495 * @return The icon.
2496 */
2497 public static Icon getTreeComputerIcon()
2498 {
2499 if (treeComputerIcon == null)
2500 treeComputerIcon = new TreeComputerIcon();
2501 return treeComputerIcon;
2502 }
2503
2504 /**
2505 * Returns a <code>16x16</code> icon representing a floppy disk.
2506 *
2507 * @return The icon.
2508 */
2509 public static Icon getTreeFloppyDriveIcon()
2510 {
2511 if (treeFloppyDriveIcon == null)
2512 treeFloppyDriveIcon = new TreeFloppyDriveIcon();
2513 return treeFloppyDriveIcon;
2514 }
2515
2516 /**
2517 * Returns a <code>16x16</code> icon representing a hard disk.
2518 *
2519 * @return The icon.
2520 */
2521 public static Icon getTreeHardDriveIcon()
2522 {
2523 if (treeHardDriveIcon == null)
2524 treeHardDriveIcon = new TreeHardDriveIcon();
2525 return treeHardDriveIcon;
2526 }
2527
2528 /**
2529 * Returns a new instance of a 4 x 8 icon showing a small black triangle that
2530 * points to the right. This is displayed in menu items that have a
2531 * sub menu.
2532 *
2533 * @return The icon.
2534 */
2535 public static Icon getMenuArrowIcon()
2536 {
2537 if (menuArrow == null)
2538 menuArrow = new Icon()
2539 {
2540 public int getIconHeight()
2541 {
2542 return 8;
2543 }
2544
2545 public int getIconWidth()
2546 {
2547 return 4;
2548 }
2549
2550 public void paintIcon(Component c, Graphics g, int x, int y)
2551 {
2552 Color saved = g.getColor();
2553 g.setColor(Color.BLACK);
2554 for (int i = 0; i < 4; i++)
2555 g.drawLine(x + i, y + i, x + i, y + 7 - i);
2556 g.setColor(saved);
2557 }
2558 };
2559 return menuArrow;
2560 }
2561
2562 /**
2563 * Returns a new instance of a 4 x 8 icon showing a small black triangle that
2564 * points to the right. This is displayed in menu items that have a sub menu.
2565 *
2566 * @return The icon.
2567 */
2568 public static Icon getMenuItemArrowIcon()
2569 {
2570 if (menuItemArrow == null)
2571 menuItemArrow = new Icon()
2572 {
2573 public int getIconHeight()
2574 {
2575 return 8;
2576 }
2577
2578 public int getIconWidth()
2579 {
2580 return 4;
2581 }
2582
2583 public void paintIcon(Component c, Graphics g, int x, int y)
2584 {
2585 Color saved = g.getColor();
2586 g.setColor(Color.BLACK);
2587 for (int i = 0; i < 4; i++)
2588 g.drawLine(x + i, y + i, x + i, y + 7 - i);
2589 g.setColor(saved);
2590 }
2591 };
2592 return menuItemArrow;
2593 }
2594
2595 /**
2596 * Returns a new instance of a 13 x 13 icon showing a small black check mark.
2597 *
2598 * @return The icon.
2599 */
2600 public static Icon getMenuItemCheckIcon()
2601 {
2602 return new Icon()
2603 {
2604 public int getIconHeight()
2605 {
2606 return 13;
2607 }
2608
2609 public int getIconWidth()
2610 {
2611 return 13;
2612 }
2613
2614 public void paintIcon(Component c, Graphics g, int x, int y)
2615 {
2616 Color saved = g.getColor();
2617 g.setColor(Color.BLACK);
2618 g.drawLine(3 + x, 5 + y, 3 + x, 9 + y);
2619 g.drawLine(4 + x, 5 + y, 4 + x, 9 + y);
2620 g.drawLine(5 + x, 7 + y, 9 + x, 3 + y);
2621 g.drawLine(5 + x, 8 + y, 9 + x, 4 + y);
2622 g.setColor(saved);
2623 }
2624 };
2625 }
2626 }