View Javadoc
1   /*
2   
3       dsh-identify  Lightweight components for identifiable beans.
4       Copyright (c) 2003-2019 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   */
46  public final class IdMenuItem
47      extends JMenuItem
48  {
49      /** Default icon size. */
50      public static final IconSize DEFAULT_ICON_SIZE = IconSize.DEFAULT_16X16;
51  
52      /** Default icon text direction. */
53      private static final IconTextDirection DEFAULT_ICON_TEXT_DIRECTION = IconTextDirection.LEFT_TO_RIGHT;
54  
55      /** Icon size. */
56      private IconSize iconSize = DEFAULT_ICON_SIZE;
57  
58      /** Icon text direction. */
59      private IconTextDirection iconTextDirection = DEFAULT_ICON_TEXT_DIRECTION;
60  
61      /** Dirty flag. */
62      private transient boolean dirty = true;
63  
64  
65      /**
66       * Create a new menu item with the specified identifiable action.
67       *
68       * @param action identifiable action, must not be null
69       */
70      public IdMenuItem(final IdentifiableAction action)
71      {
72          super();
73  
74          if (action == null)
75          {
76              throw new IllegalArgumentException("action must not be null");
77          }
78          setAction(action);
79      }
80  
81      /**
82       * Create a new menu item with the specified identifiable action
83       * and icon size.
84       *
85       * @param action identifiable action, must not be null
86       * @param iconSize icon size, must not be null
87       */
88      public IdMenuItem(final IdentifiableAction action, final IconSize iconSize)
89      {
90          super();
91  
92          if (action == null)
93          {
94              throw new IllegalArgumentException("action must not be null");
95          }
96          setIconSize(iconSize);
97          setAction(action);
98      }
99  
100 
101     /**
102      * Return the icon size for this menu item.
103      *
104      * @return the icon size for this menu item
105      */
106     public IconSize getIconSize()
107     {
108         return iconSize;
109     }
110 
111     /**
112      * Set the icon size for this menu item to <code>iconSize</code>.
113      *
114      * <p>This is a bound property.</p>
115      *
116      * @param iconSize icon size, must not be null
117      */
118     public void setIconSize(final IconSize iconSize)
119     {
120         if (iconSize == null)
121         {
122             throw new IllegalArgumentException("iconSize must not be null");
123         }
124         IconSize oldIconSize = this.iconSize;
125         this.iconSize = iconSize;
126 
127         if (!this.iconSize.equals(oldIconSize))
128         {
129             firePropertyChange("iconSize", oldIconSize, this.iconSize);
130             setDirty(true);
131         }
132     }
133 
134     /**
135      * Return the icon text direction for this menu item.
136      *
137      * @return the icon text direction for this menu item
138      */
139     public IconTextDirection getIconTextDirection()
140     {
141         return iconTextDirection;
142     }
143 
144     @Override
145     public void setComponentOrientation(final ComponentOrientation orientation)
146     {
147         ComponentOrientation oldOrientation = getComponentOrientation();
148 
149         if (!oldOrientation.equals(orientation))
150         {
151             if (orientation != null)
152             {
153                 iconTextDirection = orientation.isLeftToRight()
154                     ? IconTextDirection.LEFT_TO_RIGHT : IconTextDirection.RIGHT_TO_LEFT;
155 
156                 setDirty(true);
157             }
158         }
159 
160         super.setComponentOrientation(orientation);
161     }
162 
163     @Override
164     public void applyComponentOrientation(final ComponentOrientation orientation)
165     {
166         ComponentOrientation oldOrientation = getComponentOrientation();
167 
168         if (!oldOrientation.equals(orientation))
169         {
170             if (orientation != null)
171             {
172                 iconTextDirection = orientation.isLeftToRight()
173                     ? IconTextDirection.LEFT_TO_RIGHT : IconTextDirection.RIGHT_TO_LEFT;
174 
175                 setDirty(true);
176             }
177         }
178 
179         super.applyComponentOrientation(orientation);
180     }
181 
182     @Override
183     protected void configurePropertiesFromAction(final Action action)
184     {
185         super.configurePropertiesFromAction(action);
186 
187         if (isDirty())
188         {
189             rebuild();
190         }
191     }
192 
193     /**
194      * Set the dirty flag to the logical OR of <code>dirty</code>
195      * and the previous dirty state.
196      *
197      * @param dirty dirty flag
198      */
199     private void setDirty(final boolean dirty)
200     {
201         this.dirty = (this.dirty || dirty);
202     }
203 
204     /**
205      * Return true if a rebuild of the icons for this menu item is necessary.
206      *
207      * @return true if a rebuild of the icons for this menu item is necessary
208      */
209     private boolean isDirty()
210     {
211         return dirty;
212     }
213 
214     /**
215      * Rebuild the icons for this menu item from the icon bundle
216      * provided by the identifiable action for this menu item.
217      */
218     private void rebuild()
219     {
220         Action action = getAction();
221         if ((action != null) && (action instanceof IdentifiableAction))
222         {
223             IdentifiableAction/identify/IdentifiableAction.html#IdentifiableAction">IdentifiableAction identifiableAction = (IdentifiableAction) action;
224             IconBundle bndl = identifiableAction.getIconBundle();
225             setIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.NORMAL, iconSize)));
226             setPressedIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.ACTIVE, iconSize)));
227             setSelectedIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.SELECTED, iconSize)));
228             setRolloverIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.MOUSEOVER, iconSize)));
229             setRolloverSelectedIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.SELECTED, iconSize)));
230             //setDisabledIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.DISABLED, iconSize)));
231         }
232         dirty = false;
233     }
234 }