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: import ;
58:
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: import ;
72:
73:
77: public class BasicProgressBarUI extends ProgressBarUI
78: {
79:
87: public class ChangeHandler implements ChangeListener
88: {
89:
94: public void stateChanged(ChangeEvent e)
95: {
96:
97: progressBar.repaint();
98: }
99: }
100:
101:
105: private class PropertyChangeHandler implements PropertyChangeListener
106: {
107:
113: public void propertyChange(PropertyChangeEvent e)
114: {
115:
116:
117: if (e.getPropertyName().equals("indeterminate"))
118: if (((Boolean) e.getNewValue()).booleanValue()
119: && progressBar.isShowing())
120: startAnimationTimer();
121: else
122: stopAnimationTimer();
123: }
124: }
125:
126:
132: private class AncestorHandler implements AncestorListener
133: {
134:
135:
141: public void ancestorAdded(AncestorEvent event)
142: {
143: if (progressBar.isIndeterminate())
144: startAnimationTimer();
145: }
146:
147:
153: public void ancestorRemoved(AncestorEvent event)
154: {
155: stopAnimationTimer();
156: }
157:
158:
162: public void ancestorMoved(AncestorEvent event)
163: {
164:
165: }
166:
167: }
168:
169:
174: private class Animator implements ActionListener
175: {
176:
182: public void actionPerformed(ActionEvent e)
183: {
184:
185:
186: incrementAnimationIndex();
187: }
188: }
189:
190:
197: private class ComponentHandler extends ComponentAdapter
198: {
199:
206: public void componentResized(ComponentEvent e)
207: {
208: boxDependent = -1;
209: boxIndependent = -1;
210: incr = -1;
211: }
212: }
213:
214:
219: protected Rectangle boxRect;
220:
221:
222: private transient Timer animationTimer;
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235: private transient int animationIndex;
236:
237:
238: private transient int numFrames;
239:
240:
241: private transient Animator animation;
242:
243:
244: private transient PropertyChangeHandler propertyListener;
245:
246:
247: protected ChangeListener changeListener;
248:
249:
250: protected JProgressBar progressBar;
251:
252:
253:
258: transient double boxDependent = - 1;
259:
260:
265: transient int boxIndependent = - 1;
266:
267:
271: transient double incr = -1;
272:
273:
274: private transient int cellLength;
275:
276:
277: private transient int cellSpacing;
278:
279:
280: private transient Color selectionBackground;
281:
282:
283: private transient Color selectionForeground;
284:
285:
289: private AncestorListener ancestorListener;
290:
291:
295: private ComponentListener componentListener;
296:
297:
300: public BasicProgressBarUI()
301: {
302: super();
303: }
304:
305:
312: public static ComponentUI createUI(JComponent x)
313: {
314: return new BasicProgressBarUI();
315: }
316:
317:
328: protected int getAmountFull(Insets b, int width, int height)
329: {
330: double percentDone = progressBar.getPercentComplete();
331: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
332: return (int) (percentDone * (width - b.left - b.right));
333: else
334: return (int) (percentDone * (height - b.top - b.bottom));
335: }
336:
337:
342: protected int getAnimationIndex()
343: {
344: return animationIndex;
345: }
346:
347:
357: protected Rectangle getBox(Rectangle r)
358: {
359: if (!progressBar.isIndeterminate())
360: return null;
361: if (r == null)
362: r = new Rectangle();
363:
364: Rectangle vr = new Rectangle();
365: SwingUtilities.calculateInnerArea(progressBar, vr);
366:
367:
368: if (incr == -1 || boxDependent == -1 || boxIndependent == -1)
369: {
370:
371: int iterations = numFrames / 2;
372: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
373: {
374: boxDependent = vr.width / 6.;
375: incr = ((double) (vr.width - boxDependent)) / (double) iterations;
376: boxIndependent = vr.height;
377: }
378: else
379: {
380: boxDependent = vr.height / 6.;
381: incr = ((double) (vr.height - boxDependent)) / (double) iterations;
382: boxIndependent = vr.width;
383: }
384: }
385:
386: int index = getAnimationIndex();
387: if (animationIndex > numFrames / 2)
388: index = numFrames - getAnimationIndex();
389:
390: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
391: {
392: r.x = vr.x + (int) (incr * index);
393: r.y = vr.y;
394: r.width = (int) boxDependent;
395: r.height = (int) boxIndependent;
396: }
397: else
398: {
399: r.x = vr.x;
400: r.y = vr.height - (int) (incr * index) + vr.y - (int) boxDependent;
401: r.width = (int) boxIndependent;
402: r.height = (int) boxDependent;
403: }
404: return r;
405: }
406:
407:
412: protected int getCellLength()
413: {
414: return cellLength;
415: }
416:
417:
422: protected int getCellSpacing()
423: {
424: return cellSpacing;
425: }
426:
427:
436: public Dimension getMaximumSize(JComponent c)
437: {
438: Insets insets = c.getInsets();
439: Dimension ret;
440: int orientation = progressBar.getOrientation();
441: if (orientation == JProgressBar.VERTICAL)
442: {
443: ret = getPreferredInnerVertical();
444: ret.height = Short.MAX_VALUE;
445: ret.width += insets.left + insets.right;
446: }
447: else
448: {
449: ret = getPreferredInnerHorizontal();
450: ret.width = Short.MAX_VALUE;
451: ret.height += insets.top + insets.bottom;
452: }
453: return ret;
454: }
455:
456:
465: public Dimension getMinimumSize(JComponent c)
466: {
467: Insets insets = c.getInsets();
468: Dimension ret;
469: int orientation = progressBar.getOrientation();
470: if (orientation == JProgressBar.VERTICAL)
471: {
472: ret = getPreferredInnerVertical();
473: ret.height = 10;
474: ret.width += insets.left + insets.right;
475: }
476: else
477: {
478: ret = getPreferredInnerHorizontal();
479: ret.width = 10;
480: ret.height += insets.top + insets.bottom;
481: }
482: return ret;
483: }
484:
485:
493: protected Dimension getPreferredInnerHorizontal()
494: {
495: Font font = progressBar.getFont();
496: FontMetrics fm = progressBar.getFontMetrics(font);
497:
498: int stringWidth = 0;
499: String str = progressBar.getString();
500: if (str != null)
501: stringWidth = fm.stringWidth(progressBar.getString());
502: Insets i = progressBar.getInsets();
503: int prefWidth = Math.max(200 - i.left - i.right, stringWidth);
504:
505: int stringHeight = 0;
506: if (str != null)
507: stringHeight = fm.getHeight();
508: int prefHeight = Math.max(16 - i.top - i.bottom, stringHeight);
509:
510: return new Dimension(prefWidth, prefHeight);
511: }
512:
513:
521: protected Dimension getPreferredInnerVertical()
522: {
523: Font font = progressBar.getFont();
524: FontMetrics fm = progressBar.getFontMetrics(font);
525:
526: int stringWidth = 0;
527: String str = progressBar.getString();
528: if (str != null)
529: stringWidth = fm.stringWidth(progressBar.getString());
530: Insets i = progressBar.getInsets();
531: int prefHeight = Math.max(200 - i.left - i.right, stringWidth);
532:
533: int stringHeight = 0;
534: if (str != null)
535: stringHeight = fm.getHeight();
536: int prefWidth = Math.max(16 - i.top - i.bottom, stringHeight);
537:
538: return new Dimension(prefWidth, prefHeight);
539: }
540:
541:
550: public Dimension getPreferredSize(JComponent c)
551: {
552: Insets insets = c.getInsets();
553: Dimension ret;
554: int orientation = progressBar.getOrientation();
555: if (orientation == JProgressBar.VERTICAL)
556: ret = getPreferredInnerVertical();
557: else
558: ret = getPreferredInnerHorizontal();
559: ret.width += insets.left + insets.right;
560: ret.height += insets.top + insets.bottom;
561: return ret;
562: }
563:
564:
570: protected Color getSelectionBackground()
571: {
572: return selectionBackground;
573: }
574:
575:
581: protected Color getSelectionForeground()
582: {
583: return selectionForeground;
584: }
585:
586:
599: protected Point getStringPlacement(Graphics g, String progressString, int x,
600: int y, int width, int height)
601: {
602: Rectangle tr = new Rectangle();
603: Rectangle vr = new Rectangle();
604: Rectangle ir = new Rectangle();
605:
606: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
607: vr.setBounds(x, y, width, height);
608: else
609: vr.setBounds(y, x, height, width);
610:
611: Font f = g.getFont();
612: FontMetrics fm = g.getFontMetrics(f);
613:
614: SwingUtilities.layoutCompoundLabel(progressBar, fm, progressString, null,
615: SwingConstants.CENTER,
616: SwingConstants.CENTER,
617: SwingConstants.CENTER,
618: SwingConstants.CENTER, vr, ir, tr, 0);
619:
620: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
621: return new Point(tr.x, tr.y);
622: else
623: return new Point(tr.y, tr.x);
624: }
625:
626:
629: protected void incrementAnimationIndex()
630: {
631: animationIndex++;
632:
633: if (animationIndex >= numFrames)
634: animationIndex = 0;
635: progressBar.repaint();
636: }
637:
638:
645: public void paint(Graphics g, JComponent c)
646: {
647: if (! progressBar.isIndeterminate())
648: paintDeterminate(g, c);
649: else
650: paintIndeterminate(g, c);
651: }
652:
653:
660: protected void paintDeterminate(Graphics g, JComponent c)
661: {
662: Color saved = g.getColor();
663: int space = getCellSpacing();
664: int len = getCellLength();
665: int max = progressBar.getMaximum();
666: int min = progressBar.getMinimum();
667: int value = progressBar.getValue();
668:
669: Rectangle vr = SwingUtilities.calculateInnerArea(c, new Rectangle());
670: Rectangle or = progressBar.getBounds();
671: Insets insets = c.getInsets();
672:
673: int amountFull = getAmountFull(insets, or.width, or.height);
674:
675: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
676: {
677: g.setColor(c.getForeground());
678: g.fillRect(vr.x, vr.y, amountFull, vr.height);
679: }
680: else
681: {
682: g.setColor(c.getForeground());
683: g.fillRect(vr.x, vr.y + vr.height - amountFull, vr.width,
684: amountFull);
685: }
686:
687: if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
688: paintString(g, 0, 0, or.width, or.height, amountFull, insets);
689: g.setColor(saved);
690: }
691:
692:
699: protected void paintIndeterminate(Graphics g, JComponent c)
700: {
701:
702:
703: Color saved = g.getColor();
704: Insets insets = c.getInsets();
705:
706: Rectangle or = c.getBounds();
707: Rectangle vr = new Rectangle();
708: SwingUtilities.calculateInnerArea(c, vr);
709:
710: g.setColor(c.getBackground());
711: g.fillRect(vr.x, vr.y, vr.width, vr.height);
712:
713: boxRect = getBox(boxRect);
714:
715: g.setColor(c.getForeground());
716: g.fillRect(boxRect.x, boxRect.y, boxRect.width, boxRect.height);
717:
718: if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
719: paintString(g, 0, 0, or.width, or.height,
720: getAmountFull(insets, or.width, or.height), insets);
721:
722: g.setColor(saved);
723: }
724:
725:
736: protected void paintString(Graphics g, int x, int y, int width, int height,
737: int amountFull, Insets b)
738: {
739: String str = progressBar.getString();
740: int full = getAmountFull(b, width, height);
741: Point placement = getStringPlacement(g, progressBar.getString(),
742: x + b.left, y + b.top,
743: width - b.left - b.right,
744: height - b.top - b.bottom);
745: Color savedColor = g.getColor();
746: Shape savedClip = g.getClip();
747: FontMetrics fm = g.getFontMetrics(progressBar.getFont());
748:
749: if (progressBar.getOrientation() == JProgressBar.VERTICAL)
750: {
751: AffineTransform rotate = AffineTransform.getRotateInstance(Math.PI / 2);
752: g.setFont(progressBar.getFont().deriveFont(rotate));
753: placement.x = width - placement.x - fm.getAscent();
754: }
755: else
756: {
757: placement.y += fm.getAscent();
758: }
759:
760: g.setColor(getSelectionForeground());
761: g.setClip(0, 0, full + b.left, height);
762: g.drawString(str, placement.x, placement.y);
763: g.setColor(getSelectionBackground());
764: g.setClip(full + b.left, 0, width - full, height);
765: g.drawString(str, placement.x, placement.y);
766: g.setClip(savedClip);
767: g.setColor(savedColor);
768: }
769:
770:
776: protected void setAnimationIndex(int newValue)
777: {
778: animationIndex = (newValue <= numFrames) ? newValue : 0;
779: progressBar.repaint();
780: }
781:
782:
787: protected void setCellLength(int cellLen)
788: {
789: cellLength = cellLen;
790: }
791:
792:
797: protected void setCellSpacing(int cellSpace)
798: {
799: cellSpacing = cellSpace;
800: }
801:
802:
809: protected void startAnimationTimer()
810: {
811: if (animationTimer != null)
812: animationTimer.start();
813: }
814:
815:
822: protected void stopAnimationTimer()
823: {
824: if (animationTimer != null)
825: animationTimer.stop();
826: setAnimationIndex(0);
827: }
828:
829:
833: protected void installDefaults()
834: {
835: LookAndFeel.installColorsAndFont(progressBar, "ProgressBar.background",
836: "ProgressBar.foreground",
837: "ProgressBar.font");
838: LookAndFeel.installBorder(progressBar, "ProgressBar.border");
839: progressBar.setOpaque(true);
840:
841: selectionForeground = UIManager.getColor("ProgressBar.selectionForeground");
842: selectionBackground = UIManager.getColor("ProgressBar.selectionBackground");
843: cellLength = UIManager.getInt("ProgressBar.cellLength");
844: cellSpacing = UIManager.getInt("ProgressBar.cellSpacing");
845:
846: int repaintInterval = UIManager.getInt("ProgressBar.repaintInterval");
847: int cycleTime = UIManager.getInt("ProgressBar.cycleTime");
848:
849: if (cycleTime % repaintInterval != 0
850: && (cycleTime / repaintInterval) % 2 != 0)
851: {
852: int div = (cycleTime / repaintInterval) + 2;
853: div /= 2;
854: div *= 2;
855: cycleTime = div * repaintInterval;
856: }
857: setAnimationIndex(0);
858: numFrames = cycleTime / repaintInterval;
859: animationTimer.setDelay(repaintInterval);
860: }
861:
862:
866: protected void uninstallDefaults()
867: {
868: progressBar.setFont(null);
869: progressBar.setForeground(null);
870: progressBar.setBackground(null);
871:
872: selectionForeground = null;
873: selectionBackground = null;
874: }
875:
876:
880: protected void installListeners()
881: {
882: changeListener = new ChangeHandler();
883: propertyListener = new PropertyChangeHandler();
884: animation = new Animator();
885:
886: progressBar.addChangeListener(changeListener);
887: progressBar.addPropertyChangeListener(propertyListener);
888: animationTimer.addActionListener(animation);
889:
890: ancestorListener = new AncestorHandler();
891: progressBar.addAncestorListener(ancestorListener);
892:
893: componentListener = new ComponentHandler();
894: progressBar.addComponentListener(componentListener);
895: }
896:
897:
901: protected void uninstallListeners()
902: {
903: progressBar.removeChangeListener(changeListener);
904: progressBar.removePropertyChangeListener(propertyListener);
905: animationTimer.removeActionListener(animation);
906:
907: changeListener = null;
908: propertyListener = null;
909: animation = null;
910:
911: if (ancestorListener != null)
912: progressBar.removeAncestorListener(ancestorListener);
913: ancestorListener = null;
914:
915: if (componentListener != null)
916: progressBar.removeComponentListener(componentListener);
917: componentListener = null;
918: }
919:
920:
928: public void installUI(JComponent c)
929: {
930: super.installUI(c);
931: if (c instanceof JProgressBar)
932: {
933: progressBar = (JProgressBar) c;
934:
935: animationTimer = new Timer(200, null);
936: animationTimer.setRepeats(true);
937:
938: installDefaults();
939: installListeners();
940: }
941: if (progressBar.isIndeterminate())
942: startAnimationTimer();
943: }
944:
945:
952: public void uninstallUI(JComponent c)
953: {
954: super.uninstallUI(c);
955: uninstallListeners();
956: uninstallDefaults();
957:
958: animationTimer = null;
959: progressBar = null;
960: }
961:
962: }