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