View Javadoc

1   /*
2    * $HeadURL: $
3    * $Date: $
4    * $Revision: $
5    * $Author: $
6    * 
7    * Copyright (c) 2005 MindTree Consulting Ltd. 
8    * 
9    * This file is part of Insight.
10   * 
11   * Insight is free software: you can redistribute it and/or modify it under the 
12   * terms of the GNU General Public License as published by the Free Software 
13   * Foundation, either version 3 of the License, or (at your option) any later 
14   * version.
15   * 
16   * Insight is distributed in the hope that it will be useful, but 
17   * WITHOUT ANY WARRANTY; without even the implied warranty of 
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
19   * Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public License along with 
22   * Insight.  If not, see <http://www.gnu.org/licenses/>.
23   */
24  package com.mindtree.techworks.insight.gui.widgets;
25  
26  import java.awt.Component;
27  import java.awt.Dimension;
28  import java.awt.GridBagConstraints;
29  import java.awt.GridBagLayout;
30  import java.awt.Toolkit;
31  import java.awt.event.ActionEvent;
32  import java.awt.event.ActionListener;
33  import java.util.ArrayList;
34  
35  import javax.swing.JPanel;
36  import javax.swing.JProgressBar;
37  import javax.swing.JSeparator;
38  import javax.swing.Timer;
39  
40  import com.mindtree.techworks.insight.InsightConstants;
41  
42  /**
43  *
44  * The <code>StatusBar</code> class is a GUI component that may be used for
45  * displaying status messages or progress indicator with static text. This status bar number of partitions declared
46  * in InsightConstants plus 1. The last partition is meant for statistics display such as line number, current page
47  * and total number of pages of event summary e.t.c. Each partition contains a "indeterminate" JProgressBar that supports
48  * static text and/or a progress indicator. 
49  * 
50  * @author  Regunath B
51  * @version 1.0, 04/12/28
52  */
53  
54  public class StatusBar extends JPanel {
55  	
56  	/**
57  	 * Used for object serialization
58  	 */
59  	private static final long serialVersionUID = -6654725016958741987L;
60  	
61  	/*
62  	 * Useful constants for the preferred dimensions of this StatusBar
63  	 */
64  	private static final int WIDTH = 900;
65  	private static final int HEIGHT = 20;
66  	private static final int SEPARATOR_WIDTH = 2;
67  	
68  	/*
69  	 * The maximum length of the display text for this StatusBar
70  	 */
71  	private static final int MAX_TEXT_LENGTH = 100;
72  		
73  	/*
74  	 * Singleton static instance of this class
75  	 */
76  	private static StatusBar instance;
77  	
78  	/*
79  	 * List that contains the JProgressBar instances 
80  	 */
81  	private ArrayList progressBarList;
82  	
83  	/*
84  	 * Layout definition.
85  	 */
86  	private GridBagLayout gl;
87  	private GridBagConstraints gc;
88  	
89  	/*
90  	 * Count of GUI components displayed on this JPanel
91  	 */
92  	private int componentCount = -1;
93  	
94  	/**
95  	 * Private constructor to prevent multiple instances
96  	 * @see #getInstance() to obtain instance of this class
97  	 */
98  	private StatusBar(int partitionCount) {
99  		gl = new GridBagLayout();
100 		gc = new GridBagConstraints();
101 		setLayout(gl);
102 		
103 		progressBarList = new ArrayList(partitionCount);
104 
105 		for (int i = 0; i < partitionCount; i++) {
106 			JProgressBar progressBar = new JProgressBar(JProgressBar.HORIZONTAL);
107 			initializeProgressBar(progressBar);
108 			progressBarList.add(progressBar);
109 		}
110 		setPreferredSize(getIdealPreferredSize());
111 	}
112 	
113 	/**
114 	 * Returns the singleton instance of this class.
115 	 * @return instance of this class
116 	 */
117 	public synchronized static final StatusBar getInstance() {
118 		if (instance == null) {
119 			instance = new StatusBar(InsightConstants.SB_PARTITION_COUNT + 1);
120 		}
121 		return instance;
122 	}
123 	
124 	/**
125 	 * Sets the display text of the partition identified by the specified partition index
126 	 * The display is automatically cleared after a lease duration if <code>animate</code>
127 	 * is false.
128 	 * @param partitionIndex valid 0 based index of the partition
129 	 * @param text the Text string to be displayed
130 	 * @param animate true if the "indeterminate" animation of the progress indicator is needed, false otherwise
131 	 */
132 	public void setDisplayText(int partitionIndex, String text, boolean animate) {
133 		if (partitionIndex >= InsightConstants.SB_PARTITION_COUNT) {
134 			return;
135 		}
136 		this.setDisplayTextPrivate(partitionIndex, text, animate, true);
137 	}
138 	
139 	/**
140 	 * Sets the specified text in the statistics display partition of the Status bar. Note that the text is not
141 	 * automatically cleared after the usual default duration
142 	 * @param text the text to be displayed in the statistics partition
143 	 */
144 	public void setStatisticsDisplayText(String text) {
145 		this.setDisplayTextPrivate(InsightConstants.SB_PARTITION_COUNT, text, false, false);
146 	}
147 
148 	/**
149 	 * Clears the statictics display text i.e the text displayed in the
150 	 * partition dedicated for statistics display.
151 	 */
152 	public void clearStatisticsDisplayText() {
153 		this.clearDisplayPrivate(InsightConstants.SB_PARTITION_COUNT);
154 	}
155 
156 	/**
157 	 * Clears the display text of the partition identified by the specified partition index
158 	 * @param partitionIndex valid 0 based index of the partition
159 	 */
160 	public void clearDisplay(int partitionIndex) {
161 		if (partitionIndex >= InsightConstants.SB_PARTITION_COUNT) {
162 			return;
163 		}
164 		this.clearDisplayPrivate(partitionIndex);
165 	}
166 	
167 	/**
168 	 * Helper method that returns the best size between this component's preferred size and that ideal 
169 	 * for the display size
170 	 * @return Dimension most appropriate for this widget
171 	 */
172 	private Dimension getIdealPreferredSize() {
173 		Dimension dimension = null;
174 		Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
175 		dimension = new Dimension((int)Math.min(screenDim.getWidth() - 50, WIDTH),
176 				HEIGHT);
177 		return dimension;		
178 	}        		
179 	
180 	/**
181 	 * Helper method that clears the display text of the partition identified by the specified partition index
182 	 * @param partitionIndex valid 0 based index of the partition
183 	 */
184 	private void clearDisplayPrivate(int partitionIndex) {
185 		JProgressBar progressBar = (JProgressBar)progressBarList.get(partitionIndex);
186 		progressBar.setString("");
187 		progressBar.setIndeterminate(false);						
188 	}
189 	
190 	/**
191 	 * Helper method to set the display text in the status bar partitions.
192 	 * @see #setDisplayText(int, String, boolean)
193 	 * @see #setStatisticsDisplayText(String)
194 	 * @param partitionIndex valid 0 based index of the partition
195 	 * @param text the Text string to be displayed
196 	 * @param animate true if the "indeterminate" animation of the progress indicator is needed, false otherwise
197 	 * @param enableDisplayLease true if the display is leased for the default duration, false otherwise
198 	 */
199 	private void setDisplayTextPrivate(int partitionIndex, String text, boolean animate, boolean enableDisplayLease) {
200 		JProgressBar progressBar = (JProgressBar)progressBarList.get(partitionIndex);
201 		text = text.substring(0,Math.min(text.length(), MAX_TEXT_LENGTH));
202 		progressBar.setString(text);
203 		int stringSizeInPixels = progressBar.getFontMetrics(progressBar.getFont()).stringWidth(text);
204 		if (stringSizeInPixels > progressBar.getWidth()) {
205 			// Indicate to the LayoutManager that the progress bar will need to be resized to 
206 			// accomodate the text
207 			progressBar.invalidate();
208 			this.validate();
209 		}
210 		progressBar.setIndeterminate(animate);
211 		if (!animate && enableDisplayLease) { // Start the time to clear the text after the lease duration
212 			Timer timer = new Timer(InsightConstants.DISPLAY_INTERVAL, new DisplayLease(partitionIndex));
213 			timer.setRepeats(false);
214 			timer.start();
215 		}		
216 	}
217 
218 	/**
219 	 * Helper method that initializes and adds the specified JProgressBar to this StatusBar 
220 	 * @param progressBar the JProgressBar to initialize
221 	 */
222 	private void initializeProgressBar(JProgressBar progressBar) {
223 		JSeparator separator = new JSeparator(JSeparator.VERTICAL);
224 		separator.setPreferredSize(new Dimension(SEPARATOR_WIDTH,HEIGHT));
225 		addComponent(separator,++componentCount,0,0,0);
226 		progressBar.setBorderPainted(false);
227 		progressBar.setStringPainted(true);
228 		progressBar.setString("");
229 		addComponent(progressBar,++componentCount,0,1,0);
230 	}	
231 	
232 	/**
233 	 * Adds the specified component to this panel using the specified constraints.
234 	 **/
235 	private final void addComponent(Component c, int gridx, int gridy, int weightx,
236 		int weighty) {
237 		gc.fill = GridBagConstraints.HORIZONTAL;
238 		gc.anchor = GridBagConstraints.NORTHWEST;
239 		gc.gridx = gridx;
240 		gc.gridy = gridy;
241 		gc.weightx = weightx;
242 		gc.weighty = weighty;
243 		gl.setConstraints( c, gc);
244 		add(c);
245 	}
246 	
247 	/**
248 	 * Helper class that implements the ActionListener interface for notifications from
249 	 * the Timer. Clears the display of the respective status bar partition on notification. 
250 	 */
251 	private class DisplayLease implements ActionListener {
252 		/*
253 		 * The partition index to clear
254 		 */
255 		private int partitionIndex;
256 		
257 		/**
258 		 * Constructor for this class
259 		 * @param partitionIndex the parttion index to be cleared after the display lease expires
260 		 */
261 		public DisplayLease(int partitionIndex) {
262 			this.partitionIndex = partitionIndex;
263 		}
264 		
265 		/**
266 		 * ActionListener interface impementation
267 		 * @see ActionListener#actionPerformed(java.awt.event.ActionEvent)
268 		 */
269 		public void actionPerformed(ActionEvent e) {
270 			clearDisplay(this.partitionIndex);
271 		}		
272 	}
273 	
274 }