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 }