/* * @(#)AMDProgressBar.java 0.90 12/09/96 Adam Doppelt */ import java.awt.*; /** * A ProgressBar is a widget which indicates how close a task is to * completion. The developer can create a progress bar, draw it * somewhere on screen, and make the bar move from 0% to 100% while * the rest of the program does something time consuming.

* * There are two versions of the progress bar, one which is a subclass * of an AWT component, and one which can be embedded in the drawing * area of other components. AMDProgressBar acts as a standard AWT * component.

* * A progress bar looks like this:

* *

* Version: 0.90 09 Dec 1996
* Author: Adam Doppelt
* @see AMDProgressBarEmbed */ public class AMDProgressBar extends Canvas { ///////////////////////////////////// // things the user can set int width_, height_; Color outerBorderColor_ = Color.black; Color innerBorderColor_ = Color.black; Color boxColorA_ = new Color(244, 224, 32); Color boxColorB_ = new Color(120, 80, 4); Color barColor_ = new Color(52, 112, 4); Color backTopColor_ = new Color(40, 40, 40); Color backBottomColor_ = new Color(76, 76, 76); Color textColor_ = new Color(208, 192, 28); Color textShadowColor_ = Color.black; Font font_ = new Font("TimesRoman", Font.BOLD, 14); String text_; int sinePeriod_ = 87; int colorSegment_ = 7; ///////////////////////////////////// // things stored for quick drawing Graphics graphics_; Image image_; double percent_; boolean updateTrim_, updateLocations_, updateBar_; // state variables int lastDigits_, halfY_, textX_, textY_; /** * Constructs a progress bar. */ public AMDProgressBar() { lastDigits_ = 1; setPercent(0); updateTrim_ = true; updateLocations_ = true; updateBar_ = true; } /** * Resize the progress bar. * @param x The new x location with the parent. * @param y The new y location with the parent. * @param width The new width of the bar, from outer border on the * left to outer border on the right. * @param height The new height of the bar, from outer border on the * top to outer border on the bottom. */ public void reshape (int x, int y, int width, int height) { super.reshape(x, y, width, height); width_ = width; height_ = height; if (graphics_ != null) { graphics_.dispose(); graphics_ = null; } repaint(); } /** * Update the progress bar. AWT calls this. */ public void update(Graphics g) { paint(g); } /** * Paint the progress bar. AWT calls this. */ public void paint(Graphics g) { if (graphics_ == null) { image_ = createImage(width_, height_); graphics_ = image_.getGraphics(); updateTrim_ = true; updateLocations_ = true; updateBar_ = true; } if (updateTrim_) updateTrim(); if (updateLocations_) updateLocations(); if (updateBar_) { int left = (int)((double)(width_ - 6) * percent_); int right = width_ - 6 - left; graphics_.translate(3, 3); if (left > 0) { graphics_.setColor(barColor_); graphics_.fillRect(0, 0, left, height_ - 6); } if (right > 0) { graphics_.setColor(backTopColor_); graphics_.fillRect(left, 0, right, halfY_); graphics_.setColor(backBottomColor_); graphics_.fillRect(left, halfY_, right, height_ - 6 - halfY_); } graphics_.translate(-3, -3); graphics_.setFont(font_); graphics_.setColor(textShadowColor_); String p; if (text_ == null) p = "" + ((int)(percent_ * 100)) + "%"; else p = text_; graphics_.drawString(p, textX_ + 1, textY_ + 1); graphics_.setColor(textColor_); graphics_.drawString(p, textX_, textY_); updateBar_ = false; } g.drawImage(image_, 0, 0, null); } int r_, g_, b_, r2_, g2_, b2_; Color getColor(int p) { double s = Math.sin(((double)(p % sinePeriod_) * 2.0 * Math.PI) / (double)sinePeriod_) + 1.0; return new Color(r_ + (int)(s * (double)(r2_ - r_) / 2.0), g_ + (int)(s * (double)(g2_ - g_) / 2.0), b_ + (int)(s * (double)(b2_ - b_) / 2.0)); } int drawSineLine(int p, int offset, int x1, int y1, int x2, int y2) { boolean swap = (x1 == x2); if (swap) { int t = x1; x1 = y1; y1 = t; t = x2; x2 = y2; y2 = t; } boolean reverse = (x1 > x2); if (reverse) offset *= -1; // start colorSegment_ graphics_.setColor(getColor(p)); if (swap) graphics_.drawLine(y1, x1, y1, x1 + offset); else graphics_.drawLine(x1, y1, x1 + offset, y1); int loop = 1; // main colorSegment_ if (!reverse) offset += colorSegment_; p += colorSegment_; while ((reverse && x1 + offset - colorSegment_ > x2) || (!reverse && x1 + offset < x2)) { graphics_.setColor(getColor(p)); if (swap) graphics_.drawLine(y1, x1 + offset - colorSegment_, y1, x1 + offset); else graphics_.drawLine(x1 + offset - colorSegment_, y1, x1 + offset, y1); offset += reverse ? -colorSegment_ : colorSegment_; p += colorSegment_; ++loop; } if (reverse) offset += colorSegment_; // end colorSegment_ graphics_.setColor(getColor(p)); if (swap) graphics_.drawLine(y1, x1 + offset - colorSegment_, y1, x2); else graphics_.drawLine(x1 + offset - colorSegment_, y1, x2, y1); return loop; } void drawSineBox(Color peakA, Color peakB, int x, int y, int width, int height) { r_ = peakA.getRed(); g_ = peakA.getGreen(); b_ = peakA.getBlue(); r2_ = peakB.getRed(); g2_ = peakB.getGreen(); b2_ = peakB.getBlue(); int lastX = x + width; int lastY = y + height; int offset = 0; int p = (int)((double)sinePeriod_ / 4.0); int loop; loop = drawSineLine(p, offset, x, y, lastX, y); p += loop * colorSegment_; offset += (loop * colorSegment_) - lastX + 1; loop = drawSineLine(p, offset, lastX, y, lastX, lastY); p += loop * colorSegment_; offset += (loop * colorSegment_) - lastY + 1; loop = drawSineLine(p, offset, lastX, lastY, x, lastY); p += loop * colorSegment_; offset += (loop * colorSegment_) - lastX + 1; loop = drawSineLine(p, offset, x, lastY, x, y); } void updateTrim() { graphics_.setColor(outerBorderColor_); graphics_.drawRect(0, 0, width_ - 1, height_ - 1); graphics_.setColor(innerBorderColor_); graphics_.drawRect(2, 2, width_ - 5, height_ - 5); if (boxColorB_ == null || boxColorA_.equals(boxColorB_)) { graphics_.setColor(boxColorA_); graphics_.drawRect(1, 1, width_ - 3, height_ - 3); } else drawSineBox(boxColorA_, boxColorB_, 1, 1, width_ - 3, height_ - 3); updateTrim_ = false; } void updateLocations() { halfY_ = (height_ - 6) / 2; FontMetrics m = getFontMetrics(font_); String sample; if (text_ == null) { if (lastDigits_ == 1) sample = "3"; else if (lastDigits_ == 2) sample = "30"; else sample = "100"; } else sample = text_; textX_ = (width_ - m.stringWidth(sample)) / 2; textY_ = (height_ + m.getAscent() - m.getDescent()) / 2; updateLocations_ = false; } /** * Set the percent of the progress bar. * @param percent The new percent, with 0.0 being completely empty and * 1.0 completely full. */ public void setPercent(double percent) { if (percent < 0) percent_ = 0.0; else if (percent > 1.0) percent_ = 1.0; else percent_ = percent; updateBar_= true; int newDigits; if (percent < 0.1) newDigits = 1; else if (percent < 1.0) newDigits = 2; else newDigits = 3; if (newDigits != lastDigits_) { lastDigits_ = newDigits; if (text_ == null) updateLocations_ = true; } repaint(); } /** * Set the text which should be drawn in the center of the bar. * @param text The text to draw. If null is passed, the current * percent will be drawn. */ public void setText(String text) { text_ = text; updateLocations_ = true; updateBar_ = true; repaint(); } /** * Set the colors of the outer and inner borders on the box. * @param outer The color of the 1 pixel border outside the colored box. * @param inner The color of the 1 pixel border just inside the colored box. */ public void setBorderColors(Color outer, Color inner) { outerBorderColor_ = outer; innerBorderColor_ = inner; updateTrim_ = true; repaint(); } /** * Set the colors of the high and low points of the sine box * surrounding the bar. Note that the actual color will walk in a sine * wave between the two colors passed here. The sine wave will crawl * from the upperleft corner, clockwise around the box. If a == b, the * box will be drawn in a single color. * @param a The color of the first peak of the sine wave. * @param b The color of the other peak of the sine wave. */ public void setBoxColors(Color a, Color b) { boxColorA_ = a; boxColorB_ = b; updateTrim_ = true; repaint(); } /** * Set the color of the bar itself. * @param bar The color of the bar. */ public void setBarColor(Color bar) { barColor_ = bar; updateBar_ = true; repaint(); } /** * Set the colors of the top and bottom half of the background inside * the box. * @param top The color of the top half of the background. * @param bottom The color of the bottom half of the background. */ public void setBackgroundColors(Color top, Color bottom) { backTopColor_ = top; backBottomColor_ = bottom; updateBar_ = true; repaint(); } /** * Set the colors of the text and its shadow. * @param text The color of the text in the middle of the box. * @param shadow The color of the shadow on the text. */ public void setTextColors(Color text, Color shadow) { textColor_ = text; textShadowColor_ = shadow; updateBar_ = true; repaint(); } /** * Set the font of the text. * @param font The font of the text in the middle of the box. */ public void setFont(Font font) { font_ = font; updateLocations_= true; updateBar_ = true; repaint(); } /** * Set some properties of the sine box. * @param period The distance in pixels between two peaks in the sine * box. * @param segmentSize The size in pixels of each colored segment in * the sine box. */ public void setSineProperties(int period, int segmentSize) { sinePeriod_ = period; colorSegment_ = segmentSize; updateTrim_ = true; repaint(); } }