Statistics
| Branch: | Tag: | Revision:

root / web_client / src / org / gss_project / gss / web / client / ProgressBar.java @ f1ec19a9

History | View | Annotate | Download (10.6 kB)

1
/*
2
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.com>
3
 *
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
7
 *
8
 *    http://www.apache.org/licenses/LICENSE-2.0
9
 *
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.
15
 */
16

    
17
package org.gss_project.gss.web.client;
18

    
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;
23

    
24
/**
25
 * <P>
26
 * A simple progress bar that uses table elements to show progress and with a
27
 * basic time remaining calculation built in.
28
 * <P>
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
32
 * example:
33
 *
34
 * <PRE>
35
 * final ProgressBar progressBar = new ProgressBar(20, ProgressBar.SHOW_TIME_REMAINING + ProgressBar.SHOW_TEXT);
36
 * progressBar.setText(&quot;Doing something...&quot;);
37
 * RootPanel.get().add(progressBar);
38
 * Timer t = new Timer() {
39
 *
40
 *         public void run() {
41
 *                 int progress = progressBar.getProgress() + 4;
42
 *                 if (progress &gt; 100)
43
 *                         cancel();
44
 *                 progressBar.setProgress(progress);
45
 *         }
46
 * };
47
 * t.scheduleRepeating(1000);
48
 * </PRE>
49
 * <P>
50
 * How the time remaining is displayed can be controlled by setting the relevant
51
 * messages using the language of your choice.
52
 * <P>
53
 * The default setting for the messages are as follows:
54
 *
55
 * <PRE>
56
 * setSecondsMessage(&quot;Time remaining: {0} Seconds&quot;);
57
 * setMinutesMessage(&quot;Time remaining: {0} Minutes&quot;);
58
 * setHoursMessage(&quot;Time remaining: {0} Hours&quot;);
59
 * </PRE>
60
 * <P>
61
 * To reset the time remaining/set the start time, simply set the progress to
62
 * zero.
63
 * <P>
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.
66
 *
67
 * <PRE>
68
 * .progressbar-text {
69
 *     font-weight: bold;
70
 * }
71
 * .progressbar-remaining {
72
 *     font-size: 12px;
73
 *     font-style: italic;
74
 * }
75
 * .progressbar-outer {
76
 *     border: 1px solid black;
77
 * }
78
 * .progressbar-inner {
79
 *     border: 1px solid black;
80
 *     margin: 1px;
81
 * }
82
 * .progressbar-bar {
83
 *     width: 5px;
84
 *     height: 15px;
85
 *     margin: 1px;
86
 * }
87
 * .progressbar-fullbar {
88
 *     background: blue;
89
 * }
90
 * .progressbar-blankbar {
91
 *     background: #eee;
92
 * }
93
 *</PRE>
94
 * <P>
95
 * You can take advantage of the default style by adding the following to the
96
 * head of your HTML page.
97
 * <P>
98
 * &lt;link rel="stylesheet" type="text/css" href="style/gwl-progressBar.css">
99
 * <P>
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
102
 * combined.
103
 *
104
 * <PRE>
105
 * ProgressBar progressBar = new ProgressBar(20);
106
 * progressBar.addStyleName(&quot;progressbar-solid&quot;);
107
 * progressBar.addStyleName(&quot;progressbar-noborder&quot;);
108
 * </PRE>
109
 *
110
 * @author Bjarne Matzen - Bjarne[dot]Matzen[at]gmail[dot]com
111
 */
112

    
113
public class ProgressBar extends VerticalPanel {
114

    
115
        /**
116
         * Option to show text label above progress bar
117
         */
118
        public static final int SHOW_TEXT = 2;
119

    
120
        /**
121
         * Option to show time remaining
122
         */
123
        public static final int SHOW_TIME_REMAINING = 1;
124

    
125
        /**
126
         * The time the progress bar was started
127
         */
128
        private long startTime = System.currentTimeMillis();
129

    
130
        /**
131
         * The number of bar elements to show
132
         */
133
        private int elements = 20;
134

    
135
        /**
136
         * Time element text
137
         */
138
        private String secondsMessage = "Estimated time remaining: {0} Seconds";
139

    
140
        private String minutesMessage = "Estimated time remaining: {0} Minutes";
141

    
142
        private String hoursMessage = "Estimated time remaining: {0} Hours";
143

    
144
        /**
145
         * Current progress (as a percentage)
146
         */
147
        private int progress = 0;
148

    
149
        /**
150
         * This is the frame around the progress bar
151
         */
152
        private FlexTable barFrame = new FlexTable();
153

    
154
        /**
155
         * This is the grid used to show the elements
156
         */
157
        private Grid elementGrid;
158

    
159
        /**
160
         * This is the current text label below the progress bar
161
         */
162
        private Label remainLabel = new Label();
163

    
164
        /**
165
         * This is the current text label above the progress bar
166
         */
167
        private Label textLabel = new Label();
168

    
169
        /**
170
         * internal flags for options
171
         */
172
        private boolean showRemaining = false;
173

    
174
        private boolean showText = false;
175

    
176
        /**
177
         * Base constructor for this widget
178
         *
179
         * @param elementNo The number of elements (bars) to show on the progress bar
180
         * @param options The display options for the progress bar
181
         */
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)
187
                        showText = true;
188

    
189
                // Set element count
190
                elements = elementNo;
191

    
192
                // Styling
193
                remainLabel.setStyleName("progressbar-remaining");
194
                textLabel.setStyleName("progressbar-text");
195

    
196
                // Initialize the progress elements
197
                elementGrid = new Grid(1, elementNo);
198
                elementGrid.setStyleName("progressbar-inner");
199
                elementGrid.setCellPadding(0);
200
                elementGrid.setCellSpacing(0);
201

    
202
                for (int loop = 0; loop < elementNo; loop++) {
203
                        Grid elm = new Grid(1, 1);
204
                        // elm.setHTML(0, 0, "&nbsp;");
205
                        elm.setHTML(0, 0, "");
206
                        elm.setStyleName("progressbar-blankbar");
207
                        elm.addStyleName("progressbar-bar");
208
                        elementGrid.setWidget(0, loop, elm);
209
                }
210

    
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);
218

    
219
                // Set up the surrounding flex table based on the options
220
                int row = 0;
221
                if (showText)
222
                        barFrame.setWidget(row++, 0, textLabel);
223
                barFrame.setWidget(row++, 0, containerGrid);
224
                if (showRemaining)
225
                        barFrame.setWidget(row++, 0, remainLabel);
226

    
227
                barFrame.setWidth("100%");
228

    
229
                // Add the frame to the panel
230
                this.add(barFrame);
231

    
232
                // Initialize progress bar
233
                setProgress(0);
234
        }
235

    
236
        /**
237
         * Constructor without options
238
         *
239
         * @param elementNo The number of elements (bars) to show on the progress bar
240
         */
241
        public ProgressBar(int elementNo) {
242
                this(elementNo, 0);
243
        }
244

    
245
        /**
246
         * Set the current progress as a percentage
247
         *
248
         * @param percentage Set current percentage for the progress bar
249
         */
250
        public void setProgress(int percentage) {
251
                // Make sure we are error-tolerant
252
                if (percentage > 100)
253
                        percentage = 100;
254
                if (percentage < 0)
255
                        percentage = 0;
256

    
257
                // Set the internal variable
258
                progress = percentage;
259

    
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");
268
                        } else {
269
                                elm.setStyleName("progressbar-blankbar");
270
                                elm.addStyleName("progressbar-bar");
271
                        }
272
                }
273

    
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;
286
                                }
287
                        }
288
                        // Locate the position to insert out time remaining
289
                        int pos = remainText.indexOf("{0}");
290
                        if (pos >= 0) {
291
                                String trail = "";
292
                                if (pos + 3 < remainText.length())
293
                                        trail = remainText.substring(pos + 3);
294
                                remainText = remainText.substring(0, pos) + remaining + trail;
295
                        }
296
                        // Set the label
297
                        remainLabel.setText(remainText);
298
                } else
299
                        // If progress is 0, reset the start time
300
                        startTime = System.currentTimeMillis();
301
        }
302

    
303
        /**
304
         * Get the current progress as a percentage
305
         *
306
         * @return Current percentage for the progress bar
307
         */
308
        public int getProgress() {
309
                return progress;
310
        }
311

    
312
        /**
313
         * Get the text displayed above the progress bar
314
         *
315
         * @return the text
316
         */
317
        public String getText() {
318
                return textLabel.getText();
319
        }
320

    
321
        /**
322
         * Set the text displayed above the progress bar
323
         *
324
         * @param text the text to set
325
         */
326
        public void setText(String text) {
327
                textLabel.setText(text);
328
        }
329

    
330
        /**
331
         * Get the message used to format the time remaining text for hours
332
         *
333
         * @return the hours message
334
         */
335
        public String getHoursMessage() {
336
                return hoursMessage;
337
        }
338

    
339
        /**
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}"
345
         *
346
         * @param anHoursMessage the hours message to set
347
         */
348
        public void setHoursMessage(String anHoursMessage) {
349
                hoursMessage = anHoursMessage;
350
        }
351

    
352
        /**
353
         * Get the message used to format the time remaining text for minutes
354
         *
355
         * @return the minutesMessage
356
         */
357
        public String getMinutesMessage() {
358
                return minutesMessage;
359
        }
360

    
361
        /**
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}"
367
         *
368
         * @param aMinutesMessage the minutes message to set
369
         */
370
        public void setMinutesMessage(String aMinutesMessage) {
371
                minutesMessage = aMinutesMessage;
372
        }
373

    
374
        /**
375
         * Get the message used to format the time remaining text for seconds
376
         *
377
         * @return the secondsMessage
378
         */
379
        public String getSecondsMessage() {
380
                return secondsMessage;
381
        }
382

    
383
        /**
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}"
389
         *
390
         * @param aSecondsMessage the secondsMessage to set
391
         */
392
        public void setSecondsMessage(String aSecondsMessage) {
393
                secondsMessage = aSecondsMessage;
394
        }
395

    
396
}