001 /* 002 * Copyright 2002-2004 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of 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, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.springframework.richclient.command.config; 017 018 import java.awt.Color; 019 import java.awt.Image; 020 021 import javax.swing.AbstractButton; 022 import javax.swing.Action; 023 import javax.swing.Icon; 024 import javax.swing.KeyStroke; 025 026 import org.springframework.binding.value.support.AbstractPropertyChangePublisher; 027 import org.springframework.core.style.ToStringCreator; 028 import org.springframework.richclient.command.AbstractCommand; 029 import org.springframework.richclient.core.ColorConfigurable; 030 import org.springframework.richclient.core.DescribedElement; 031 import org.springframework.richclient.core.DescriptionConfigurable; 032 import org.springframework.richclient.core.VisualizedElement; 033 import org.springframework.richclient.util.Assert; 034 035 /** 036 * A parameter object that contains the information to describe the visual representation of a 037 * command object. 038 * 039 * 040 * @author Keith Donald 041 */ 042 public class CommandFaceDescriptor extends AbstractPropertyChangePublisher implements DescribedElement, 043 VisualizedElement, CommandLabelConfigurable, DescriptionConfigurable, CommandIconConfigurable, ColorConfigurable { 044 045 /** The property name used when firing events for the {@code labelInfo} property. */ 046 public static final String LABEL_INFO_PROPERTY = "labelInfo"; 047 048 /** The property name used when firing events for the {@code icon} property. */ 049 public static final String ICON_PROPERTY = "icon"; 050 051 /** The property name used when firing events for the {@code largeIcon} property. */ 052 public static final String LARGE_ICON_PROPERTY = "largeIcon"; 053 054 /** The property name used when firing events for the {@code iconInfo} property. */ 055 public static final String ICON_INFO_PROPERTY = "iconInfo"; 056 057 /** The property name used when firing events for the {@code largeIconInfo} property. */ 058 public static final String LARGE_ICON_INFO_PROPERTY = "largeIconInfo"; 059 060 /** The property name used when firing events for the {@code background} property. */ 061 public static final String BACKGROUND_PROPERTY = "background"; 062 063 /** The property name used when firing events for the {@code foreground} property. */ 064 public static final String FOREGROUND_PROPERTY = "foreground"; 065 066 private String caption; 067 068 private String description; 069 070 private Color background; 071 072 private Color foreground; 073 074 private CommandButtonLabelInfo labelInfo; 075 076 private CommandButtonIconInfo iconInfo = CommandButtonIconInfo.BLANK_ICON_INFO; 077 078 private CommandButtonIconInfo largeIconInfo = CommandButtonIconInfo.BLANK_ICON_INFO; 079 080 /** 081 * Creates a new {@code CommandFaceDescriptor} that uses the given encoded label descriptor 082 * to provide the label properties. 083 * 084 * @param encodedLabel The encoded label descriptor. May be null or empty to define a blank label. 085 * 086 * @see CommandButtonLabelInfo#valueOf(String) 087 */ 088 public CommandFaceDescriptor(String encodedLabel) { 089 this(encodedLabel, null, null); 090 } 091 092 /** 093 * Creates a new {@code CommandFaceDescriptor} that uses the given encoded label descriptor 094 * to provide the label properties, along with the given icon and caption. 095 * 096 * @param encodedLabel The encoded label descriptor. May be null or empty. 097 * @param icon The main default icon to be displayed by the command. May be null. 098 * @param caption The caption to be displayed on rollover of the command. May be null or empty. 099 * 100 * @see CommandButtonLabelInfo#valueOf(String) 101 */ 102 public CommandFaceDescriptor(String encodedLabel, Icon icon, String caption) { 103 this.labelInfo = CommandButtonLabelInfo.valueOf(encodedLabel); 104 if (icon != null) { 105 this.iconInfo = new CommandButtonIconInfo(icon); 106 } 107 this.caption = caption; 108 } 109 110 /** 111 * Creates a new {@code CommandFaceDescriptor} with a blank label and no icon or caption. 112 */ 113 public CommandFaceDescriptor() { 114 this(CommandButtonLabelInfo.BLANK_BUTTON_LABEL); 115 } 116 117 /** 118 * Creates a new {@code CommandFaceDescriptor} whose label information is provided by the 119 * given {@link CommandButtonLabelInfo} instance. 120 * 121 * @param labelInfo The label information for the command. 122 */ 123 public CommandFaceDescriptor(CommandButtonLabelInfo labelInfo) { 124 Assert.notNull(labelInfo, "The labelInfo property is required"); 125 this.labelInfo = labelInfo; 126 } 127 128 /** 129 * Returns true if no command label information is provided by this descriptor. 130 * 131 * @return true if there is no label information, false otherwise. 132 */ 133 public boolean isBlank() { 134 return labelInfo == CommandButtonLabelInfo.BLANK_BUTTON_LABEL; 135 } 136 137 /** 138 * Returns the label text specified by this descriptor. 139 * 140 * @return The label text. May be null or empty. 141 */ 142 public String getText() { 143 return labelInfo.getText(); 144 } 145 146 /** 147 * {@inheritDoc} 148 */ 149 public String getDisplayName() { 150 return getText(); 151 } 152 153 /** 154 * {@inheritDoc} 155 */ 156 public String getCaption() { 157 return caption; 158 } 159 160 /** 161 * {@inheritDoc} 162 */ 163 public String getDescription() { 164 return description; 165 } 166 167 /** 168 * Returns the mnemonic to be associated with the command. 169 * 170 * @return The command mnemonic. 171 */ 172 public int getMnemonic() { 173 return labelInfo.getMnemonic(); 174 } 175 176 /** 177 * Returns the zero-based index of the mnemonic character within the label text associated with 178 * the command. 179 * 180 * @return The mnemonic index, or -1 if no mnemonic index is associated with the command. 181 */ 182 public int getMnemonicIndex() { 183 return labelInfo.getMnemonicIndex(); 184 } 185 186 /** 187 * {@inheritDoc} 188 */ 189 public Image getImage() { 190 191 if (this.iconInfo == null) { 192 return null; 193 } 194 else { 195 return iconInfo.getImage(); 196 } 197 198 } 199 200 /** 201 * {@inheritDoc} 202 */ 203 public Icon getIcon() { 204 205 if (this.iconInfo == null) { 206 return null; 207 } 208 else { 209 return iconInfo.getIcon(); 210 } 211 212 } 213 214 /** 215 * Returns the main default large icon associated with the command. 216 * 217 * @return The large icon, or null. 218 */ 219 public Icon getLargeIcon() { 220 221 if (this.largeIconInfo == null) { 222 return null; 223 } 224 else { 225 return largeIconInfo.getIcon(); 226 } 227 228 } 229 230 /** 231 * Returns the keystroke accelerator associated with the command. 232 * 233 * @return The keystroke accelerator, or null. 234 */ 235 public KeyStroke getAccelerator() { 236 return labelInfo.getAccelerator(); 237 } 238 239 /** 240 * Returns the command button label info object. 241 * 242 * @return The command button label info, or null. 243 */ 244 protected CommandButtonLabelInfo getLabelInfo() { 245 return labelInfo; 246 } 247 248 /** 249 * Returns the label information for the command. 250 * 251 * @return The label information, never null. 252 */ 253 protected CommandButtonIconInfo getIconInfo() { 254 return iconInfo; 255 } 256 257 /** 258 * Returns the large icon information object for the command. 259 * 260 * @return The large icon information, or null. 261 */ 262 protected CommandButtonIconInfo getLargeIconInfo() { 263 return largeIconInfo; 264 } 265 266 /** 267 * {@inheritDoc} 268 */ 269 public void setCaption(String shortDescription) { 270 String old = this.caption; 271 this.caption = shortDescription; 272 firePropertyChange(DescribedElement.CAPTION_PROPERTY, old, this.caption); 273 } 274 275 /** 276 * {@inheritDoc} 277 */ 278 public void setDescription(String longDescription) { 279 String old = this.description; 280 this.description = longDescription; 281 firePropertyChange(DescribedElement.DESCRIPTION_PROPERTY, old, this.description); 282 } 283 284 /** 285 * {@inheritDoc} 286 */ 287 public void setBackground(Color background) { 288 Color old = this.background; 289 this.background = background; 290 firePropertyChange(BACKGROUND_PROPERTY, old, this.background); 291 } 292 293 /** 294 * {@inheritDoc} 295 */ 296 public void setForeground(Color foreground) { 297 Color old = this.foreground; 298 this.foreground = foreground; 299 firePropertyChange(FOREGROUND_PROPERTY, old, this.foreground); 300 } 301 302 /** 303 * Sets the label information for the command using the given encoded label descriptor. 304 * 305 * @param encodedLabelInfo The encoded label descriptor. May be null or empty. 306 * 307 * @see CommandButtonLabelInfo#valueOf(String) 308 */ 309 public void setButtonLabelInfo(String encodedLabelInfo) { 310 CommandButtonLabelInfo newLabelInfo = CommandButtonLabelInfo.valueOf(encodedLabelInfo); 311 setLabelInfo(newLabelInfo); 312 } 313 314 /** 315 * {@inheritDoc} 316 */ 317 public void setLabelInfo(CommandButtonLabelInfo labelInfo) { 318 if (labelInfo == null) { 319 labelInfo = CommandButtonLabelInfo.BLANK_BUTTON_LABEL; 320 } 321 CommandButtonLabelInfo old = this.labelInfo; 322 this.labelInfo = labelInfo; 323 firePropertyChange(LABEL_INFO_PROPERTY, old, this.labelInfo); 324 } 325 326 /** 327 * {@inheritDoc} 328 */ 329 public void setIconInfo(CommandButtonIconInfo iconInfo) { 330 if (iconInfo == null) { 331 iconInfo = CommandButtonIconInfo.BLANK_ICON_INFO; 332 } 333 CommandButtonIconInfo old = this.iconInfo; 334 this.iconInfo = iconInfo; 335 firePropertyChange(ICON_INFO_PROPERTY, old, this.iconInfo); 336 } 337 338 /** 339 * {@inheritDoc} 340 */ 341 public void setLargeIconInfo(CommandButtonIconInfo largeIconInfo) { 342 if (largeIconInfo == null) { 343 largeIconInfo = CommandButtonIconInfo.BLANK_ICON_INFO; 344 } 345 CommandButtonIconInfo old = this.largeIconInfo; 346 this.largeIconInfo = largeIconInfo; 347 firePropertyChange(LARGE_ICON_INFO_PROPERTY, old, this.largeIconInfo); 348 } 349 350 /** 351 * Set the main default icon to be associated with the command. 352 * 353 * @param icon The main default icon. May be null. 354 */ 355 public void setIcon(Icon icon) { 356 Icon old = null; 357 if (iconInfo == CommandButtonIconInfo.BLANK_ICON_INFO) { 358 if (icon != null) { 359 // New IconInfo fires event 360 setIconInfo(new CommandButtonIconInfo(icon)); 361 } 362 } 363 else { 364 old = iconInfo.getIcon(); 365 this.iconInfo.setIcon(icon); 366 } 367 firePropertyChange(ICON_PROPERTY, old, icon); 368 } 369 370 /** 371 * Sets the main default large icon for the command. 372 * 373 * @param icon The large icon. May be null. 374 */ 375 public void setLargeIcon(Icon icon) { 376 Icon old = null; 377 if (largeIconInfo == CommandButtonIconInfo.BLANK_ICON_INFO) { 378 if (icon != null) { 379 // new IconInfo fires event 380 setLargeIconInfo(new CommandButtonIconInfo(icon)); 381 } 382 } 383 else { 384 old = largeIconInfo.getIcon(); 385 this.largeIconInfo.setIcon(icon); 386 } 387 firePropertyChange(LARGE_ICON_PROPERTY, old, icon); 388 } 389 390 /** 391 * Configures the given button with the label information contained in this descriptor. 392 * 393 * @param button The button to be configured. Must not be null. 394 * 395 * @throws IllegalArgumentException if {@code button} is null. 396 */ 397 public void configureLabel(AbstractButton button) { 398 Assert.required(button, "button"); 399 labelInfo.configure(button); 400 } 401 402 /** 403 * Configures the given button with the icon information contained in this descriptor. 404 * 405 * @param button The button to be configured. Must not be null. 406 * 407 * @throws IllegalArgumentException if {@code button} is null. 408 */ 409 public void configureIcon(AbstractButton button) { 410 Assert.required(button, "button"); 411 configureIconInfo(button, false); 412 } 413 414 /** 415 * Configures the given button with the icon information contained in this descriptor. 416 * 417 * @param button The button to be configured. Must not be null. 418 * @param useLargeIcons Set to true to configure the button with large icons. False will use 419 * default size icons. 420 * 421 * @throws IllegalArgumentException if {@code button} is null. 422 */ 423 public void configureIconInfo(AbstractButton button, boolean useLargeIcons) { 424 425 Assert.required(button, "button"); 426 427 if (useLargeIcons) { 428 largeIconInfo.configure(button); 429 } 430 else { 431 iconInfo.configure(button); 432 } 433 } 434 435 /** 436 * Configures the given button with colours for background and foreground if available. 437 * 438 * @param button The button to be configured. Must not be null. 439 */ 440 public void configureColor(AbstractButton button) { 441 Assert.required(button, "button"); 442 if (foreground != null) { 443 button.setForeground(foreground); 444 } 445 if (background != null) { 446 button.setBackground(background); 447 } 448 } 449 450 /** 451 * Configures the given button and command using the given configurer and the information 452 * contained in this instance. 453 * 454 * @param button The button to be configured. Must not be null. 455 * @param command The command to be configured. May be null. 456 * @param configurer The configurer. Must not be null. 457 * 458 * @throws IllegalArgumentException if {@code button} or {@code configurer} are null. 459 */ 460 public void configure(AbstractButton button, AbstractCommand command, CommandButtonConfigurer configurer) { 461 Assert.required(button, "button"); 462 Assert.required(configurer, "configurer"); 463 configurer.configure(button, command, this); 464 } 465 466 /** 467 * Configures the given action with the information contained in this descriptor. 468 * 469 * @param action The action to be configured. Must not be null. 470 * 471 * @throws IllegalArgumentException if {@code action} is null. 472 */ 473 public void configure(Action action) { 474 Assert.notNull(action, "The swing action to configure is required"); 475 action.putValue(Action.NAME, getText()); 476 action.putValue(Action.MNEMONIC_KEY, new Integer(getMnemonic())); 477 action.putValue(Action.SMALL_ICON, getIcon()); 478 action.putValue("LargeIcon", getLargeIcon()); 479 action.putValue(Action.ACCELERATOR_KEY, getAccelerator()); 480 action.putValue(Action.SHORT_DESCRIPTION, caption); 481 action.putValue(Action.LONG_DESCRIPTION, description); 482 } 483 484 /** 485 * {@inheritDoc} 486 */ 487 public String toString() { 488 return new ToStringCreator(this).append("caption", caption).append("description", description).append( 489 "buttonLabelInfo", labelInfo).append("buttonIconInfo", iconInfo).toString(); 490 } 491 }