View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans-Common.
5    *
6    * CosyBeans-Common is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans-Common is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans-Common.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.components;
21  
22  import java.awt.GridBagConstraints;
23  import java.awt.GridBagLayout;
24  import java.awt.event.ActionEvent;
25  import java.awt.event.ActionListener;
26  
27  import javax.swing.JLabel;
28  import javax.swing.JProgressBar;
29  import javax.swing.Timer;
30  
31  
32  /**
33   * Simple progress bar dialog for displaying <code>ProgressMonitor</code>
34   * enabled tasks. Implementation takes care to prevent GUI freezes during
35   * extensive tasks.
36   *
37   * @author <a href="mailto:ales.pucelj@cosylab.com">Ales Pucelj</a>
38   * @version $id$
39   */
40  public class ProgressDialog extends javax.swing.JDialog
41  {
42  	private static final long serialVersionUID = 1L;
43  	private JLabel statusLabel;
44  	private JProgressBar progressBar;
45  	private AbstractProgressTask task;
46  	private Timer timer;
47  
48  	/**
49  	 * Timer that will update GUI twice a second if regardless of events
50  	 * generated from task. This ensures consistent GUI updates even if task
51  	 * does not report progress frequently.
52  	 */
53  	protected class TimerListener implements ActionListener
54  	{
55  		/**
56  		 * Updates GUI.
57  		 *
58  		 * @param e event.
59  		 */
60  		public void actionPerformed(ActionEvent e)
61  		{
62  			updateState();
63  		}
64  	}
65  
66  	/**
67  	 * Listens for status updates from thread implementing ProgressMonitor and
68  	 * updates interface accordingly.
69  	 */
70  	protected class StateListener implements ProgressListener
71  	{
72  		/**
73  		 * Updates GUI with new progress value.
74  		 *
75  		 * @param e event.
76  		 */
77  		public void progress(ProgressEvent e)
78  		{
79  			updateState();
80  		}
81  
82  		/**
83  		 * Hides the dialog.
84  		 *
85  		 * @param e event.
86  		 */
87  		public void taskComplete(ProgressEvent e)
88  		{
89  			updateState();
90  			setVisible(false);
91  		}
92  
93  		/**
94  		 * Hides the dialog.
95  		 *
96  		 * @param e event.
97  		 */
98  		public void taskInterruped(ProgressEvent e)
99  		{
100 			setStatus(e.getStatus());
101 			setVisible(false);
102 		}
103 
104 		/**
105 		 * No action, since dialog is expected to be already visible.
106 		 *
107 		 * @param e event.
108 		 */
109 		public void taskStarted(ProgressEvent e)
110 		{
111 			//			show();
112 		}
113 	}
114 
115 	/**
116 	 * ProgressDialog constructor comment.
117 	 *
118 	 * @param task this dialog will monitor.
119 	 */
120 	public ProgressDialog(AbstractProgressTask task)
121 	{
122 		super();
123 		this.task = task;
124 		initialize();
125 	}
126 
127 	private GridBagConstraints createConstraints(int x, int y)
128 	{
129 		GridBagConstraints gc = new GridBagConstraints();
130 		gc.gridx = x;
131 		gc.gridy = y;
132 		gc.fill = GridBagConstraints.HORIZONTAL;
133 		gc.weightx = 1.0;
134 		gc.weighty = 0.0;
135 		gc.anchor = GridBagConstraints.WEST;
136 		gc.insets = new java.awt.Insets(4, 4, 4, 4);
137 
138 		return gc;
139 	}
140 
141 	private void initialize()
142 	{
143 		setSize(350, 100);
144 		getContentPane().setLayout(new GridBagLayout());
145 
146 		statusLabel = new JLabel();
147 		getContentPane().add(statusLabel, createConstraints(0, 0));
148 
149 		progressBar = new JProgressBar();
150 		getContentPane().add(progressBar, createConstraints(0, 1));
151 	}
152 
153 	/**
154 	 * Starts the task associated with this component.
155 	 */
156 	public void performTask()
157 	{
158 		TimerListener tl = new TimerListener();
159 		ProgressListener pl = new StateListener();
160 
161 		timer = new Timer(500, tl);
162 		task.addProgressListener(pl);
163 
164 		task.setPriority(Thread.MIN_PRIORITY);
165 		task.start();
166 		timer.start();
167 
168 		setVisible(true);
169 	}
170 
171 	protected void setProgress(int value)
172 	{
173 		progressBar.setValue(value);
174 	}
175 
176 	protected void setProgressBounds(int min, int max)
177 	{
178 		if (min >= max) {
179 			return;
180 		}
181 
182 		progressBar.setMinimum(min);
183 		progressBar.setMaximum(max);
184 		progressBar.setValue(min);
185 		progressBar.repaint();
186 	}
187 
188 	protected void setStatus(String status)
189 	{
190 		statusLabel.setText(status);
191 	}
192 
193 	protected void updateState()
194 	{
195 		ProgressDialog owner = ProgressDialog.this;
196 
197 		int current = task.getCurrent();
198 		int total = task.getTotal();
199 
200 		owner.progressBar.setVisible(total > -1);
201 
202 		owner.setProgressBounds(0, total);
203 		owner.setProgress(current);
204 
205 		setStatus(owner.task.getStatus());
206 	}
207 }
208 
209 /* __oOo__ */