2 * Copyright 2008, 2009 Electronic Business Systems Ltd.
4 * This file is part of GSS.
6 * GSS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GSS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GSS. If not, see <http://www.gnu.org/licenses/>.
19 package gr.ebs.gss.client;
21 import com.google.gwt.user.client.ui.FlexTable;
22 import com.google.gwt.user.client.ui.Grid;
23 import com.google.gwt.user.client.ui.Label;
24 import com.google.gwt.user.client.ui.VerticalPanel;
28 * A simple progress bar that uses table elements to show progress and with a
29 * basic time remaining calculation built in.
31 * You can optionally display some text above the progress bar and/or display
32 * time remaining underneath the progress bar. To control the display of those
33 * features, set the options in the constructor as shown in the following usage
37 * final ProgressBar progressBar = new ProgressBar(20, ProgressBar.SHOW_TIME_REMAINING + ProgressBar.SHOW_TEXT);
38 * progressBar.setText("Doing something...");
39 * RootPanel.get().add(progressBar);
40 * Timer t = new Timer() {
43 * int progress = progressBar.getProgress() + 4;
44 * if (progress > 100)
46 * progressBar.setProgress(progress);
49 * t.scheduleRepeating(1000);
52 * How the time remaining is displayed can be controlled by setting the relevant
53 * messages using the language of your choice.
55 * The default setting for the messages are as follows:
58 * setSecondsMessage("Time remaining: {0} Seconds");
59 * setMinutesMessage("Time remaining: {0} Minutes");
60 * setHoursMessage("Time remaining: {0} Hours");
63 * To reset the time remaining/set the start time, simply set the progress to
66 * Some basic CSS styling is available to control the text, border around the
67 * progress bar itself and the colour of the progress bar elements.
73 * .progressbar-remaining {
77 * .progressbar-outer {
78 * border: 1px solid black;
80 * .progressbar-inner {
81 * border: 1px solid black;
89 * .progressbar-fullbar {
92 * .progressbar-blankbar {
97 * You can take advantage of the default style by adding the following to the
98 * head of your HTML page.
100 * <link rel="stylesheet" type="text/css" href="style/gwl-progressBar.css">
102 * This style sheet also has two additional styles which you can use by adding
103 * the stye name to the widget. You can use either one of these, or use both
107 * ProgressBar progressBar = new ProgressBar(20);
108 * progressBar.addStyleName("progressbar-solid");
109 * progressBar.addStyleName("progressbar-noborder");
112 * @author Bjarne Matzen - Bjarne[dot]Matzen[at]gmail[dot]com
115 public class ProgressBar extends VerticalPanel {
118 * Option to show text label above progress bar
120 public static final int SHOW_TEXT = 2;
123 * Option to show time remaining
125 public static final int SHOW_TIME_REMAINING = 1;
128 * The time the progress bar was started
130 private long startTime = System.currentTimeMillis();
133 * The number of bar elements to show
135 private int elements = 20;
140 private String secondsMessage = "Estimated time remaining: {0} Seconds";
142 private String minutesMessage = "Estimated time remaining: {0} Minutes";
144 private String hoursMessage = "Estimated time remaining: {0} Hours";
147 * Current progress (as a percentage)
149 private int progress = 0;
152 * This is the frame around the progress bar
154 private FlexTable barFrame = new FlexTable();
157 * This is the grid used to show the elements
159 private Grid elementGrid;
162 * This is the current text label below the progress bar
164 private Label remainLabel = new Label();
167 * This is the current text label above the progress bar
169 private Label textLabel = new Label();
172 * internal flags for options
174 private boolean showRemaining = false;
176 private boolean showText = false;
179 * Base constructor for this widget
181 * @param elements The number of elements (bars) to show on the progress bar
182 * @param options The display options for the progress bar
184 public ProgressBar(int elements, int options) {
185 // Read the options and set convenience variables
186 if ((options & SHOW_TIME_REMAINING) == SHOW_TIME_REMAINING)
187 showRemaining = true;
188 if ((options & SHOW_TEXT) == SHOW_TEXT)
192 this.elements = elements;
195 remainLabel.setStyleName("progressbar-remaining");
196 textLabel.setStyleName("progressbar-text");
198 // Initialize the progress elements
199 elementGrid = new Grid(1, elements);
200 elementGrid.setStyleName("progressbar-inner");
201 elementGrid.setCellPadding(0);
202 elementGrid.setCellSpacing(0);
204 for (int loop = 0; loop < elements; loop++) {
205 Grid elm = new Grid(1, 1);
206 // elm.setHTML(0, 0, " ");
207 elm.setHTML(0, 0, "");
208 elm.setStyleName("progressbar-blankbar");
209 elm.addStyleName("progressbar-bar");
210 elementGrid.setWidget(0, loop, elm);
213 // Create the container around the elements
214 Grid containerGrid = new Grid(1, 1);
215 containerGrid.setCellPadding(0);
216 containerGrid.setCellSpacing(0);
217 containerGrid.setWidget(0, 0, elementGrid);
218 containerGrid.setStyleName("progressbar-outer");
219 // containerGrid.setBorderWidth(1);
221 // Set up the surrounding flex table based on the options
224 barFrame.setWidget(row++, 0, textLabel);
225 barFrame.setWidget(row++, 0, containerGrid);
227 barFrame.setWidget(row++, 0, remainLabel);
229 barFrame.setWidth("100%");
231 // Add the frame to the panel
234 // Initialize progress bar
239 * Constructor without options
241 * @param elements The number of elements (bars) to show on the progress bar
243 public ProgressBar(int elements) {
248 * Set the current progress as a percentage
250 * @param percentage Set current percentage for the progress bar
252 public void setProgress(int percentage) {
253 // Make sure we are error-tolerant
254 if (percentage > 100)
259 // Set the internal variable
260 progress = percentage;
262 // Update the elements in the progress grid to
263 // reflect the status
264 int completed = elements * percentage / 100;
265 for (int loop = 0; loop < elements; loop++) {
266 Grid elm = (Grid) elementGrid.getWidget(0, loop);
267 if (loop < completed) {
268 elm.setStyleName("progressbar-fullbar");
269 elm.addStyleName("progressbar-bar");
271 elm.setStyleName("progressbar-blankbar");
272 elm.addStyleName("progressbar-bar");
276 if (percentage > 0) {
277 // Calculate the new time remaining
278 long soFar = (System.currentTimeMillis() - startTime) / 1000;
279 long remaining = soFar * (100 - percentage) / percentage;
280 // Select the best UOM
281 String remainText = secondsMessage;
282 if (remaining > 120) {
283 remaining = remaining / 60;
284 remainText = minutesMessage;
285 if (remaining > 120) {
286 remaining = remaining / 60;
287 remainText = hoursMessage;
290 // Locate the position to insert out time remaining
291 int pos = remainText.indexOf("{0}");
294 if (pos + 3 < remainText.length())
295 trail = remainText.substring(pos + 3);
296 remainText = remainText.substring(0, pos) + remaining + trail;
299 remainLabel.setText(remainText);
301 // If progress is 0, reset the start time
302 startTime = System.currentTimeMillis();
306 * Get the current progress as a percentage
308 * @return Current percentage for the progress bar
310 public int getProgress() {
315 * Get the text displayed above the progress bar
319 public String getText() {
320 return textLabel.getText();
324 * Set the text displayed above the progress bar
326 * @param text the text to set
328 public void setText(String text) {
329 textLabel.setText(text);
333 * Get the message used to format the time remaining text for hours
335 * @return the hours message
337 public String getHoursMessage() {
342 * Set the message used to format the time remaining text below the progress
343 * bar. There are 3 messages used for hours, minutes and seconds
344 * respectively. The message must contain a placeholder for the value. The
345 * placeholder must be {0}. For example, the following is a valid message:
346 * "Hours remaining: {0}"
348 * @param hoursMessage the hours message to set
350 public void setHoursMessage(String hoursMessage) {
351 this.hoursMessage = hoursMessage;
355 * Get the message used to format the time remaining text for minutes
357 * @return the minutesMessage
359 public String getMinutesMessage() {
360 return minutesMessage;
364 * Set the message used to format the time remaining text below the progress
365 * bar. There are 3 messages used for hours, minutes and seconds
366 * respectively. The message must contain a placeholder for the value. The
367 * placeholder must be {0}. For example, the following is a valid message:
368 * "Minutes remaining: {0}"
370 * @param minutesMessage the minutes message to set
372 public void setMinutesMessage(String minutesMessage) {
373 this.minutesMessage = minutesMessage;
377 * Get the message used to format the time remaining text for seconds
379 * @return the secondsMessage
381 public String getSecondsMessage() {
382 return secondsMessage;
386 * Set the message used to format the time remaining text below the progress
387 * bar. There are 3 messages used for hours, minutes and seconds
388 * respectively. The message must contain a placeholder for the value. The
389 * placeholder must be {0}. For example, the following is a valid message:
390 * "Seconds remaining: {0}"
392 * @param secondsMessage the secondsMessage to set
394 public void setSecondsMessage(String secondsMessage) {
395 this.secondsMessage = secondsMessage;