001: package com.xoetrope.swing;
002:
003: import java.awt.Color;
004: import java.awt.Dimension;
005: import java.awt.Font;
006: import java.awt.FontMetrics;
007: import java.awt.Graphics;
008: import java.awt.Image;
009: import javax.swing.JComponent;
010:
011: import net.xoetrope.xui.XAttributedComponent;
012: import net.xoetrope.xui.XProject;
013: import net.xoetrope.xui.XProjectManager;
014: import net.xoetrope.xui.style.XStyle;
015: import net.xoetrope.xui.style.XStyleManager;
016:
017: /**
018: * <p>A progress meter that can be dynamically updated. The
019: * progress can be set to a specified value or it can be incremented as the
020: * application proceeds. The progress bar can contain a cue or feedback image and
021: * text describing the control</p>
022: *
023: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
024: * the GNU Public License (GPL), please see license.txt for more details. If
025: * you make commercial use of this software you must purchase a commercial
026: * license from Xoetrope.</p>
027: * <p> $Revision: 1.11 $</p>
028: */
029: public class XProgressBar extends JComponent implements
030: XAttributedComponent {
031: protected Color doneClr, todoClr;
032: protected int numBars;
033: protected double progress;
034: protected Image cueImage;
035:
036: protected int minProgress, maxProgress;
037:
038: protected String cueImageName;
039: private double stepSize;
040:
041: /**
042: * The owner project and the context in which this object operates.
043: */
044: protected XProject currentProject = XProjectManager
045: .getCurrentProject();
046:
047: /**
048: * Constructor for a new XProgressMeter
049: */
050: public XProgressBar() {
051: cueImageName = "cue.gif";
052:
053: numBars = 5;
054: progress = 0;
055: minProgress = 0;
056: maxProgress = 100;
057: stepSize = 20.0;
058:
059: XStyleManager styleManager = XProjectManager
060: .getCurrentProject().getStyleManager();
061: todoClr = styleManager.getStyle("Progress").getStyleAsColor(
062: XStyle.COLOR_FORE);
063: if (todoClr == null)
064: todoClr = Color.red;
065: doneClr = todoClr.darker();
066: }
067:
068: /**
069: * Set the progress to a specific level.
070: * @param p the new level. If p is less than 0 then the progress level is set to the step size.
071: */
072: public void setProgress(int p) {
073: if (p < 0)
074: progress = stepSize;
075: else
076: progress = p;
077: repaint();
078: }
079:
080: /**
081: * Get the progress level.
082: * @return the current value
083: */
084: public int getProgress() {
085: return (int) progress;
086: }
087:
088: /**
089: * Increments the progress level
090: */
091: public void next() {
092: progress += stepSize;
093: if ((progress - maxProgress) > 1.0)
094: progress = stepSize;
095: repaint();
096: }
097:
098: /**
099: * Decrements the progress level.
100: */
101: public void previous() {
102: if (progress > minProgress) {
103: progress -= stepSize;
104: repaint();
105: }
106: }
107:
108: /**
109: * Set the number of bars shown in the progress bar.
110: * @param nb the number of bars within the progress bar
111: */
112: public void setNumBars(int nb) {
113: numBars = nb;
114: }
115:
116: /**
117: * Set the step size for incrementing the progress bar
118: * @param ns the new step size
119: */
120: public void setStepSize(int ns) {
121: stepSize = ns;
122: }
123:
124: /**
125: * Set the name of the cue image
126: * @param newName the name of the new image
127: */
128: public void setCueImageName(String newName) {
129: cueImageName = newName;
130: }
131:
132: /**
133: * Get the maximum allowable progress value. Above this value the progress
134: * counter wraps to zero.
135: * @return the max value
136: */
137: public int getMaxValue() {
138: return maxProgress;
139: }
140:
141: /**
142: * Set the maximum allowable progress value. Above this value the progress
143: * counter wraps to zero.
144: * @param newMax the new max value
145: */
146: public void setMaxValue(int newMax) {
147: maxProgress = newMax;
148: }
149:
150: /**
151: * Render the progress bar.
152: * @param g The graphics context
153: */
154: public void paint(Graphics g) {
155: Dimension d = getSize();
156:
157: // Calculate the font size.
158: Font f = getFont();
159: g.setFont(f);
160: FontMetrics fm = g.getFontMetrics(f);
161: int fontAscent = fm.getAscent();
162:
163: int cueSize = 20;
164:
165: String caption = " "
166: + Integer
167: .toString((int) ((100 * progress) / maxProgress))
168: + " %";
169: int textW = (int) fm.stringWidth(caption);
170: int progressWidth = (d.width - textW - 15 - cueSize) / numBars;
171:
172: if (cueImage == null) {
173: if (cueImageName != null)
174: cueImage = currentProject.getImage(cueImageName);
175: else
176: cueSize = 0;
177: }
178: if (cueImage != null)
179: g.drawImage(cueImage, 0, fontAscent, getBackground(), this );
180:
181: int grayStart = 5 + cueSize;
182: int greenStart = 3 + cueSize;
183: int textStart = 5 + progressWidth / 2 - fontAscent / 2
184: + cueSize;
185: int grayTop = fontAscent + 6;
186: int greenTop = fontAscent + 4;
187: int greenWidth = progressWidth - 4;
188: int greenHeight = d.height - fontAscent - 6;
189: int pOffset = 0;
190: int progressCutOff = (int) (((progress + (stepSize / 4.0)) * numBars) / maxProgress);
191: for (int i = 0; i < numBars; i++) {
192: g.setColor(getForeground());
193: if (numBars < 11)
194: g.drawString(Integer.toString(i + 1), textStart
195: + pOffset, fontAscent);
196:
197: g.setColor(Color.lightGray);
198: g.fillRect(grayStart + pOffset, grayTop, greenWidth,
199: greenHeight);
200:
201: if (i < progressCutOff)
202: g.setColor(doneClr);
203: else
204: g.setColor(todoClr);
205:
206: g.fillRect(greenStart + pOffset, greenTop, greenWidth,
207: greenHeight);
208:
209: pOffset += progressWidth;
210: }
211: g.setColor(getForeground());
212: g.drawString(caption, progressWidth * numBars + cueSize + 2,
213: d.height - 4);
214: }
215:
216: /**
217: * Sets the progress state to the minimum value;
218: */
219: public void reset() {
220: progress = minProgress;
221: }
222:
223: /**
224: * Set one or more attributes of the component. Currently this handles the
225: * attributes
226: * <OL>
227: * <LI>cue, value=Cue image filename</LI>
228: * <LI>bars, value=number of bars</LI>
229: * <LI>progress, value=the current progress value</LI>
230: * <LI>max, value=the maximum progress value</LI>
231: * <LI>step, value=the step size</LI>
232: * </OL>
233: * @param attribName the attribute name
234: * @param attribValue the attribute value
235: * @return 0 for success, non zero otherwise
236: */
237: public int setAttribute(String attribName, Object attribValue) {
238: String attribNameLwr = attribName.toLowerCase();
239: String attribValueStr = (String) attribValue;
240: String attribValueLwr = attribValueStr.toLowerCase();
241: if (attribNameLwr.equals("cue"))
242: cueImageName = attribValueStr;
243: else if (attribNameLwr.equals("bars")) {
244: numBars = new Integer(attribValueStr).intValue();
245: progress = stepSize = (double) maxProgress / numBars;
246: } else if (attribNameLwr.equals("progress"))
247: progress = new Integer(attribValueStr).intValue();
248: else if (attribNameLwr.equals("max")) {
249: maxProgress = new Integer(attribValueStr).intValue();
250: progress = stepSize = (double) maxProgress / numBars;
251: } else if (attribNameLwr.equals("step")) {
252: stepSize = new Integer(attribValueStr).intValue();
253: }
254:
255: repaint(100);
256:
257: return 0;
258: }
259:
260: /**
261: * Gets the number of bars in the progress bar
262: * @return the number of bars
263: */
264: public int getNumBars() {
265: return numBars;
266: }
267:
268: /**
269: * Get the name of the cue image
270: * @return the image name
271: */
272: public String getCueImageName() {
273: return cueImageName;
274: }
275:
276: /**
277: * Get the progress increment used when next is invoked
278: * @return the progress increment
279: */
280: public int getStepSize() {
281: return (int) stepSize;
282: }
283: }
|