2 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.com>
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package gr.ebs.gss.client;
19 import com.google.gwt.user.client.ui.FlexTable;
20 import com.google.gwt.user.client.ui.Grid;
21 import com.google.gwt.user.client.ui.Label;
22 import com.google.gwt.user.client.ui.VerticalPanel;
26 * A simple progress bar that uses table elements to show progress and with a
27 * basic time remaining calculation built in.
29 * You can optionally display some text above the progress bar and/or display
30 * time remaining underneath the progress bar. To control the display of those
31 * features, set the options in the constructor as shown in the following usage
35 * final ProgressBar progressBar = new ProgressBar(20, ProgressBar.SHOW_TIME_REMAINING + ProgressBar.SHOW_TEXT);
36 * progressBar.setText("Doing something...");
37 * RootPanel.get().add(progressBar);
38 * Timer t = new Timer() {
41 * int progress = progressBar.getProgress() + 4;
42 * if (progress > 100)
44 * progressBar.setProgress(progress);
47 * t.scheduleRepeating(1000);
50 * How the time remaining is displayed can be controlled by setting the relevant
51 * messages using the language of your choice.
53 * The default setting for the messages are as follows:
56 * setSecondsMessage("Time remaining: {0} Seconds");
57 * setMinutesMessage("Time remaining: {0} Minutes");
58 * setHoursMessage("Time remaining: {0} Hours");
61 * To reset the time remaining/set the start time, simply set the progress to
64 * Some basic CSS styling is available to control the text, border around the
65 * progress bar itself and the colour of the progress bar elements.
71 * .progressbar-remaining {
75 * .progressbar-outer {
76 * border: 1px solid black;
78 * .progressbar-inner {
79 * border: 1px solid black;
87 * .progressbar-fullbar {
90 * .progressbar-blankbar {
95 * You can take advantage of the default style by adding the following to the
96 * head of your HTML page.
98 * <link rel="stylesheet" type="text/css" href="style/gwl-progressBar.css">
100 * This style sheet also has two additional styles which you can use by adding
101 * the stye name to the widget. You can use either one of these, or use both
105 * ProgressBar progressBar = new ProgressBar(20);
106 * progressBar.addStyleName("progressbar-solid");
107 * progressBar.addStyleName("progressbar-noborder");
110 * @author Bjarne Matzen - Bjarne[dot]Matzen[at]gmail[dot]com
113 public class ProgressBar extends VerticalPanel {
116 * Option to show text label above progress bar
118 public static final int SHOW_TEXT = 2;
121 * Option to show time remaining
123 public static final int SHOW_TIME_REMAINING = 1;
126 * The time the progress bar was started
128 private long startTime = System.currentTimeMillis();
131 * The number of bar elements to show
133 private int elements = 20;
138 private String secondsMessage = "Estimated time remaining: {0} Seconds";
140 private String minutesMessage = "Estimated time remaining: {0} Minutes";
142 private String hoursMessage = "Estimated time remaining: {0} Hours";
145 * Current progress (as a percentage)
147 private int progress = 0;
150 * This is the frame around the progress bar
152 private FlexTable barFrame = new FlexTable();
155 * This is the grid used to show the elements
157 private Grid elementGrid;
160 * This is the current text label below the progress bar
162 private Label remainLabel = new Label();
165 * This is the current text label above the progress bar
167 private Label textLabel = new Label();
170 * internal flags for options
172 private boolean showRemaining = false;
174 private boolean showText = false;
177 * Base constructor for this widget
179 * @param elementNo The number of elements (bars) to show on the progress bar
180 * @param options The display options for the progress bar
182 public ProgressBar(int elementNo, int options) {
183 // Read the options and set convenience variables
184 if ((options & SHOW_TIME_REMAINING) == SHOW_TIME_REMAINING)
185 showRemaining = true;
186 if ((options & SHOW_TEXT) == SHOW_TEXT)
190 elements = elementNo;
193 remainLabel.setStyleName("progressbar-remaining");
194 textLabel.setStyleName("progressbar-text");
196 // Initialize the progress elements
197 elementGrid = new Grid(1, elementNo);
198 elementGrid.setStyleName("progressbar-inner");
199 elementGrid.setCellPadding(0);
200 elementGrid.setCellSpacing(0);
202 for (int loop = 0; loop < elementNo; loop++) {
203 Grid elm = new Grid(1, 1);
204 // elm.setHTML(0, 0, " ");
205 elm.setHTML(0, 0, "");
206 elm.setStyleName("progressbar-blankbar");
207 elm.addStyleName("progressbar-bar");
208 elementGrid.setWidget(0, loop, elm);
211 // Create the container around the elements
212 Grid containerGrid = new Grid(1, 1);
213 containerGrid.setCellPadding(0);
214 containerGrid.setCellSpacing(0);
215 containerGrid.setWidget(0, 0, elementGrid);
216 containerGrid.setStyleName("progressbar-outer");
217 // containerGrid.setBorderWidth(1);
219 // Set up the surrounding flex table based on the options
222 barFrame.setWidget(row++, 0, textLabel);
223 barFrame.setWidget(row++, 0, containerGrid);
225 barFrame.setWidget(row++, 0, remainLabel);
227 barFrame.setWidth("100%");
229 // Add the frame to the panel
232 // Initialize progress bar
237 * Constructor without options
239 * @param elementNo The number of elements (bars) to show on the progress bar
241 public ProgressBar(int elementNo) {
246 * Set the current progress as a percentage
248 * @param percentage Set current percentage for the progress bar
250 public void setProgress(int percentage) {
251 // Make sure we are error-tolerant
252 if (percentage > 100)
257 // Set the internal variable
258 progress = percentage;
260 // Update the elements in the progress grid to
261 // reflect the status
262 int completed = elements * percentage / 100;
263 for (int loop = 0; loop < elements; loop++) {
264 Grid elm = (Grid) elementGrid.getWidget(0, loop);
265 if (loop < completed) {
266 elm.setStyleName("progressbar-fullbar");
267 elm.addStyleName("progressbar-bar");
269 elm.setStyleName("progressbar-blankbar");
270 elm.addStyleName("progressbar-bar");
274 if (percentage > 0) {
275 // Calculate the new time remaining
276 long soFar = (System.currentTimeMillis() - startTime) / 1000;
277 long remaining = soFar * (100 - percentage) / percentage;
278 // Select the best UOM
279 String remainText = secondsMessage;
280 if (remaining > 120) {
281 remaining = remaining / 60;
282 remainText = minutesMessage;
283 if (remaining > 120) {
284 remaining = remaining / 60;
285 remainText = hoursMessage;
288 // Locate the position to insert out time remaining
289 int pos = remainText.indexOf("{0}");
292 if (pos + 3 < remainText.length())
293 trail = remainText.substring(pos + 3);
294 remainText = remainText.substring(0, pos) + remaining + trail;
297 remainLabel.setText(remainText);
299 // If progress is 0, reset the start time
300 startTime = System.currentTimeMillis();
304 * Get the current progress as a percentage
306 * @return Current percentage for the progress bar
308 public int getProgress() {
313 * Get the text displayed above the progress bar
317 public String getText() {
318 return textLabel.getText();
322 * Set the text displayed above the progress bar
324 * @param text the text to set
326 public void setText(String text) {
327 textLabel.setText(text);
331 * Get the message used to format the time remaining text for hours
333 * @return the hours message
335 public String getHoursMessage() {
340 * Set the message used to format the time remaining text below the progress
341 * bar. There are 3 messages used for hours, minutes and seconds
342 * respectively. The message must contain a placeholder for the value. The
343 * placeholder must be {0}. For example, the following is a valid message:
344 * "Hours remaining: {0}"
346 * @param anHoursMessage the hours message to set
348 public void setHoursMessage(String anHoursMessage) {
349 hoursMessage = anHoursMessage;
353 * Get the message used to format the time remaining text for minutes
355 * @return the minutesMessage
357 public String getMinutesMessage() {
358 return minutesMessage;
362 * Set the message used to format the time remaining text below the progress
363 * bar. There are 3 messages used for hours, minutes and seconds
364 * respectively. The message must contain a placeholder for the value. The
365 * placeholder must be {0}. For example, the following is a valid message:
366 * "Minutes remaining: {0}"
368 * @param aMinutesMessage the minutes message to set
370 public void setMinutesMessage(String aMinutesMessage) {
371 minutesMessage = aMinutesMessage;
375 * Get the message used to format the time remaining text for seconds
377 * @return the secondsMessage
379 public String getSecondsMessage() {
380 return secondsMessage;
384 * Set the message used to format the time remaining text below the progress
385 * bar. There are 3 messages used for hours, minutes and seconds
386 * respectively. The message must contain a placeholder for the value. The
387 * placeholder must be {0}. For example, the following is a valid message:
388 * "Seconds remaining: {0}"
390 * @param aSecondsMessage the secondsMessage to set
392 public void setSecondsMessage(String aSecondsMessage) {
393 secondsMessage = aSecondsMessage;