1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57:
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71:
72:
76: public class BasicProgressBarUI extends ProgressBarUI
77: {
78:
86: public class ChangeHandler implements ChangeListener
87: {
88:
93: public void stateChanged(ChangeEvent e)
94: {
95:
96: progressBar.repaint();
97: }
98: }
99:
100:
104: private class PropertyChangeHandler implements PropertyChangeListener
105: {
106:
112: public void propertyChange(PropertyChangeEvent e)
113: {
114:
115:
116: if (e.getPropertyName().equals("indeterminate"))
117: if (((Boolean) e.getNewValue()).booleanValue()
118: && progressBar.isShowing())
119: startAnimationTimer();
120: else
121: stopAnimationTimer();
122: }
123: }
124:
125:
131: private class AncestorHandler implements AncestorListener
132: {
133:
134:
140: public void ancestorAdded(AncestorEvent event)
141: {
142: if (progressBar.isIndeterminate())
143: startAnimationTimer();
144: }
145:
146:
152: public void ancestorRemoved(AncestorEvent event)
153: {
154: stopAnimationTimer();
155: }
156:
157:
161: public void ancestorMoved(AncestorEvent event)
162: {
163:
164: }
165:
166: }
167:
168:
173: private class Animator implements ActionListener
174: {
175:
181: public void actionPerformed(ActionEvent e)
182: {
183:
184:
185: incrementAnimationIndex();
186: }
187: }
188:
189:
196: private class ComponentHandler extends ComponentAdapter
197: {
198:
205: public void componentResized(ComponentEvent e)
206: {
207: boxDependent = -1;
208: boxIndependent = -1;
209: incr = -1;
210: }
211: }
212:
213:
218: protected Rectangle boxRect;
219:
220:
221: private transient Timer animationTimer;
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234: private transient int animationIndex;
235:
236:
237: private transient int numFrames;
238:
239:
240: private transient Animator animation;
241:
242:
243: private transient PropertyChangeHandler propertyListener;
244:
245:
246: protected ChangeListener changeListener;
247:
248:
249: protected JProgressBar progressBar;
250:
251:
252:
257: transient double boxDependent = - 1;
258:
259:
264: transient int boxIndependent = - 1;
265:
266:
270: transient double incr = -1;
271:
272:
273: private transient int cellLength;
274:
275:
276: private transient int cellSpacing;
277:
278:
279: private transient Color selectionBackground;
280:
281:
282: private transient Color selectionForeground;
283:
284:
288: private AncestorListener ancestorListener;
289:
290:
294: private ComponentListener componentListener;
295:
296:
299: public BasicProgressBarUI()
300: {
301: super();
302: }
303:
304:
311: public static ComponentUI createUI(JComponent x)
312: {
313: return new BasicProgressBarUI();
314: }
315:
316:
327: protected int getAmountFull(Insets b, int width, int height)
328: {
329: double percentDone = progressBar.getPercentComplete();
330: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
331: return (int) (percentDone * (width - b.left - b.right));
332: else
333: return (int) (percentDone * (height - b.top - b.bottom));
334: }
335:
336:
341: protected int getAnimationIndex()
342: {
343: return animationIndex;
344: }
345:
346:
356: protected Rectangle getBox(Rectangle r)
357: {
358: if (!progressBar.isIndeterminate())
359: return null;
360: if (r == null)
361: r = new Rectangle();
362:
363: Rectangle vr = new Rectangle();
364: SwingUtilities.calculateInnerArea(progressBar, vr);
365:
366:
367: if (incr == -1 || boxDependent == -1 || boxIndependent == -1)
368: {
369:
370: int iterations = numFrames / 2;
371: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
372: {
373: boxDependent = vr.width / 6.;
374: incr = ((double) (vr.width - boxDependent)) / (double) iterations;
375: boxIndependent = vr.height;
376: }
377: else
378: {
379: boxDependent = vr.height / 6.;
380: incr = ((double) (vr.height - boxDependent)) / (double) iterations;
381: boxIndependent = vr.width;
382: }
383: }
384:
385: int index = getAnimationIndex();
386: if (animationIndex > (numFrames) / 2)
387: index = numFrames - getAnimationIndex();
388:
389: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
390: {
391: r.x = vr.x + (int) (incr * index);
392: r.y = vr.y;
393: r.width = (int) boxDependent;
394: r.height = (int) boxIndependent;
395: }
396: else
397: {
398: r.x = vr.x;
399: r.y = vr.height - (int) (incr * index) + vr.y - (int) boxDependent;
400: r.width = (int) boxIndependent;
401: r.height = (int) boxDependent;
402: }
403: return r;
404: }
405:
406:
411: protected int getCellLength()
412: {
413: return cellLength;
414: }
415:
416:
421: protected int getCellSpacing()
422: {
423: return cellSpacing;
424: }
425:
426:
435: public Dimension getMaximumSize(JComponent c)
436: {
437: Insets insets = c.getInsets();
438: Dimension ret;
439: int orientation = progressBar.getOrientation();
440: if (orientation == JProgressBar.VERTICAL)
441: {
442: ret = getPreferredInnerVertical();
443: ret.height = Short.MAX_VALUE;
444: ret.width += insets.left + insets.right;
445: }
446: else
447: {
448: ret = getPreferredInnerHorizontal();
449: ret.width = Short.MAX_VALUE;
450: ret.height += insets.top + insets.bottom;
451: }
452: return ret;
453: }
454:
455:
464: public Dimension getMinimumSize(JComponent c)
465: {
466: Insets insets = c.getInsets();
467: Dimension ret;
468: int orientation = progressBar.getOrientation();
469: if (orientation == JProgressBar.VERTICAL)
470: {
471: ret = getPreferredInnerVertical();
472: ret.height = 10;
473: ret.width += insets.left + insets.right;
474: }
475: else
476: {
477: ret = getPreferredInnerHorizontal();
478: ret.width = 10;
479: ret.height += insets.top + insets.bottom;
480: }
481: return ret;
482: }
483:
484:
492: protected Dimension getPreferredInnerHorizontal()
493: {
494: Font font = progressBar.getFont();
495: FontMetrics fm = progressBar.getFontMetrics(font);
496:
497: int stringWidth = 0;
498: String str = progressBar.getString();
499: if (str != null)
500: stringWidth = fm.stringWidth(progressBar.getString());
501: Insets i = progressBar.getInsets();
502: int prefWidth = Math.max(200 - i.left - i.right, stringWidth);
503:
504: int stringHeight = 0;
505: if (str != null)
506: stringHeight = fm.getHeight();
507: int prefHeight = Math.max(16 - i.top - i.bottom, stringHeight);
508:
509: return new Dimension(prefWidth, prefHeight);
510: }
511:
512:
520: protected Dimension getPreferredInnerVertical()
521: {
522: Font font = progressBar.getFont();
523: FontMetrics fm = progressBar.getFontMetrics(font);
524:
525: int stringWidth = 0;
526: String str = progressBar.getString();
527: if (str != null)
528: stringWidth = fm.stringWidth(progressBar.getString());
529: Insets i = progressBar.getInsets();
530: int prefHeight = Math.max(200 - i.left - i.right, stringWidth);
531:
532: int stringHeight = 0;
533: if (str != null)
534: stringHeight = fm.getHeight();
535: int prefWidth = Math.max(16 - i.top - i.bottom, stringHeight);
536:
537: return new Dimension(prefWidth, prefHeight);
538: }
539:
540:
549: public Dimension getPreferredSize(JComponent c)
550: {
551: Insets insets = c.getInsets();
552: Dimension ret;
553: int orientation = progressBar.getOrientation();
554: if (orientation == JProgressBar.VERTICAL)
555: ret = getPreferredInnerVertical();
556: else
557: ret = getPreferredInnerHorizontal();
558: ret.width += insets.left + insets.right;
559: ret.height += insets.top + insets.bottom;
560: return ret;
561: }
562:
563:
569: protected Color getSelectionBackground()
570: {
571: return selectionBackground;
572: }
573:
574:
580: protected Color getSelectionForeground()
581: {
582: return selectionForeground;
583: }
584:
585:
598: protected Point getStringPlacement(Graphics g, String progressString, int x,
599: int y, int width, int height)
600: {
601: Rectangle tr = new Rectangle();
602: Rectangle vr = new Rectangle(x, y, width, height);
603: Rectangle ir = new Rectangle();
604:
605: Font f = g.getFont();
606: FontMetrics fm = g.getFontMetrics(f);
607:
608: SwingUtilities.layoutCompoundLabel(progressBar, fm, progressString, null,
609: SwingConstants.CENTER,
610: SwingConstants.CENTER,
611: SwingConstants.CENTER,
612: SwingConstants.CENTER, vr, ir, tr, 0);
613: return new Point(tr.x, tr.y);
614: }
615:
616:
619: protected void incrementAnimationIndex()
620: {
621: animationIndex++;
622:
623: if (animationIndex >= numFrames)
624: animationIndex = 0;
625: progressBar.repaint();
626: }
627:
628:
635: public void paint(Graphics g, JComponent c)
636: {
637: if (! progressBar.isIndeterminate())
638: paintDeterminate(g, c);
639: else
640: paintIndeterminate(g, c);
641: }
642:
643:
650: protected void paintDeterminate(Graphics g, JComponent c)
651: {
652: Color saved = g.getColor();
653: int space = getCellSpacing();
654: int len = getCellLength();
655: int max = progressBar.getMaximum();
656: int min = progressBar.getMinimum();
657: int value = progressBar.getValue();
658:
659: Rectangle vr = SwingUtilities.calculateInnerArea(c, new Rectangle());
660: Rectangle or = progressBar.getBounds();
661: Insets insets = c.getInsets();
662:
663: int amountFull = getAmountFull(insets, or.width, or.height);
664:
665: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
666: {
667: g.setColor(c.getForeground());
668: g.fillRect(vr.x, vr.y, amountFull, vr.height);
669: }
670: else
671: {
672: g.setColor(c.getForeground());
673: g.fillRect(vr.x, vr.y + vr.height - amountFull, vr.width, amountFull);
674: }
675:
676: if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
677: paintString(g, 0, 0, or.width, or.height, amountFull, insets);
678: g.setColor(saved);
679: }
680:
681:
688: protected void paintIndeterminate(Graphics g, JComponent c)
689: {
690:
691:
692: Color saved = g.getColor();
693: Insets insets = c.getInsets();
694:
695: Rectangle or = c.getBounds();
696: Rectangle vr = new Rectangle();
697: SwingUtilities.calculateInnerArea(c, vr);
698:
699: g.setColor(c.getBackground());
700: g.fillRect(vr.x, vr.y, vr.width, vr.height);
701:
702: boxRect = getBox(boxRect);
703:
704: g.setColor(c.getForeground());
705: g.fillRect(boxRect.x, boxRect.y, boxRect.width, boxRect.height);
706:
707: if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
708: paintString(g, 0, 0, or.width, or.height,
709: getAmountFull(insets, or.width, or.height), insets);
710:
711: g.setColor(saved);
712: }
713:
714:
725: protected void paintString(Graphics g, int x, int y, int width, int height,
726: int amountFull, Insets b)
727: {
728:
729:
730: if (progressBar.getOrientation() == JProgressBar.VERTICAL)
731: return;
732:
733:
734: Point placement = getStringPlacement(g, progressBar.getString(),
735: x + b.left, y + b.top,
736: width - b.left - b.right,
737: height - b.top - b.bottom);
738:
739: Color savedColor = g.getColor();
740: Shape savedClip = g.getClip();
741: FontMetrics fm = g.getFontMetrics(progressBar.getFont());
742: int full = getAmountFull(b, width, height);
743: String str = progressBar.getString();
744:
745:
746:
747:
748: g.setColor(getSelectionForeground());
749: g.setClip(0, 0, full + b.left, height);
750: g.drawString(str, placement.x, placement.y + fm.getAscent());
751: g.setColor(getSelectionBackground());
752: g.setClip(full + b.left, 0, width - full, height);
753: g.drawString(str, placement.x, placement.y + fm.getAscent());
754: g.setClip(savedClip);
755: g.setColor(savedColor);
756: }
757:
758:
764: protected void setAnimationIndex(int newValue)
765: {
766: animationIndex = (newValue <= numFrames) ? newValue : 0;
767: progressBar.repaint();
768: }
769:
770:
775: protected void setCellLength(int cellLen)
776: {
777: cellLength = cellLen;
778: }
779:
780:
785: protected void setCellSpacing(int cellSpace)
786: {
787: cellSpacing = cellSpace;
788: }
789:
790:
797: protected void startAnimationTimer()
798: {
799: if (animationTimer != null)
800: animationTimer.start();
801: }
802:
803:
810: protected void stopAnimationTimer()
811: {
812: if (animationTimer != null)
813: animationTimer.stop();
814: setAnimationIndex(0);
815: }
816:
817:
821: protected void installDefaults()
822: {
823: LookAndFeel.installColorsAndFont(progressBar, "ProgressBar.background",
824: "ProgressBar.foreground",
825: "ProgressBar.font");
826: LookAndFeel.installBorder(progressBar, "ProgressBar.border");
827: progressBar.setOpaque(true);
828:
829: selectionForeground = UIManager.getColor("ProgressBar.selectionForeground");
830: selectionBackground = UIManager.getColor("ProgressBar.selectionBackground");
831: cellLength = UIManager.getInt("ProgressBar.cellLength");
832: cellSpacing = UIManager.getInt("ProgressBar.cellSpacing");
833:
834: int repaintInterval = UIManager.getInt("ProgressBar.repaintInterval");
835: int cycleTime = UIManager.getInt("ProgressBar.cycleTime");
836:
837: if (cycleTime % repaintInterval != 0
838: && (cycleTime / repaintInterval) % 2 != 0)
839: {
840: int div = (cycleTime / repaintInterval) + 2;
841: div /= 2;
842: div *= 2;
843: cycleTime = div * repaintInterval;
844: }
845: setAnimationIndex(0);
846: numFrames = cycleTime / repaintInterval;
847: animationTimer.setDelay(repaintInterval);
848: }
849:
850:
854: protected void uninstallDefaults()
855: {
856: progressBar.setFont(null);
857: progressBar.setForeground(null);
858: progressBar.setBackground(null);
859:
860: selectionForeground = null;
861: selectionBackground = null;
862: }
863:
864:
868: protected void installListeners()
869: {
870: changeListener = new ChangeHandler();
871: propertyListener = new PropertyChangeHandler();
872: animation = new Animator();
873:
874: progressBar.addChangeListener(changeListener);
875: progressBar.addPropertyChangeListener(propertyListener);
876: animationTimer.addActionListener(animation);
877:
878: ancestorListener = new AncestorHandler();
879: progressBar.addAncestorListener(ancestorListener);
880:
881: componentListener = new ComponentHandler();
882: progressBar.addComponentListener(componentListener);
883: }
884:
885:
889: protected void uninstallListeners()
890: {
891: progressBar.removeChangeListener(changeListener);
892: progressBar.removePropertyChangeListener(propertyListener);
893: animationTimer.removeActionListener(animation);
894:
895: changeListener = null;
896: propertyListener = null;
897: animation = null;
898:
899: if (ancestorListener != null)
900: progressBar.removeAncestorListener(ancestorListener);
901: ancestorListener = null;
902:
903: if (componentListener != null)
904: progressBar.removeComponentListener(componentListener);
905: componentListener = null;
906: }
907:
908:
916: public void installUI(JComponent c)
917: {
918: super.installUI(c);
919: if (c instanceof JProgressBar)
920: {
921: progressBar = (JProgressBar) c;
922:
923: animationTimer = new Timer(200, null);
924: animationTimer.setRepeats(true);
925:
926: installDefaults();
927: installListeners();
928: }
929: if (progressBar.isIndeterminate())
930: startAnimationTimer();
931: }
932:
933:
940: public void uninstallUI(JComponent c)
941: {
942: super.uninstallUI(c);
943: uninstallListeners();
944: uninstallDefaults();
945:
946: animationTimer = null;
947: progressBar = null;
948: }
949:
950: }