001 /*
002 * Copyright 2002-2007 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005 * use this file except in compliance with the License. You may obtain a copy of
006 * the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013 * License for the specific language governing permissions and limitations under
014 * the License.
015 */
016 package org.springframework.richclient.application.statusbar.support;
017
018 import java.awt.BorderLayout;
019 import java.awt.Dimension;
020 import java.awt.Insets;
021 import java.awt.event.ActionEvent;
022 import java.awt.event.ActionListener;
023
024 import javax.swing.BorderFactory;
025 import javax.swing.Icon;
026 import javax.swing.JButton;
027 import javax.swing.JComponent;
028 import javax.swing.JPanel;
029 import javax.swing.JProgressBar;
030 import javax.swing.UIManager;
031 import javax.swing.border.BevelBorder;
032 import javax.swing.border.Border;
033
034 import org.springframework.richclient.application.ApplicationServicesLocator;
035 import org.springframework.richclient.factory.AbstractControlFactory;
036 import org.springframework.richclient.image.IconSource;
037 import org.springframework.richclient.progress.ProgressMonitor;
038 import org.springframework.util.StringUtils;
039
040 /**
041 * <code>ProgressMonitor</code> implementation that handles its own controls:
042 * <ul>
043 * <li>a <code>JProgressBar</code> to show the progress to the user</li>
044 * <li>optionally a <code>JButton</code> to allow the user to cancel the
045 * current task</li>
046 * </ul>
047 * <p>
048 * Initally the progress bar and button are hidden, and shown when a task is
049 * running longer than the <code>delayProgress</code> property (default is 500
050 * ms).
051 *
052 * @author Peter De Bruycker
053 */
054 public class StatusBarProgressMonitor extends AbstractControlFactory implements
055 ProgressMonitor {
056
057 /** Progress bar creation is delayed by this ms */
058 public static final int DEFAULT_DELAY_PROGRESS = 500;
059
060 public static final int UNKNOWN = -1;
061
062 private JButton cancelButton;
063
064 private boolean cancelEnabled = true;
065
066 private Icon cancelIcon;
067
068 private JPanel control;
069
070 private boolean isCanceled;
071
072 private JProgressBar progressBar;
073
074 private long startTime;
075
076 private String taskName;
077
078 private int delayProgress = DEFAULT_DELAY_PROGRESS;
079
080 protected JButton createCancelButton() {
081 JButton cancelButton = new JButton();
082 cancelButton.setBorderPainted(false);
083 cancelButton.setIcon(getCancelIcon());
084 cancelButton.setMargin(new Insets(0, 0, 0, 0));
085
086 return cancelButton;
087 }
088
089 protected JComponent createControl() {
090 control = new JPanel(new BorderLayout());
091
092 cancelButton = createCancelButton();
093 cancelButton.addActionListener(new ActionListener() {
094 public void actionPerformed(ActionEvent e) {
095 logger.info("Requesting task cancellation...");
096 setCanceled(true);
097 }
098 });
099 progressBar = createProgressBar();
100
101 control.add(progressBar);
102 control.add(cancelButton, BorderLayout.LINE_END);
103
104 Border bevelBorder = BorderFactory.createBevelBorder(BevelBorder.LOWERED, UIManager
105 .getColor("controlHighlight"), UIManager.getColor("controlShadow"));
106 Border emptyBorder = BorderFactory.createEmptyBorder(1, 3, 1, 3);
107 control.setBorder(BorderFactory.createCompoundBorder(bevelBorder, emptyBorder));
108
109 // initially hide the control
110 hideProgress();
111
112 return control;
113 }
114
115 protected JProgressBar createProgressBar() {
116 JProgressBar progressBar = new JProgressBar();
117 progressBar.setPreferredSize(new Dimension(200, 17));
118 progressBar.setStringPainted(true);
119
120 return progressBar;
121 }
122
123 public void done() {
124 startTime = 0;
125 if (progressBar != null) {
126 progressBar.setValue(progressBar.getMaximum());
127 progressBar.setString("");
128 }
129 hideProgress();
130 }
131
132 public Icon getCancelIcon() {
133 if (cancelIcon == null) {
134 cancelIcon = ((IconSource) ApplicationServicesLocator.services()
135 .getService(IconSource.class)).getIcon("cancel.icon");
136 }
137
138 return cancelIcon;
139 }
140
141 protected JProgressBar getProgressBar() {
142 return progressBar;
143 }
144
145 private void hideButton() {
146 cancelButton.setEnabled(cancelEnabled);
147 cancelButton.setVisible(false);
148 }
149
150 protected void hideProgress() {
151 if (progressBar.isVisible()) {
152 progressBar.setVisible(false);
153 cancelButton.setVisible(false);
154 }
155 }
156
157 public boolean isCanceled() {
158 return isCanceled;
159 }
160
161 public void setCanceled(boolean b) {
162 isCanceled = b;
163 cancelButton.setEnabled(!b);
164 }
165
166 public void setCancelEnabled(boolean enabled) {
167 cancelEnabled = enabled;
168 if (progressBar.isVisible() && !cancelButton.isVisible() && enabled) {
169 showButton();
170 } else {
171 hideButton();
172 }
173 }
174
175 public void setCancelIcon(Icon icon) {
176 cancelIcon = icon;
177 if (cancelButton != null) {
178 cancelButton.setIcon(icon);
179 }
180 }
181
182 private void showButton() {
183 cancelButton.setEnabled(cancelEnabled);
184 cancelButton.setVisible(true);
185 }
186
187 private void showProgress() {
188 if (!progressBar.isVisible()) {
189 if (cancelEnabled) {
190 showButton();
191 }
192 progressBar.setVisible(true);
193 }
194 }
195
196 public void subTaskStarted(String name) {
197 String text;
198 if (name.length() == 0) {
199 text = name;
200 } else {
201 if (StringUtils.hasText(taskName)) {
202 text = taskName + " - " + name;
203 } else {
204 text = name;
205 }
206 }
207 progressBar.setString(text);
208 }
209
210 public void taskStarted(String name, int totalWork) {
211 startTime = System.currentTimeMillis();
212 isCanceled = false;
213 if (totalWork == UNKNOWN) {
214 progressBar.setIndeterminate(true);
215 } else {
216 progressBar.setIndeterminate(false);
217 progressBar.setMaximum(totalWork);
218 progressBar.setValue(0);
219 }
220 taskName = name;
221 progressBar.setString(taskName);
222 showProgress();
223 }
224
225 public void worked(int work) {
226 if (!progressBar.isVisible()) {
227 if ((System.currentTimeMillis() - startTime) > delayProgress) {
228 control.setVisible(true);
229 }
230 }
231 progressBar.setValue((int) work);
232
233 if (progressBar.isStringPainted()) {
234 progressBar.setString(((int) work) + "%");
235 }
236 }
237
238 public void setDelayProgress(int delayProgress) {
239 this.delayProgress = delayProgress;
240 }
241 }