1 /* 2 * $Id: StatusBar.java 178 2010-10-31 18:01:20Z roland $ 3 * Copyright (C) 2007 Roland Krueger 4 * 5 * Author: Roland Krueger (www.rolandkrueger.info) 6 * 7 * This file is part of RoKlib. 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public License 11 * as published by the Free Software Foundation; either version 2.1 of 12 * the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 22 * USA 23 */ 24 package info.rolandkrueger.roklib.ui.swing; 25 26 import java.awt.GridLayout; 27 import java.util.ArrayList; 28 import java.util.Timer; 29 import java.util.TimerTask; 30 31 import javax.swing.JLabel; 32 import javax.swing.JPanel; 33 import javax.swing.border.EmptyBorder; 34 import javax.swing.border.EtchedBorder; 35 36 /** 37 * This class represents a status bar that can be used to display status 38 * messages in a windowed application. The area of a status bar is divided into 39 * two parts. The bar's left half is used as display for general messages. Here, 40 * all types of messages can be displayed by the application. If desired, the 41 * right half of a status bar can be filled with specialized message fields. 42 * Such fields can be used to show the status of a some special part of the 43 * application. In a client-server application, it is conceivable to show the 44 * server address a client is connected to in such a field, for example. These 45 * specialized message fields are added to a status bar with 46 * {@link StatusBar#addElement(String, String)}.<br> 47 * <br> 48 * It is possible to display messages in the message area of a status bar that 49 * will be shown for a certain predefined period of time. This is done with 50 * {@link StatusBar#setTimedMessage(String)}. If the delay of a timed message - 51 * which can be defined through the constructor 52 * {@link StatusBar#StatusBar(long)} or with 53 * {@link StatusBar#setMessageDelay(long)} - has elapsed, the timed message is 54 * replaced by the ready message as provided by 55 * {@link StatusBar#setReadyMessage(String)}.<br> 56 * <br> 57 * <b>Example:</b> The following code will create a status bar as sketched 58 * below: <blockquote> 59 * 60 * <pre> 61 * StatusBar bar = new StatusBar (); 62 * bar.setReadyMessage ("Ready."); 63 * bar.addElement ("Msg. field 1", "Help text for message field 1."); 64 * bar.addElement ("Other msg. field", "Help text for the other message field."); 65 * 66 * +-------------------------------+--------------+------------------+ 67 * | Ready. | Msg. field 1 | Other msg. field | 68 * +-------------------------------+--------------+------------------+ 69 * </pre> 70 * 71 * </blockquote> 72 * 73 * @author Roland Krueger 74 */ 75 public class StatusBar extends JPanel implements HoverListener 76 { 77 private static final long serialVersionUID = 1777229355563005791L; 78 79 private JLabel mInfoLabel; 80 private JPanel mElementsPanel; 81 private Timer mTimer; 82 private long mDelay; 83 private String mReadyText = ""; 84 private String mCurrentMessage = ""; 85 private ArrayList<BarElement> mElements; 86 87 /** 88 * Default constructor. The duration of displaying a timed message is set to 2 89 * seconds. 90 * 91 * @see StatusBar#setTimedMessage(String) 92 */ 93 public StatusBar () 94 { 95 this (2000); 96 } 97 98 /** 99 * Constructs a {@link StatusBar} with the specified delay for timed messages. 100 * 101 * @see StatusBar#setTimedMessage(String) 102 * @param messageDelay 103 * delay in milliseconds for timed messages 104 */ 105 public StatusBar (long messageDelay) 106 { 107 mInfoLabel = new JLabel (); 108 setLayout (new GridLayout ()); 109 mInfoLabel.setBorder (new EtchedBorder (EtchedBorder.LOWERED)); 110 add (mInfoLabel); 111 mDelay = messageDelay; 112 mTimer = new Timer (); 113 mElementsPanel = new JPanel (); 114 mElements = new ArrayList<BarElement> (); 115 mElementsPanel.setLayout (new GridLayout ()); 116 setBorder (new EmptyBorder (1, 1, 1, 1)); 117 } 118 119 public void hoverStarted (Hoverable source) 120 { 121 if (source.getHoverText () == null) return; 122 mInfoLabel.setText (source.getHoverText ()); 123 } 124 125 public void hoverEnded (Hoverable source) 126 { 127 mInfoLabel.setText (mCurrentMessage); 128 } 129 130 /** 131 * Sets the ready message for this status bar. This message will be displayed 132 * in the message area if no other message is currently being shown. 133 * 134 * @param msg 135 * the ready message for this status bar. 136 */ 137 public void setReadyMessage (String msg) 138 { 139 mReadyText = msg; 140 mCurrentMessage = msg; 141 mInfoLabel.setText (msg); 142 } 143 144 /** 145 * A timed message will be displayed in the message area for a certain amount 146 * of time. This time can be configured either through the constructor 147 * {@link StatusBar#StatusBar(long)} or through method 148 * {@link StatusBar#setMessageDelay(long)}. After the delay has elapsed, the 149 * status bar's ready message is displayed again. 150 * 151 * @param msg 152 * the message to be displayed for some time 153 */ 154 public void setTimedMessage (String msg) 155 { 156 mCurrentMessage = msg; 157 mInfoLabel.setText (msg); 158 159 mTimer.schedule (new TimerTask () 160 { 161 public void run () 162 { 163 mCurrentMessage = mReadyText; 164 mInfoLabel.setText (mCurrentMessage); 165 } 166 }, mDelay); 167 } 168 169 /** 170 * Sets the amount of time in milliseconds of how long a timed message will be 171 * displayed. 172 * 173 * @see StatusBar#setTimedMessage(String) 174 * @param delay 175 * the amount of time in milliseconds of how long a timed message 176 * will be displayed 177 */ 178 public void setMessageDelay (long delay) 179 { 180 mDelay = delay; 181 } 182 183 /** 184 * Adds a specialized message field to the right half of the status bar. The 185 * specified <code>text</code> will be displayed in that field. The given 186 * <code>helpText</code> will be displayed in the general message area while 187 * the mouse cursor hovers over the specialized message field. Both of these 188 * text messages can be changed with 189 * {@link StatusBar#setElementText(int, String)} and 190 * {@link StatusBar#setElementHelpText(int, String)}, respectively. The 191 * <code>int</code> value that is returned by this method is the 192 * identification number of the new specialized message field. This number is 193 * needed for the first parameter of the <code>setElement*</code> methods and 194 * indicates the field that is meant to be changed. 195 * 196 * @see StatusBar#setElementHelpText(int, String) 197 * @see StatusBar#setElementText(int, String) 198 * @param text 199 * the text that will be displayed in the text area 200 * @param helpText 201 * help text for the text area that will be displayed in the general 202 * text area when the mouse hovers over the new text area 203 * @return an identification number that is needed to refer to the newly added 204 * text area 205 */ 206 public int addElement (String text, String helpText) 207 { 208 BarElement element = new BarElement (text, helpText); 209 element.addHoverListener (this); 210 if (mElements.size () == 0) 211 { 212 // rearrange layout if the first separate element is added 213 removeAll (); 214 setLayout (new GridLayout (1, 2)); 215 add (mInfoLabel); 216 add (mElementsPanel); 217 } 218 mElementsPanel.add (element); 219 mElements.add (element); 220 return mElements.indexOf (element); 221 } 222 223 /** 224 * Sets the text displayed by the spezialized message area with the given 225 * identification number. 226 * 227 * @param elementNr 228 * identification number as provided by 229 * {@link StatusBar#addElement(String, String)} which refers to the 230 * message field that is to be changed by this method 231 * @param text 232 * the text to be displayed by the message field 233 * @throws ArrayIndexOutOfBoundsException 234 * if the message field denoted by <code>elementNr</code> does not 235 * exist 236 */ 237 public void setElementText (int elementNr, String text) 238 { 239 if (elementNr > mElements.size () || elementNr < 0) 240 throw new ArrayIndexOutOfBoundsException (); 241 mElements.get (elementNr).setText (text); 242 } 243 244 /** 245 * Sets the help text that belongs to the spezialized message area with the 246 * given identification number. 247 * 248 * @param elementNr 249 * identification number as provided by 250 * {@link StatusBar#addElement(String, String)} which refers to the 251 * message field that is to be changed by this method 252 * @param helpText 253 * the text to be displayed by the message field 254 * @throws ArrayIndexOutOfBoundsException 255 * if the message field denoted by <code>elementNr</code> does not 256 * exist 257 */ 258 public void setElementHelpText (int elementNr, String helpText) 259 { 260 if (elementNr >= mElements.size () || elementNr < 0) 261 throw new ArrayIndexOutOfBoundsException (); 262 mElements.get (elementNr).setHelpText (helpText); 263 } 264 265 /** 266 * This class represents a single display area of a status bar. 267 * 268 * @author Roland Krueger 269 */ 270 private class BarElement extends JLabel implements Hoverable 271 { 272 private static final long serialVersionUID = 9159375387417999283L; 273 274 private String mHelpText; 275 private HoverManager mHoverManager; 276 277 public BarElement (String text, String helpText) 278 { 279 super (text); 280 setHelpText (helpText); 281 mHoverManager = new HoverManager (this); 282 addMouseListener (mHoverManager); 283 setBorder (new EtchedBorder (EtchedBorder.LOWERED)); 284 } 285 286 public BarElement (String text) 287 { 288 this (text, ""); 289 } 290 291 public void setText (String text) 292 { 293 super.setText (text); 294 } 295 296 public void setHelpText (String helpText) 297 { 298 mHelpText = helpText; 299 setToolTipText (helpText); 300 } 301 302 public String getHoverText () 303 { 304 return mHelpText; 305 } 306 307 public boolean addHoverListener (HoverListener listener) 308 { 309 return mHoverManager.addHoverListener (listener); 310 } 311 } 312 }