Statistics
| Branch: | Tag: | Revision:

root / web_client / src / gr / grnet / pithos / web / client / ProgressBar.java @ 58777026

History | View | Annotate | Download (11.5 kB)

1
/*
2
 * Copyright 2011 GRNET S.A. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or
5
 * without modification, are permitted provided that the following
6
 * conditions are met:
7
 *
8
 *   1. Redistributions of source code must retain the above
9
 *      copyright notice, this list of conditions and the following
10
 *      disclaimer.
11
 *
12
 *   2. Redistributions in binary form must reproduce the above
13
 *      copyright notice, this list of conditions and the following
14
 *      disclaimer in the documentation and/or other materials
15
 *      provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
 * POSSIBILITY OF SUCH DAMAGE.
29
 *
30
 * The views and conclusions contained in the software and
31
 * documentation are those of the authors and should not be
32
 * interpreted as representing official policies, either expressed
33
 * or implied, of GRNET S.A.
34
 */
35

    
36
package gr.grnet.pithos.web.client;
37

    
38
import com.google.gwt.user.client.ui.FlexTable;
39
import com.google.gwt.user.client.ui.Grid;
40
import com.google.gwt.user.client.ui.Label;
41
import com.google.gwt.user.client.ui.VerticalPanel;
42

    
43
/**
44
 * <P>
45
 * A simple progress bar that uses table elements to show progress and with a
46
 * basic time remaining calculation built in.
47
 * <P>
48
 * You can optionally display some text above the progress bar and/or display
49
 * time remaining underneath the progress bar. To control the display of those
50
 * features, set the options in the constructor as shown in the following usage
51
 * example:
52
 *
53
 * <PRE>
54
 * final ProgressBar progressBar = new ProgressBar(20, ProgressBar.SHOW_TIME_REMAINING + ProgressBar.SHOW_TEXT);
55
 * progressBar.setText(&quot;Doing something...&quot;);
56
 * RootPanel.get().add(progressBar);
57
 * Timer t = new Timer() {
58
 *
59
 *         public void run() {
60
 *                 int progress = progressBar.getProgress() + 4;
61
 *                 if (progress &gt; 100)
62
 *                         cancel();
63
 *                 progressBar.setProgress(progress);
64
 *         }
65
 * };
66
 * t.scheduleRepeating(1000);
67
 * </PRE>
68
 * <P>
69
 * How the time remaining is displayed can be controlled by setting the relevant
70
 * messages using the language of your choice.
71
 * <P>
72
 * The default setting for the messages are as follows:
73
 *
74
 * <PRE>
75
 * setSecondsMessage(&quot;Time remaining: {0} Seconds&quot;);
76
 * setMinutesMessage(&quot;Time remaining: {0} Minutes&quot;);
77
 * setHoursMessage(&quot;Time remaining: {0} Hours&quot;);
78
 * </PRE>
79
 * <P>
80
 * To reset the time remaining/set the start time, simply set the progress to
81
 * zero.
82
 * <P>
83
 * Some basic CSS styling is available to control the text, border around the
84
 * progress bar itself and the colour of the progress bar elements.
85
 *
86
 * <PRE>
87
 * .progressbar-text {
88
 *     font-weight: bold;
89
 * }
90
 * .progressbar-remaining {
91
 *     font-size: 12px;
92
 *     font-style: italic;
93
 * }
94
 * .progressbar-outer {
95
 *     border: 1px solid black;
96
 * }
97
 * .progressbar-inner {
98
 *     border: 1px solid black;
99
 *     margin: 1px;
100
 * }
101
 * .progressbar-bar {
102
 *     width: 5px;
103
 *     height: 15px;
104
 *     margin: 1px;
105
 * }
106
 * .progressbar-fullbar {
107
 *     background: blue;
108
 * }
109
 * .progressbar-blankbar {
110
 *     background: #eee;
111
 * }
112
 *</PRE>
113
 * <P>
114
 * You can take advantage of the default style by adding the following to the
115
 * head of your HTML page.
116
 * <P>
117
 * &lt;link rel="stylesheet" type="text/css" href="style/gwl-progressBar.css">
118
 * <P>
119
 * This style sheet also has two additional styles which you can use by adding
120
 * the stye name to the widget. You can use either one of these, or use both
121
 * combined.
122
 *
123
 * <PRE>
124
 * ProgressBar progressBar = new ProgressBar(20);
125
 * progressBar.addStyleName(&quot;progressbar-solid&quot;);
126
 * progressBar.addStyleName(&quot;progressbar-noborder&quot;);
127
 * </PRE>
128
 *
129
 * @author Bjarne Matzen - Bjarne[dot]Matzen[at]gmail[dot]com
130
 */
131

    
132
public class ProgressBar extends VerticalPanel {
133

    
134
        /**
135
         * Option to show text label above progress bar
136
         */
137
        public static final int SHOW_TEXT = 2;
138

    
139
        /**
140
         * Option to show time remaining
141
         */
142
        public static final int SHOW_TIME_REMAINING = 1;
143

    
144
        /**
145
         * The time the progress bar was started
146
         */
147
        private long startTime = System.currentTimeMillis();
148

    
149
        /**
150
         * The number of bar elements to show
151
         */
152
        private int elements = 20;
153

    
154
        /**
155
         * Time element text
156
         */
157
        private String secondsMessage = "Estimated time remaining: {0} Seconds";
158

    
159
        private String minutesMessage = "Estimated time remaining: {0} Minutes";
160

    
161
        private String hoursMessage = "Estimated time remaining: {0} Hours";
162

    
163
        /**
164
         * Current progress (as a percentage)
165
         */
166
        private int progress = 0;
167

    
168
        /**
169
         * This is the frame around the progress bar
170
         */
171
        private FlexTable barFrame = new FlexTable();
172

    
173
        /**
174
         * This is the grid used to show the elements
175
         */
176
        private Grid elementGrid;
177

    
178
        /**
179
         * This is the current text label below the progress bar
180
         */
181
        private Label remainLabel = new Label();
182

    
183
        /**
184
         * This is the current text label above the progress bar
185
         */
186
        private Label textLabel = new Label();
187

    
188
        /**
189
         * internal flags for options
190
         */
191
        private boolean showRemaining = false;
192

    
193
        private boolean showText = false;
194

    
195
        /**
196
         * Base constructor for this widget
197
         *
198
         * @param elementNo The number of elements (bars) to show on the progress bar
199
         * @param options The display options for the progress bar
200
         */
201
        public ProgressBar(int elementNo, int options) {
202
                // Read the options and set convenience variables
203
                if ((options & SHOW_TIME_REMAINING) == SHOW_TIME_REMAINING)
204
                        showRemaining = true;
205
                if ((options & SHOW_TEXT) == SHOW_TEXT)
206
                        showText = true;
207

    
208
                // Set element count
209
                elements = elementNo;
210

    
211
                // Styling
212
                remainLabel.setStyleName("progressbar-remaining");
213
                textLabel.setStyleName("progressbar-text");
214

    
215
                // Initialize the progress elements
216
                elementGrid = new Grid(1, elementNo);
217
                elementGrid.setStyleName("progressbar-inner");
218
                elementGrid.setCellPadding(0);
219
                elementGrid.setCellSpacing(0);
220

    
221
                for (int loop = 0; loop < elementNo; loop++) {
222
                        Grid elm = new Grid(1, 1);
223
                        // elm.setHTML(0, 0, "&nbsp;");
224
                        elm.setHTML(0, 0, "");
225
                        elm.setStyleName("progressbar-blankbar");
226
                        elm.addStyleName("progressbar-bar");
227
                        elementGrid.setWidget(0, loop, elm);
228
                }
229

    
230
                // Create the container around the elements
231
                Grid containerGrid = new Grid(1, 1);
232
                containerGrid.setCellPadding(0);
233
                containerGrid.setCellSpacing(0);
234
                containerGrid.setWidget(0, 0, elementGrid);
235
                containerGrid.setStyleName("progressbar-outer");
236
                // containerGrid.setBorderWidth(1);
237

    
238
                // Set up the surrounding flex table based on the options
239
                int row = 0;
240
                if (showText)
241
                        barFrame.setWidget(row++, 0, textLabel);
242
                barFrame.setWidget(row++, 0, containerGrid);
243
                if (showRemaining)
244
                        barFrame.setWidget(row++, 0, remainLabel);
245

    
246
                barFrame.setWidth("100%");
247

    
248
                // Add the frame to the panel
249
                this.add(barFrame);
250

    
251
                // Initialize progress bar
252
                setProgress(0);
253
        }
254

    
255
        /**
256
         * Constructor without options
257
         *
258
         * @param elementNo The number of elements (bars) to show on the progress bar
259
         */
260
        public ProgressBar(int elementNo) {
261
                this(elementNo, 0);
262
        }
263

    
264
        /**
265
         * Set the current progress as a percentage
266
         *
267
         * @param percentage Set current percentage for the progress bar
268
         */
269
        public void setProgress(int percentage) {
270
                // Make sure we are error-tolerant
271
                if (percentage > 100)
272
                        percentage = 100;
273
                if (percentage < 0)
274
                        percentage = 0;
275

    
276
                // Set the internal variable
277
                progress = percentage;
278

    
279
                // Update the elements in the progress grid to
280
                // reflect the status
281
                int completed = elements * percentage / 100;
282
                for (int loop = 0; loop < elements; loop++) {
283
                        Grid elm = (Grid) elementGrid.getWidget(0, loop);
284
                        if (loop < completed) {
285
                                elm.setStyleName("progressbar-fullbar");
286
                                elm.addStyleName("progressbar-bar");
287
                        } else {
288
                                elm.setStyleName("progressbar-blankbar");
289
                                elm.addStyleName("progressbar-bar");
290
                        }
291
                }
292

    
293
                if (percentage > 0) {
294
                        // Calculate the new time remaining
295
                        long soFar = (System.currentTimeMillis() - startTime) / 1000;
296
                        long remaining = soFar * (100 - percentage) / percentage;
297
                        // Select the best UOM
298
                        String remainText = secondsMessage;
299
                        if (remaining > 120) {
300
                                remaining = remaining / 60;
301
                                remainText = minutesMessage;
302
                                if (remaining > 120) {
303
                                        remaining = remaining / 60;
304
                                        remainText = hoursMessage;
305
                                }
306
                        }
307
                        // Locate the position to insert out time remaining
308
                        int pos = remainText.indexOf("{0}");
309
                        if (pos >= 0) {
310
                                String trail = "";
311
                                if (pos + 3 < remainText.length())
312
                                        trail = remainText.substring(pos + 3);
313
                                remainText = remainText.substring(0, pos) + remaining + trail;
314
                        }
315
                        // Set the label
316
                        remainLabel.setText(remainText);
317
                } else
318
                        // If progress is 0, reset the start time
319
                        startTime = System.currentTimeMillis();
320
        }
321

    
322
        /**
323
         * Get the current progress as a percentage
324
         *
325
         * @return Current percentage for the progress bar
326
         */
327
        public int getProgress() {
328
                return progress;
329
        }
330

    
331
        /**
332
         * Get the text displayed above the progress bar
333
         *
334
         * @return the text
335
         */
336
        public String getText() {
337
                return textLabel.getText();
338
        }
339

    
340
        /**
341
         * Set the text displayed above the progress bar
342
         *
343
         * @param text the text to set
344
         */
345
        public void setText(String text) {
346
                textLabel.setText(text);
347
        }
348

    
349
        /**
350
         * Get the message used to format the time remaining text for hours
351
         *
352
         * @return the hours message
353
         */
354
        public String getHoursMessage() {
355
                return hoursMessage;
356
        }
357

    
358
        /**
359
         * Set the message used to format the time remaining text below the progress
360
         * bar. There are 3 messages used for hours, minutes and seconds
361
         * respectively. The message must contain a placeholder for the value. The
362
         * placeholder must be {0}. For example, the following is a valid message:
363
         * "Hours remaining: {0}"
364
         *
365
         * @param anHoursMessage the hours message to set
366
         */
367
        public void setHoursMessage(String anHoursMessage) {
368
                hoursMessage = anHoursMessage;
369
        }
370

    
371
        /**
372
         * Get the message used to format the time remaining text for minutes
373
         *
374
         * @return the minutesMessage
375
         */
376
        public String getMinutesMessage() {
377
                return minutesMessage;
378
        }
379

    
380
        /**
381
         * Set the message used to format the time remaining text below the progress
382
         * bar. There are 3 messages used for hours, minutes and seconds
383
         * respectively. The message must contain a placeholder for the value. The
384
         * placeholder must be {0}. For example, the following is a valid message:
385
         * "Minutes remaining: {0}"
386
         *
387
         * @param aMinutesMessage the minutes message to set
388
         */
389
        public void setMinutesMessage(String aMinutesMessage) {
390
                minutesMessage = aMinutesMessage;
391
        }
392

    
393
        /**
394
         * Get the message used to format the time remaining text for seconds
395
         *
396
         * @return the secondsMessage
397
         */
398
        public String getSecondsMessage() {
399
                return secondsMessage;
400
        }
401

    
402
        /**
403
         * Set the message used to format the time remaining text below the progress
404
         * bar. There are 3 messages used for hours, minutes and seconds
405
         * respectively. The message must contain a placeholder for the value. The
406
         * placeholder must be {0}. For example, the following is a valid message:
407
         * "Seconds remaining: {0}"
408
         *
409
         * @param aSecondsMessage the secondsMessage to set
410
         */
411
        public void setSecondsMessage(String aSecondsMessage) {
412
                secondsMessage = aSecondsMessage;
413
        }
414

    
415
}