View Javadoc

1   /*
2   
3       dsh-identify  Lightweight components for identifiable beans.
4       Copyright (c) 2003-2012 held jointly by the individual authors.
5   
6       This library is free software; you can redistribute it and/or modify it
7       under the terms of the GNU Lesser General Public License as published
8       by the Free Software Foundation; either version 3 of the License, or (at
9       your option) any later version.
10  
11      This library is distributed in the hope that it will be useful, but WITHOUT
12      ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
13      FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14      License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public License
17      along with this library;  if not, write to the Free Software Foundation,
18      Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
19  
20      > http://www.fsf.org/licensing/licenses/lgpl.html
21      > http://www.opensource.org/licenses/lgpl-license.php
22  
23  */
24  package org.dishevelled.identify;
25  
26  import java.awt.ComponentOrientation;
27  
28  import javax.swing.Action;
29  import javax.swing.ImageIcon;
30  import javax.swing.JMenuItem;
31  
32  import org.dishevelled.iconbundle.IconBundle;
33  import org.dishevelled.iconbundle.IconSize;
34  import org.dishevelled.iconbundle.IconState;
35  import org.dishevelled.iconbundle.IconTextDirection;
36  
37  /**
38   * An extension of JMenuItem that displays the name property value
39   * and appropriate icon from an icon bundle for an identifiable
40   * action.
41   *
42   * @see IdentifiableAction
43   *
44   * @author  Michael Heuer
45   * @version $Revision$ $Date$
46   */
47  public final class IdMenuItem
48      extends JMenuItem
49  {
50      /** Default icon size. */
51      public static final IconSize DEFAULT_ICON_SIZE = IconSize.DEFAULT_16X16;
52  
53      /** Default icon text direction. */
54      private static final IconTextDirection DEFAULT_ICON_TEXT_DIRECTION = IconTextDirection.LEFT_TO_RIGHT;
55  
56      /** Icon size. */
57      private IconSize iconSize = DEFAULT_ICON_SIZE;
58  
59      /** Icon text direction. */
60      private IconTextDirection iconTextDirection = DEFAULT_ICON_TEXT_DIRECTION;
61  
62      /** Dirty flag. */
63      private transient boolean dirty = true;
64  
65  
66      /**
67       * Create a new menu item with the specified identifiable action.
68       *
69       * @param action identifiable action, must not be null
70       */
71      public IdMenuItem(final IdentifiableAction action)
72      {
73          super();
74  
75          if (action == null)
76          {
77              throw new IllegalArgumentException("action must not be null");
78          }
79          setAction(action);
80      }
81  
82      /**
83       * Create a new menu item with the specified identifiable action
84       * and icon size.
85       *
86       * @param action identifiable action, must not be null
87       * @param iconSize icon size, must not be null
88       */
89      public IdMenuItem(final IdentifiableAction action, final IconSize iconSize)
90      {
91          super();
92  
93          if (action == null)
94          {
95              throw new IllegalArgumentException("action must not be null");
96          }
97          setIconSize(iconSize);
98          setAction(action);
99      }
100 
101 
102     /**
103      * Return the icon size for this menu item.
104      *
105      * @return the icon size for this menu item
106      */
107     public IconSize getIconSize()
108     {
109         return iconSize;
110     }
111 
112     /**
113      * Set the icon size for this menu item to <code>iconSize</code>.
114      *
115      * <p>This is a bound property.</p>
116      *
117      * @param iconSize icon size, must not be null
118      */
119     public void setIconSize(final IconSize iconSize)
120     {
121         if (iconSize == null)
122         {
123             throw new IllegalArgumentException("iconSize must not be null");
124         }
125         IconSize oldIconSize = this.iconSize;
126         this.iconSize = iconSize;
127 
128         if (!this.iconSize.equals(oldIconSize))
129         {
130             firePropertyChange("iconSize", oldIconSize, this.iconSize);
131             setDirty(true);
132         }
133     }
134 
135     /**
136      * Return the icon text direction for this menu item.
137      *
138      * @return the icon text direction for this menu item
139      */
140     public IconTextDirection getIconTextDirection()
141     {
142         return iconTextDirection;
143     }
144 
145     /** {@inheritDoc} */
146     public void setComponentOrientation(final ComponentOrientation orientation)
147     {
148         ComponentOrientation oldOrientation = getComponentOrientation();
149 
150         if (!oldOrientation.equals(orientation))
151         {
152             if (orientation != null)
153             {
154                 iconTextDirection = orientation.isLeftToRight()
155                     ? IconTextDirection.LEFT_TO_RIGHT : IconTextDirection.RIGHT_TO_LEFT;
156 
157                 setDirty(true);
158             }
159         }
160 
161         super.setComponentOrientation(orientation);
162     }
163 
164     /** {@inheritDoc} */
165     public void applyComponentOrientation(final ComponentOrientation orientation)
166     {
167         ComponentOrientation oldOrientation = getComponentOrientation();
168 
169         if (!oldOrientation.equals(orientation))
170         {
171             if (orientation != null)
172             {
173                 iconTextDirection = orientation.isLeftToRight()
174                     ? IconTextDirection.LEFT_TO_RIGHT : IconTextDirection.RIGHT_TO_LEFT;
175 
176                 setDirty(true);
177             }
178         }
179 
180         super.applyComponentOrientation(orientation);
181     }
182 
183     /** {@inheritDoc} */
184     protected void configurePropertiesFromAction(final Action action)
185     {
186         super.configurePropertiesFromAction(action);
187 
188         if (isDirty())
189         {
190             rebuild();
191         }
192     }
193 
194     /**
195      * Set the dirty flag to the logical OR of <code>dirty</code>
196      * and the previous dirty state.
197      *
198      * @param dirty dirty flag
199      */
200     private void setDirty(final boolean dirty)
201     {
202         this.dirty = (this.dirty || dirty);
203     }
204 
205     /**
206      * Return true if a rebuild of the icons for this menu item is necessary.
207      *
208      * @return true if a rebuild of the icons for this menu item is necessary
209      */
210     private boolean isDirty()
211     {
212         return dirty;
213     }
214 
215     /**
216      * Rebuild the icons for this menu item from the icon bundle
217      * provided by the identifiable action for this menu item.
218      */
219     private void rebuild()
220     {
221         Action action = getAction();
222         if ((action != null) && (action instanceof IdentifiableAction))
223         {
224             IdentifiableAction identifiableAction = (IdentifiableAction) action;
225             IconBundle bndl = identifiableAction.getIconBundle();
226             setIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.NORMAL, iconSize)));
227             setPressedIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.ACTIVE, iconSize)));
228             setSelectedIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.SELECTED, iconSize)));
229             setRolloverIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.MOUSEOVER, iconSize)));
230             setRolloverSelectedIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.SELECTED, iconSize)));
231             setDisabledIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.DISABLED, iconSize)));
232         }
233         dirty = false;
234     }
235 }