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 }