001: /*
002: * Copyright (c) 2005-2008 Substance Kirill Grouchnikov. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of Substance Kirill Grouchnikov nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030: package org.jvnet.substance;
031:
032: import java.awt.*;
033: import java.awt.image.BufferedImage;
034: import java.util.HashMap;
035: import java.util.Map;
036:
037: import javax.swing.*;
038: import javax.swing.event.ChangeEvent;
039: import javax.swing.event.ChangeListener;
040: import javax.swing.plaf.ComponentUI;
041: import javax.swing.plaf.basic.BasicProgressBarUI;
042:
043: import org.jvnet.lafwidget.animation.FadeKind;
044: import org.jvnet.lafwidget.animation.FadeTracker;
045: import org.jvnet.lafwidget.layout.TransitionLayout;
046: import org.jvnet.substance.border.InnerDelegateBorderPainter;
047: import org.jvnet.substance.border.SubstanceBorderPainter;
048: import org.jvnet.substance.button.BaseButtonShaper;
049: import org.jvnet.substance.color.ColorScheme;
050: import org.jvnet.substance.painter.SubstanceGradientPainter;
051: import org.jvnet.substance.painter.text.SubstanceTextPainter;
052: import org.jvnet.substance.theme.SubstanceTheme;
053: import org.jvnet.substance.utils.*;
054:
055: /**
056: * UI for progress bars in <b>Substance</b> look and feel.
057: *
058: * @author Kirill Grouchnikov
059: */
060: public class SubstanceProgressBarUI extends BasicProgressBarUI {
061: /**
062: * Hash for computed stripe images.
063: */
064: private static Map<String, BufferedImage> stripeMap = new HashMap<String, BufferedImage>();
065:
066: /**
067: * Resets image maps (used when setting new theme).
068: *
069: * @see SubstanceLookAndFeel#setCurrentTheme(String)
070: * @see SubstanceLookAndFeel#setCurrentTheme(SubstanceTheme)
071: */
072: public static synchronized void reset() {
073: SubstanceProgressBarUI.stripeMap.clear();
074: }
075:
076: /**
077: * The current state of the indeterminate animation's cycle. 0, the initial
078: * value, means paint the first frame. When the progress bar is
079: * indeterminate and showing, the default animation thread updates this
080: * variable by invoking incrementAnimationIndex() every repaintInterval
081: * milliseconds.
082: */
083: private float animationIndex;
084:
085: /**
086: * Value change listener on the associated progress bar.
087: */
088: protected ChangeListener substanceValueChangeListener;
089:
090: /**
091: * The speed factor for the indeterminate progress bars.
092: */
093: protected float speed;
094:
095: /**
096: * Fade kind for the progress bar value change.
097: */
098: public static final FadeKind PROGRESS_BAR_VALUE_CHANGED = new FadeKind(
099: "substancelaf.progressBarValueChanged");
100:
101: // static {
102: // FadeConfigurationManager.getInstance().allowFades(PROGRESS_BAR_VALUE_CHANGED);
103: // }
104:
105: /**
106: * Property name for storing the <code>from</code> value on progress bar
107: * value animation. Is for internal use only.
108: */
109: private static final String PROGRESS_BAR_FROM = "substancelaf.internal.from";
110:
111: /**
112: * Property name for storing the <code>to</code> value on progress bar
113: * value animation. Is for internal use only.
114: */
115: private static final String PROGRESS_BAR_TO = "substancelaf.internal.to";
116:
117: /*
118: * (non-Javadoc)
119: *
120: * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
121: */
122: public static ComponentUI createUI(JComponent c) {
123: return new SubstanceProgressBarUI();
124: }
125:
126: @Override
127: protected void installDefaults() {
128: super .installDefaults();
129:
130: progressBar.putClientProperty(PROGRESS_BAR_TO, progressBar
131: .getValue());
132: LookAndFeel.installProperty(progressBar, "opaque",
133: Boolean.FALSE);
134:
135: this .speed = (20.0f * UIManager
136: .getInt("ProgressBar.repaintInterval"))
137: / UIManager.getInt("ProgressBar.cycleTime");
138: }
139:
140: @Override
141: protected void installListeners() {
142: super .installListeners();
143:
144: final BoundedRangeModel model = progressBar.getModel();
145: if (model instanceof DefaultBoundedRangeModel) {
146: substanceValueChangeListener = new ChangeListener() {
147: public void stateChanged(ChangeEvent e) {
148: int oldValue = (Integer) progressBar
149: .getClientProperty(PROGRESS_BAR_TO);
150: int currValue = model.getValue();
151: int span = model.getMaximum() - model.getMinimum();
152: Insets b = progressBar.getInsets(); // area for border
153: int barRectWidth = progressBar.getWidth()
154: - (b.right + b.left);
155: int barRectHeight = progressBar.getHeight()
156: - (b.top + b.bottom);
157: int totalPixels = (progressBar.getOrientation() == JProgressBar.HORIZONTAL) ? barRectWidth
158: : barRectHeight;
159: // fix for defect 223 (min and max on the model are the
160: // same).
161: int pixelDelta = (span <= 0) ? 0
162: : (currValue - oldValue) * totalPixels
163: / span;
164:
165: FadeTracker fadeTracker = FadeTracker.getInstance();
166: if (!fadeTracker.isTracked(progressBar,
167: PROGRESS_BAR_VALUE_CHANGED)) {
168: progressBar
169: .putClientProperty(
170: PROGRESS_BAR_FROM,
171: progressBar
172: .getClientProperty(PROGRESS_BAR_TO));
173: }
174: progressBar.putClientProperty(PROGRESS_BAR_TO,
175: progressBar.getValue());
176: if (Math.abs(pixelDelta) > 5) {
177: FadeTracker.getInstance().trackFadeIn(
178: PROGRESS_BAR_VALUE_CHANGED,
179: progressBar, false, null);
180: }
181: }
182: };
183: ((DefaultBoundedRangeModel) model)
184: .addChangeListener(substanceValueChangeListener);
185: }
186: }
187:
188: @Override
189: protected void uninstallListeners() {
190: BoundedRangeModel model = progressBar.getModel();
191: if (model instanceof DefaultBoundedRangeModel) {
192: ((DefaultBoundedRangeModel) model)
193: .removeChangeListener(substanceValueChangeListener);
194: }
195:
196: super .uninstallListeners();
197: }
198:
199: /**
200: * Retrieves stripe image.
201: *
202: * @param baseSize
203: * Stripe base in pixels.
204: * @param isRotated
205: * if <code>true</code>, the resulting stripe image will be
206: * rotated.
207: * @param colorScheme
208: * Color scheme to paint the stripe image.
209: * @return Stripe image.
210: */
211: private static synchronized BufferedImage getStripe(int baseSize,
212: boolean isRotated, ColorScheme colorScheme) {
213: String key = "" + baseSize + ":" + isRotated + ":"
214: + SubstanceCoreUtilities.getSchemeId(colorScheme);
215: BufferedImage result = SubstanceProgressBarUI.stripeMap
216: .get(key);
217: if (result == null) {
218: result = SubstanceImageCreator.getStripe(baseSize,
219: colorScheme.getUltraLightColor());
220: if (isRotated) {
221: result = SubstanceImageCreator.getRotated(result, 1);
222: }
223: SubstanceProgressBarUI.stripeMap.put(key, result);
224: }
225: return result;
226: }
227:
228: /*
229: * (non-Javadoc)
230: *
231: * @see javax.swing.plaf.basic.BasicProgressBarUI#paintDeterminate(java.awt.Graphics,
232: * javax.swing.JComponent)
233: */
234: @Override
235: public void paintDeterminate(Graphics g, JComponent c) {
236: if (!(g instanceof Graphics2D)) {
237: return;
238: }
239:
240: final Insets insets = progressBar.getInsets();
241: insets.top /= 2;
242: insets.left /= 2;
243: insets.bottom /= 2;
244: insets.right /= 2;
245: final int barRectWidth = progressBar.getWidth()
246: - (insets.right + insets.left);
247: final int barRectHeight = progressBar.getHeight()
248: - (insets.top + insets.bottom);
249:
250: // amount of progress to draw
251: final int amountFull = getAmountFull(insets, barRectWidth,
252: barRectHeight);
253:
254: SubstanceTextPainter.BackgroundPaintingCallback callback = new SubstanceTextPainter.BackgroundPaintingCallback() {
255: public void paintBackground(Graphics g) {
256: Graphics2D graphics = (Graphics2D) g.create();
257:
258: SubstanceTheme bgTheme = SubstanceThemeUtilities
259: .getTheme(progressBar);
260: if (progressBar.isEnabled())
261: bgTheme = bgTheme.getDefaultTheme();
262: else
263: bgTheme = bgTheme.getDisabledTheme();
264:
265: SubstanceGradientPainter gp = SubstanceCoreUtilities
266: .getGradientPainter(progressBar);
267: // background
268: if (progressBar.getOrientation() == SwingConstants.HORIZONTAL) {
269: Shape contour = BaseButtonShaper.getBaseOutline(
270: barRectWidth + 1, barRectHeight + 1, 0,
271: null);
272: BufferedImage bg = gp.getContourBackground(
273: barRectWidth + 1, barRectHeight + 1,
274: contour, false, bgTheme.getColorScheme(),
275: bgTheme.getColorScheme(), 0, true, false);
276: graphics.drawImage(bg, insets.left, insets.top,
277: null);
278: } else { // VERTICAL
279: Shape contour = BaseButtonShaper.getBaseOutline(
280: barRectHeight + 1, barRectWidth + 1, 0,
281: null);
282: BufferedImage bg = gp.getContourBackground(
283: barRectHeight + 1, barRectWidth + 1,
284: contour, false, bgTheme.getColorScheme(),
285: bgTheme.getColorScheme(), 0, true, false);
286: graphics.drawImage(SubstanceImageCreator
287: .getRotated(bg, 3), insets.left,
288: insets.top, null);
289: }
290:
291: if (amountFull > 0) {
292: float borderStrokeWidth = SubstanceSizeUtils
293: .getBorderStrokeWidth(SubstanceSizeUtils
294: .getComponentFontSize(progressBar));
295: SubstanceBorderPainter borderPainter = SubstanceCoreUtilities
296: .getBorderPainter(null);
297: int borderDelta = (borderPainter instanceof InnerDelegateBorderPainter) ? (int) (Math
298: .ceil(2.0 * borderStrokeWidth)) / 2
299: : (int) (borderStrokeWidth / 2.0);
300:
301: ColorScheme fillColorScheme = SubstanceThemeUtilities
302: .getTheme(
303: progressBar,
304: progressBar.isEnabled() ? ComponentState.SELECTED
305: : ComponentState.DISABLED_UNSELECTED)
306: .getColorScheme();
307: if (progressBar.getOrientation() == SwingConstants.HORIZONTAL) {
308: int barWidth = amountFull - 2 * borderDelta;
309: int barHeight = barRectHeight - 2 * borderDelta;
310: if ((barWidth > 0) && (barHeight > 0)) {
311: if (progressBar.getComponentOrientation()
312: .isLeftToRight()) {
313: SubstanceImageCreator
314: .paintRectangularBackground(g,
315: insets.left
316: + borderDelta,
317: insets.top
318: + borderDelta,
319: barWidth, barHeight,
320: fillColorScheme, 0.6f,
321: false);
322: } else {
323: // fix for RTL determinate horizontal progress
324: // bar in 2.3
325: SubstanceImageCreator
326: .paintRectangularBackground(g,
327: insets.left
328: + barRectWidth
329: - amountFull
330: - 2
331: * borderDelta,
332: insets.top
333: + borderDelta,
334: barWidth, barHeight,
335: fillColorScheme, 0.6f,
336: false);
337: }
338: }
339: } else { // VERTICAL
340: int barWidth = progressBar.getHeight()
341: - insets.bottom - amountFull - 2
342: * borderDelta;
343: int barHeight = barRectWidth - 2 * borderDelta;
344: if ((barWidth > 0) && (barHeight > 0)) {
345: // fix for issue 95. Vertical bar is growing from
346: // the bottom
347: SubstanceImageCreator
348: .paintRectangularBackground(g,
349: insets.left + borderDelta,
350: barWidth + borderDelta,
351: barHeight, amountFull,
352: fillColorScheme, 0.6f, true);
353: }
354: }
355: }
356: graphics.dispose();
357: }
358: };
359:
360: Graphics2D g2d = (Graphics2D) g.create();
361: // install state-aware alpha channel (support for skins
362: // that use translucency on disabled states).
363: float themeAlpha = SubstanceThemeUtilities
364: .getTheme(progressBar)
365: .getThemeAlpha(
366: progressBar,
367: progressBar.isEnabled() ? ComponentState.DEFAULT
368: : ComponentState.DISABLED_UNSELECTED);
369: g2d.setComposite(TransitionLayout.getAlphaComposite(
370: progressBar, themeAlpha, g));
371:
372: SubstanceTextPainter textPainter = SubstanceLookAndFeel
373: .getCurrentTextPainter();
374: textPainter.init(this .progressBar, null, true);
375: textPainter.setBackgroundFill(progressBar, progressBar
376: .getParent().getBackground(), true, 0, 0);
377:
378: if (textPainter.needsBackgroundImage()) {
379: textPainter.attachCallback(callback);
380: } else {
381: callback.paintBackground(g2d);
382: }
383:
384: // Deal with possible text painting
385: if (progressBar.isStringPainted()) {
386: this .paintString(g2d, insets.left, insets.top,
387: barRectWidth, barRectHeight, amountFull, insets);
388: }
389: textPainter.renderSurface(g2d);
390: g2d.dispose();
391: }
392:
393: /*
394: * (non-Javadoc)
395: *
396: * @see javax.swing.plaf.basic.BasicProgressBarUI#getSelectionBackground()
397: */
398: @Override
399: protected Color getSelectionBackground() {
400: ComponentState state = this .progressBar.isEnabled() ? ComponentState.DEFAULT
401: : ComponentState.DISABLED_UNSELECTED;
402: SubstanceTheme theme = SubstanceThemeUtilities.getTheme(
403: this .progressBar, state);
404: return theme.getForegroundColor();
405: // SubstanceTheme bgTheme = SubstanceCoreUtilities.getTheme(progressBar,
406: // true, true);
407: // if (progressBar.isEnabled())
408: // bgTheme = bgTheme.getDefaultTheme();
409: // else
410: // bgTheme = bgTheme.getDisabledTheme();
411: // return bgTheme.getForegroundColor();
412: }
413:
414: /*
415: * (non-Javadoc)
416: *
417: * @see javax.swing.plaf.basic.BasicProgressBarUI#getSelectionForeground()
418: */
419: @Override
420: protected Color getSelectionForeground() {
421: ComponentState state = this .progressBar.isEnabled() ? ComponentState.ACTIVE
422: : ComponentState.DISABLED_UNSELECTED;
423: SubstanceTheme theme = SubstanceThemeUtilities.getTheme(
424: this .progressBar, state);
425: return theme.getForegroundColor();
426: // ColorScheme fillColorScheme = progressBar.isEnabled() ?
427: // SubstanceCoreUtilities
428: // .getActiveScheme(progressBar)
429: // : SubstanceCoreUtilities.getDefaultScheme(progressBar);
430: // return fillColorScheme.getForegroundColor();
431: }
432:
433: /*
434: * (non-Javadoc)
435: *
436: * @see javax.swing.plaf.basic.BasicProgressBarUI#paintIndeterminate(java.awt.Graphics,
437: * javax.swing.JComponent)
438: */
439: @Override
440: public void paintIndeterminate(Graphics g, JComponent c) {
441: if (!(g instanceof Graphics2D)) {
442: return;
443: }
444:
445: final Insets b = progressBar.getInsets(); // area for border
446: final int barRectWidth = progressBar.getWidth()
447: - (b.right + b.left);
448: final int barRectHeight = progressBar.getHeight()
449: - (b.top + b.bottom);
450:
451: final int valComplete = (int) animationIndex;
452:
453: SubstanceTextPainter.BackgroundPaintingCallback callback = new SubstanceTextPainter.BackgroundPaintingCallback() {
454: public void paintBackground(Graphics g) {
455: Graphics2D graphics = (Graphics2D) g.create();
456:
457: ColorScheme fillColorScheme = SubstanceThemeUtilities
458: .getTheme(
459: progressBar,
460: progressBar.isEnabled() ? ComponentState.SELECTED
461: : ComponentState.DISABLED_UNSELECTED)
462: .getColorScheme();
463: if (progressBar.getOrientation() == SwingConstants.HORIZONTAL) {
464: SubstanceImageCreator
465: .paintRectangularStripedBackground(
466: graphics, b.left, b.top,
467: barRectWidth, barRectHeight,
468: fillColorScheme,
469: SubstanceProgressBarUI.getStripe(
470: barRectHeight, false,
471: fillColorScheme),
472: valComplete, 0.6f, false);
473: } else {
474: // fix for issue 95. Vertical progress bar grows from the
475: // bottom.
476: SubstanceImageCreator
477: .paintRectangularStripedBackground(
478: graphics, b.left, b.top,
479: barRectWidth, barRectHeight,
480: fillColorScheme,
481: SubstanceProgressBarUI.getStripe(
482: barRectWidth, true,
483: fillColorScheme), 2
484: * barRectWidth
485: - valComplete, 0.6f, true);
486: }
487: graphics.dispose();
488: }
489: };
490:
491: Graphics2D g2d = (Graphics2D) g.create();
492: // install state-aware alpha channel (support for skins
493: // that use translucency on disabled states).
494: float themeAlpha = SubstanceThemeUtilities
495: .getTheme(progressBar)
496: .getThemeAlpha(
497: progressBar,
498: progressBar.isEnabled() ? ComponentState.DEFAULT
499: : ComponentState.DISABLED_UNSELECTED);
500: g2d.setComposite(TransitionLayout.getAlphaComposite(
501: progressBar, themeAlpha, g));
502:
503: SubstanceTextPainter textPainter = SubstanceLookAndFeel
504: .getCurrentTextPainter();
505: textPainter.init(this .progressBar, null, true);
506: textPainter.setBackgroundFill(progressBar, progressBar
507: .getParent().getBackground(), true, 0, 0);
508: if (textPainter.needsBackgroundImage()) {
509: textPainter.attachCallback(callback);
510: } else {
511: callback.paintBackground(g2d);
512: }
513:
514: // Deal with possible text painting
515: if (progressBar.isStringPainted()) {
516: this .paintString(g2d, b.left, b.top, barRectWidth,
517: barRectHeight, barRectWidth, b);
518: }
519: textPainter.renderSurface(g2d);
520: g2d.dispose();
521: }
522:
523: /*
524: * (non-Javadoc)
525: *
526: * @see javax.swing.plaf.basic.BasicProgressBarUI#getBox(java.awt.Rectangle)
527: */
528: @Override
529: protected Rectangle getBox(Rectangle r) {
530: Insets b = progressBar.getInsets(); // area for border
531: int barRectWidth = progressBar.getWidth() - (b.right + b.left);
532: int barRectHeight = progressBar.getHeight()
533: - (b.top + b.bottom);
534: return new Rectangle(b.left, b.top, barRectWidth, barRectHeight);
535: }
536:
537: /*
538: * (non-Javadoc)
539: *
540: * @see javax.swing.plaf.basic.BasicProgressBarUI#incrementAnimationIndex()
541: */
542: @Override
543: protected void incrementAnimationIndex() {
544: float newValue = animationIndex + this .speed;
545:
546: Insets b = progressBar.getInsets(); // area for border
547: int barRectHeight = progressBar.getHeight()
548: - (b.top + b.bottom);
549: int barRectWidth = progressBar.getWidth() - (b.right + b.left);
550: int threshold = 0;
551: if (progressBar.getOrientation() == SwingConstants.HORIZONTAL) {
552: threshold = 2 * barRectHeight + 1;
553: } else {
554: threshold = 2 * barRectWidth + 1;
555: }
556: animationIndex = newValue % threshold;
557: progressBar.repaint();
558: }
559:
560: /**
561: * Returns the memory usage string.
562: *
563: * @return The memory usage string.
564: */
565: public static String getMemoryUsage() {
566: StringBuffer sb = new StringBuffer();
567: sb.append("SubstanceProgressBarUI: \n");
568: sb.append("\t" + SubstanceProgressBarUI.stripeMap.size()
569: + " stripes");
570: return sb.toString();
571: }
572:
573: @Override
574: protected int getAmountFull(Insets b, int width, int height) {
575: int amountFull = 0;
576: BoundedRangeModel model = progressBar.getModel();
577:
578: long span = model.getMaximum() - model.getMinimum();
579: double currentValue = model.getValue();
580: FadeTracker fadeTracker = FadeTracker.getInstance();
581: if (fadeTracker.isTracked(progressBar,
582: PROGRESS_BAR_VALUE_CHANGED)) {
583: double fade10 = fadeTracker.getFade10(progressBar,
584: PROGRESS_BAR_VALUE_CHANGED);
585: int from = (Integer) progressBar
586: .getClientProperty(PROGRESS_BAR_FROM);
587: int to = (Integer) progressBar
588: .getClientProperty(PROGRESS_BAR_TO);
589: currentValue = from + (fade10 * (to - from) / 10.0);
590: }
591:
592: double percentComplete = (currentValue - model.getMinimum())
593: / span;
594:
595: if ((model.getMaximum() - model.getMinimum()) != 0) {
596: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
597: amountFull = (int) Math.round(width * percentComplete);
598: } else {
599: amountFull = (int) Math.round(height * percentComplete);
600: }
601: }
602: return amountFull;
603: }
604:
605: /*
606: * (non-Javadoc)
607: *
608: * @see javax.swing.plaf.basic.BasicProgressBarUI#getPreferredInnerHorizontal()
609: */
610: @Override
611: protected Dimension getPreferredInnerHorizontal() {
612: int size = SubstanceSizeUtils
613: .getComponentFontSize(this .progressBar);
614: size += 2 * SubstanceSizeUtils.getAdjustedSize(size, 1, 4, 1,
615: false);
616: return new Dimension(146 + SubstanceSizeUtils.getAdjustedSize(
617: size, 0, 1, 10, false), size);
618: }
619:
620: /*
621: * (non-Javadoc)
622: *
623: * @see javax.swing.plaf.basic.BasicProgressBarUI#getPreferredInnerVertical()
624: */
625: @Override
626: protected Dimension getPreferredInnerVertical() {
627: int size = SubstanceSizeUtils
628: .getComponentFontSize(this .progressBar);
629: size += 2 * SubstanceSizeUtils.getAdjustedSize(size, 1, 4, 1,
630: false);
631: return new Dimension(size, 146 + SubstanceSizeUtils
632: .getAdjustedSize(size, 0, 1, 10, false));
633: }
634:
635: @Override
636: protected void paintString(Graphics g, int x, int y, int width,
637: int height, int amountFull, Insets b) {
638: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
639: if (progressBar.getComponentOrientation().isLeftToRight()) {
640: if (progressBar.isIndeterminate()) {
641: boxRect = getBox(boxRect);
642: paintString(x, y, width, height, boxRect.x,
643: boxRect.width, b);
644: } else {
645: paintString(x, y, width, height, x, amountFull, b);
646: }
647: } else {
648: paintString(x, y, width, height,
649: x + width - amountFull, amountFull, b);
650: }
651: } else {
652: if (progressBar.isIndeterminate()) {
653: boxRect = getBox(boxRect);
654: paintString(x, y, width, height, boxRect.y,
655: boxRect.height, b);
656: } else {
657: paintString(x, y, width, height, y + height
658: - amountFull, amountFull, b);
659: }
660: }
661: }
662:
663: /**
664: * Paints the progress string.
665: *
666: * @param g
667: * Graphics used for drawing.
668: * @param x
669: * x location of bounding box
670: * @param y
671: * y location of bounding box
672: * @param width
673: * width of bounding box
674: * @param height
675: * height of bounding box
676: * @param fillStart
677: * start location, in x or y depending on orientation, of the
678: * filled portion of the progress bar.
679: * @param amountFull
680: * size of the fill region, either width or height depending upon
681: * orientation.
682: * @param b
683: * Insets of the progress bar.
684: */
685: private void paintString(int x, int y, int width, int height,
686: int fillStart, int amountFull, Insets b) {
687: String progressString = progressBar.getString();
688: Rectangle renderRectangle = getStringRectangle(progressString,
689: x, y, width, height);
690:
691: SubstanceTextPainter textPainter = SubstanceLookAndFeel
692: .getCurrentTextPainter();
693: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
694: textPainter.attachText(this .progressBar, renderRectangle,
695: progressString, -1, progressBar.getFont(),
696: getSelectionBackground(), new Rectangle(amountFull,
697: y, progressBar.getWidth() - amountFull,
698: height));
699:
700: textPainter.attachText(this .progressBar, renderRectangle,
701: progressString, -1, progressBar.getFont(),
702: getSelectionForeground(), new Rectangle(fillStart,
703: y, amountFull, height));
704: } else { // VERTICAL
705: textPainter.attachVerticalText(this .progressBar,
706: renderRectangle, progressString, -1, progressBar
707: .getFont(), getSelectionBackground(),
708: new Rectangle(x, y, width, progressBar.getHeight()
709: - amountFull), progressBar
710: .getComponentOrientation().isLeftToRight());
711:
712: textPainter.attachVerticalText(this .progressBar,
713: renderRectangle, progressString, -1, progressBar
714: .getFont(), getSelectionForeground(),
715: new Rectangle(x, fillStart, width, amountFull),
716: progressBar.getComponentOrientation()
717: .isLeftToRight());
718: }
719: }
720:
721: /**
722: * Returns the rectangle for the progress bar string.
723: *
724: * @param progressString
725: * Progress bar string.
726: * @param x
727: * x location of bounding box
728: * @param y
729: * y location of bounding box
730: * @param width
731: * width of bounding box
732: * @param height
733: * height of bounding box
734: * @return The rectangle for the progress bar string.
735: */
736: protected Rectangle getStringRectangle(String progressString,
737: int x, int y, int width, int height) {
738: FontMetrics fontSizer = progressBar.getFontMetrics(progressBar
739: .getFont());
740:
741: int stringWidth = fontSizer.stringWidth(progressString);
742:
743: if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
744: return new Rectangle(x
745: + Math.round(width / 2 - stringWidth / 2), y
746: + (height - fontSizer.getHeight()) / 2,
747: stringWidth, fontSizer.getHeight());
748: } else {
749: return new Rectangle(x + (width - fontSizer.getHeight())
750: / 2, y + Math.round(height / 2 - stringWidth / 2),
751: fontSizer.getHeight(), stringWidth);
752: // return new Rectangle(x - height / 2 - fontSizer.getHeight(), y,
753: // fontSizer.getHeight(), stringWidth);
754: }
755: }
756:
757: }
|