View Javadoc

1   /*
2    * Copyright 2002-2004 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.springframework.richclient.command.config;
17  
18  import java.awt.Color;
19  import java.awt.Image;
20  
21  import javax.swing.AbstractButton;
22  import javax.swing.Action;
23  import javax.swing.Icon;
24  import javax.swing.KeyStroke;
25  
26  import org.springframework.binding.value.support.AbstractPropertyChangePublisher;
27  import org.springframework.core.style.ToStringCreator;
28  import org.springframework.richclient.command.AbstractCommand;
29  import org.springframework.richclient.core.ColorConfigurable;
30  import org.springframework.richclient.core.DescribedElement;
31  import org.springframework.richclient.core.DescriptionConfigurable;
32  import org.springframework.richclient.core.VisualizedElement;
33  import org.springframework.richclient.util.Assert;
34  
35  /**
36   * A parameter object that contains the information to describe the visual representation of a 
37   * command object.
38   * 
39   * 
40   * @author Keith Donald
41   */
42  public class CommandFaceDescriptor extends AbstractPropertyChangePublisher implements DescribedElement,
43          VisualizedElement, CommandLabelConfigurable, DescriptionConfigurable, CommandIconConfigurable, ColorConfigurable {
44  
45      /** The property name used when firing events for the {@code labelInfo} property. */
46      public static final String LABEL_INFO_PROPERTY = "labelInfo";
47  
48      /** The property name used when firing events for the {@code icon} property. */
49      public static final String ICON_PROPERTY = "icon";
50  
51      /** The property name used when firing events for the {@code largeIcon} property. */
52      public static final String LARGE_ICON_PROPERTY = "largeIcon";
53  
54      /** The property name used when firing events for the {@code iconInfo} property. */
55      public static final String ICON_INFO_PROPERTY = "iconInfo";
56  
57      /** The property name used when firing events for the {@code largeIconInfo} property. */
58      public static final String LARGE_ICON_INFO_PROPERTY = "largeIconInfo";
59      
60      /** The property name used when firing events for the {@code background} property. */
61      public static final String BACKGROUND_PROPERTY = "background";
62      
63      /** The property name used when firing events for the {@code foreground} property. */
64      public static final String FOREGROUND_PROPERTY = "foreground";
65  
66      private String caption;
67  
68      private String description;
69      
70      private Color background;
71      
72      private Color foreground;
73  
74      private CommandButtonLabelInfo labelInfo;
75  
76      private CommandButtonIconInfo iconInfo = CommandButtonIconInfo.BLANK_ICON_INFO;
77  
78      private CommandButtonIconInfo largeIconInfo = CommandButtonIconInfo.BLANK_ICON_INFO;
79  
80      /**
81       * Creates a new {@code CommandFaceDescriptor} that uses the given encoded label descriptor
82       * to provide the label properties. 
83       *
84       * @param encodedLabel The encoded label descriptor. May be null or empty to define a blank label.
85       * 
86       * @see CommandButtonLabelInfo#valueOf(String)
87       */
88      public CommandFaceDescriptor(String encodedLabel) {
89          this(encodedLabel, null, null);
90      }
91  
92      /**
93       * Creates a new {@code CommandFaceDescriptor} that uses the given encoded label descriptor
94       * to provide the label properties, along with the given icon and caption.
95       *
96       * @param encodedLabel The encoded label descriptor. May be null or empty.
97       * @param icon The main default icon to be displayed by the command. May be null.
98       * @param caption The caption to be displayed on rollover of the command. May be null or empty.
99       * 
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 }