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:
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68:
69:
73: public class BasicProgressBarUI extends ProgressBarUI
74: {
75:
83: public class ChangeHandler implements ChangeListener
84: {
85:
90: public void stateChanged(ChangeEvent e)
91: {
92:
93: progressBar.repaint();
94: }
95: }
96:
97:
101: private class PropertyChangeHandler implements PropertyChangeListener
102: {
103:
109: public void propertyChange(PropertyChangeEvent e)
110: {
111:
112:
113: if (e.getPropertyName().equals("inderterminate"))
114: if (((Boolean) e.getNewValue()).booleanValue())
115: startAnimationTimer();
116: else
117: stopAnimationTimer();
118: else
119: progressBar.repaint();
120: }
121: }
122:
123:
128: private class Animator implements ActionListener
129: {
130:
136: public void actionPerformed(ActionEvent e)
137: {
138:
139:
140: incrementAnimationIndex();
141: }
142: }
143:
144:
145: private transient Timer animationTimer;
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158: private transient int animationIndex;
159:
160:
161: private transient int numFrames;
162:
163:
164: private transient Animator animation;
165:
166:
167: private transient PropertyChangeHandler propertyListener;
168:
169:
170: protected ChangeListener changeListener;
171:
172:
173: protected JProgressBar progressBar;
174:
175:
176: private transient int cellLength;
177:
178:
179: private transient int cellSpacing;
180:
181:
182: private transient Color selectionBackground;
183:
184:
185: private transient Color selectionForeground;
186:
187:
190: public BasicProgressBarUI()
191: {
192: super();
193: }
194:
195:
202: public static ComponentUI createUI(JComponent x)
203: {
204: return new BasicProgressBarUI();
205: }
206:
207:
218: protected int getAmountFull(Insets b, int width, int height)
219: {
220: double percentDone = progressBar.getPercentComplete();
221: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
222: return (int) (percentDone * (width - b.left - b.right));
223: else
224: return (int) (percentDone * (height - b.top - b.bottom));
225: }
226:
227:
232: protected int getAnimationIndex()
233: {
234: return animationIndex;
235: }
236:
237:
247: protected Rectangle getBox(Rectangle r)
248: {
249: if (!progressBar.isIndeterminate())
250: return null;
251:
252: int iterations = numFrames / 2 + 1;
253:
254: double boxDependent;
255: double boxIndependent;
256:
257: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
258: {
259: Dimension dims = getPreferredInnerHorizontal();
260: boxDependent = (double) dims.width / iterations;
261: boxIndependent = dims.height;
262: }
263: else
264: {
265: Dimension dims = getPreferredInnerVertical();
266: boxDependent = (double) dims.height / iterations;
267: boxIndependent = dims.width;
268: }
269:
270: Rectangle vr = new Rectangle();
271: SwingUtilities.calculateInnerArea(progressBar, vr);
272:
273: int index = getAnimationIndex();
274: if (animationIndex > (numFrames + 1) / 2)
275: index = numFrames - getAnimationIndex();
276:
277: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
278: {
279: r.x = vr.x + (int) (index * boxDependent);
280: r.y = vr.y;
281: r.width = (int) boxDependent;
282: r.height = (int) boxIndependent;
283: }
284: else
285: {
286: index++;
287: r.x = vr.x;
288: r.y = vr.height - (int) (index * boxDependent) + vr.y;
289: r.width = (int) boxIndependent;
290: r.height = (int) boxDependent;
291: }
292:
293: return r;
294: }
295:
296:
301: protected int getCellLength()
302: {
303: return cellLength;
304: }
305:
306:
311: protected int getCellSpacing()
312: {
313: return cellSpacing;
314: }
315:
316:
325: public Dimension getMaximumSize(JComponent c)
326: {
327: return getPreferredSize(c);
328: }
329:
330:
339: public Dimension getMinimumSize(JComponent c)
340: {
341: return getPreferredSize(c);
342: }
343:
344:
352: protected Dimension getPreferredInnerHorizontal()
353: {
354: Rectangle vr = new Rectangle();
355:
356: SwingUtilities.calculateInnerArea(progressBar, vr);
357:
358: return new Dimension(vr.width, vr.height);
359: }
360:
361:
369: protected Dimension getPreferredInnerVertical()
370: {
371: Rectangle vr = new Rectangle();
372:
373: SwingUtilities.calculateInnerArea(progressBar, vr);
374:
375: return new Dimension(vr.width, vr.height);
376: }
377:
378:
387: public Dimension getPreferredSize(JComponent c)
388: {
389:
390:
391: Insets insets = c.getInsets();
392:
393:
394:
395: FontRenderContext ctx = new FontRenderContext(new AffineTransform(),
396: false, false);
397: Rectangle2D bounds = c.getFont().getStringBounds(progressBar.getString(),
398: ctx);
399: int textW = (int) bounds.getWidth();
400: int textH = (int) bounds.getHeight();
401:
402: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
403: {
404: if (textH < 20)
405: textH = 20;
406: if (textW < 200)
407: textW = 200;
408: }
409: else
410: {
411: if (textH < 200)
412: textH = 200;
413: if (textW < 20)
414: textW = 20;
415: }
416: textW += insets.left + insets.right;
417: textH += insets.top + insets.bottom;
418: return new Dimension(textW, textH);
419: }
420:
421:
427: protected Color getSelectionBackground()
428: {
429: return selectionBackground;
430: }
431:
432:
438: protected Color getSelectionForeground()
439: {
440: return selectionForeground;
441: }
442:
443:
456: protected Point getStringPlacement(Graphics g, String progressString, int x,
457: int y, int width, int height)
458: {
459: Rectangle tr = new Rectangle();
460: Rectangle vr = new Rectangle(x, y, width, height);
461: Rectangle ir = new Rectangle();
462:
463: Font f = g.getFont();
464: FontMetrics fm = g.getFontMetrics(f);
465:
466: SwingUtilities.layoutCompoundLabel(progressBar, fm, progressString, null,
467: SwingConstants.CENTER,
468: SwingConstants.CENTER,
469: SwingConstants.CENTER,
470: SwingConstants.CENTER, vr, ir, tr, 0);
471: return new Point(tr.x, tr.y);
472: }
473:
474:
477: protected void incrementAnimationIndex()
478: {
479: animationIndex++;
480:
481: if (animationIndex >= numFrames)
482: animationIndex = 0;
483: progressBar.repaint();
484: }
485:
486:
493: public void paint(Graphics g, JComponent c)
494: {
495: if (! progressBar.isIndeterminate())
496: paintDeterminate(g, c);
497: else
498: paintIndeterminate(g, c);
499: }
500:
501:
508: protected void paintDeterminate(Graphics g, JComponent c)
509: {
510: Color saved = g.getColor();
511: int space = getCellSpacing();
512: int len = getCellLength();
513: int max = progressBar.getMaximum();
514: int min = progressBar.getMinimum();
515: int value = progressBar.getValue();
516:
517: Rectangle vr = new Rectangle();
518: SwingUtilities.calculateInnerArea(c, vr);
519:
520: Rectangle or = c.getBounds();
521:
522: Insets insets = c.getInsets();
523:
524: int amountFull = getAmountFull(insets, or.width, or.height);
525:
526: g.setColor(c.getBackground());
527: g.fill3DRect(vr.x, vr.y, vr.width, vr.height, false);
528:
529: if (max != min && len != 0 && value > min)
530: {
531: int iterations = value / (space + len);
532:
533: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
534: {
535: double spaceInUnits = space * (double) vr.width / (max - min);
536: double lenInUnits = len * (double) vr.width / (max - min);
537: double currX = vr.x;
538:
539: g.setColor(c.getForeground());
540: g.fill3DRect(vr.x, vr.y, amountFull, vr.height, true);
541:
542: g.setColor(c.getBackground());
543: if (spaceInUnits != 0)
544: {
545: for (int i = 0; i < iterations; i++)
546: {
547: currX += lenInUnits;
548: g.fill3DRect((int) currX, vr.y, (int) spaceInUnits,
549: vr.height, true);
550: currX += spaceInUnits;
551: }
552: }
553: }
554: else
555: {
556: double currY = vr.y;
557: double spaceInUnits = space * (double) vr.height / (max - min);
558: double lenInUnits = len * (double) vr.height / (max - min);
559:
560: g.setColor(c.getForeground());
561: g.fill3DRect(vr.x, vr.y + vr.height - amountFull, vr.width,
562: amountFull, true);
563:
564: g.setColor(c.getBackground());
565:
566: if (spaceInUnits != 0)
567: {
568: for (int i = 0; i < iterations; i++)
569: {
570: currY -= lenInUnits + spaceInUnits;
571: g.fill3DRect(vr.x, (int) currY, vr.width,
572: (int) spaceInUnits, true);
573: }
574: }
575: }
576: }
577:
578: if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
579: paintString(g, 0, 0, or.width, or.height, amountFull, insets);
580: g.setColor(saved);
581: }
582:
583:
590: protected void paintIndeterminate(Graphics g, JComponent c)
591: {
592:
593:
594: Color saved = g.getColor();
595: Insets insets = c.getInsets();
596:
597: Rectangle or = c.getBounds();
598: Rectangle vr = new Rectangle();
599: SwingUtilities.calculateInnerArea(c, vr);
600:
601: g.setColor(c.getBackground());
602: g.fill3DRect(vr.x, vr.y, vr.width, vr.height, false);
603:
604: Rectangle box = new Rectangle();
605: getBox(box);
606:
607: g.setColor(c.getForeground());
608: g.fill3DRect(box.x, box.y, box.width, box.height, true);
609:
610: if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
611: paintString(g, 0, 0, or.width, or.height,
612: getAmountFull(insets, or.width, or.height), insets);
613:
614: g.setColor(saved);
615: }
616:
617:
628: protected void paintString(Graphics g, int x, int y, int width, int height,
629: int amountFull, Insets b)
630: {
631:
632: Point placement = getStringPlacement(g, progressBar.getString(),
633: x + b.left, y + b.top,
634: width - b.left - b.right,
635: height - b.top - b.bottom);
636: Color saved = g.getColor();
637:
638:
639:
640: g.setColor(Color.WHITE);
641:
642: FontMetrics fm = g.getFontMetrics(progressBar.getFont());
643:
644: g.drawString(progressBar.getString(), placement.x,
645: placement.y + fm.getAscent());
646:
647: g.setColor(saved);
648: }
649:
650:
656: protected void setAnimationIndex(int newValue)
657: {
658: animationIndex = (newValue <= numFrames) ? newValue : 0;
659: progressBar.repaint();
660: }
661:
662:
667: protected void setCellLength(int cellLen)
668: {
669: cellLength = cellLen;
670: }
671:
672:
677: protected void setCellSpacing(int cellSpace)
678: {
679: cellSpacing = cellSpace;
680: }
681:
682:
689: protected void startAnimationTimer()
690: {
691: if (animationTimer != null)
692: animationTimer.start();
693: }
694:
695:
702: protected void stopAnimationTimer()
703: {
704: if (animationTimer != null)
705: animationTimer.stop();
706: setAnimationIndex(0);
707: }
708:
709:
713: protected void installDefaults()
714: {
715: LookAndFeel.installColorsAndFont(progressBar, "ProgressBar.background",
716: "ProgressBar.foreground",
717: "ProgressBar.font");
718: LookAndFeel.installBorder(progressBar, "ProgressBar.border");
719: progressBar.setOpaque(true);
720:
721: selectionForeground = UIManager.getColor("ProgressBar.selectionForeground");
722: selectionBackground = UIManager.getColor("ProgressBar.selectionBackground");
723: cellLength = UIManager.getInt("ProgressBar.cellLength");
724: cellSpacing = UIManager.getInt("ProgressBar.cellSpacing");
725:
726: int repaintInterval = UIManager.getInt("ProgressBar.repaintInterval");
727: int cycleTime = UIManager.getInt("ProgressBar.cycleTime");
728:
729: if (cycleTime % repaintInterval != 0
730: && (cycleTime / repaintInterval) % 2 != 0)
731: {
732: int div = (cycleTime / repaintInterval) + 2;
733: div /= 2;
734: div *= 2;
735: cycleTime = div * repaintInterval;
736: }
737: setAnimationIndex(0);
738: numFrames = cycleTime / repaintInterval;
739: animationTimer.setDelay(repaintInterval);
740: }
741:
742:
746: protected void uninstallDefaults()
747: {
748: progressBar.setFont(null);
749: progressBar.setForeground(null);
750: progressBar.setBackground(null);
751:
752: selectionForeground = null;
753: selectionBackground = null;
754: }
755:
756:
760: protected void installListeners()
761: {
762: changeListener = new ChangeHandler();
763: propertyListener = new PropertyChangeHandler();
764: animation = new Animator();
765:
766: progressBar.addChangeListener(changeListener);
767: progressBar.addPropertyChangeListener(propertyListener);
768: animationTimer.addActionListener(animation);
769: }
770:
771:
775: protected void uninstallListeners()
776: {
777: progressBar.removeChangeListener(changeListener);
778: progressBar.removePropertyChangeListener(propertyListener);
779: animationTimer.removeActionListener(animation);
780:
781: changeListener = null;
782: propertyListener = null;
783: animation = null;
784: }
785:
786:
794: public void installUI(JComponent c)
795: {
796: super.installUI(c);
797: if (c instanceof JProgressBar)
798: {
799: progressBar = (JProgressBar) c;
800:
801: animationTimer = new Timer(200, null);
802: animationTimer.setRepeats(true);
803:
804: installDefaults();
805: installListeners();
806: }
807: }
808:
809:
816: public void uninstallUI(JComponent c)
817: {
818: super.uninstallUI(c);
819: uninstallListeners();
820: uninstallDefaults();
821:
822: animationTimer = null;
823: progressBar = null;
824: }
825: }