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.JCheckBoxMenuItem;
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 JCheckBoxMenuItem 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 IdCheckBoxMenuItem
48      extends JCheckBoxMenuItem
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 check box menu item with the specified identifiable action.
68       *
69       * @param action identifiable action, must not be null
70       */
71      public IdCheckBoxMenuItem(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 check box menu item with the specified identifiable action and state.
84       *
85       * @param action identifiable action, must not be null
86       * @param state true if this check box menu item is selected
87       */
88      public IdCheckBoxMenuItem(final IdentifiableAction action, final boolean state)
89      {
90          super();
91  
92          if (action == null)
93          {
94              throw new IllegalArgumentException("action must not be null");
95          }
96          setAction(action);
97          setState(state);
98      }
99  
100     /**
101      * Create a new check box menu item with the specified identifiable action
102      * and icon size.
103      *
104      * @param action identifiable action, must not be null
105      * @param iconSize icon size, must not be null
106      */
107     public IdCheckBoxMenuItem(final IdentifiableAction action, final IconSize iconSize)
108     {
109         super();
110 
111         if (action == null)
112         {
113             throw new IllegalArgumentException("action must not be null");
114         }
115         setIconSize(iconSize);
116         setAction(action);
117     }
118 
119     /**
120      * Create a new check box menu item with the specified identifiable action,
121      * icon size, and state.
122      *
123      * @param action identifiable action, must not be null
124      * @param iconSize icon size, must not be null
125      * @param state true if this check box menu item is selected
126      */
127     public IdCheckBoxMenuItem(final IdentifiableAction action, final IconSize iconSize, final boolean state)
128     {
129         super();
130 
131         if (action == null)
132         {
133             throw new IllegalArgumentException("action must not be null");
134         }
135         setIconSize(iconSize);
136         setAction(action);
137         setState(state);
138     }
139 
140 
141     /**
142      * Return the icon size for this check box menu item.
143      *
144      * @return the icon size for this check box menu item
145      */
146     public IconSize getIconSize()
147     {
148         return iconSize;
149     }
150 
151     /**
152      * Set the icon size for this check box menu item to <code>iconSize</code>.
153      *
154      * <p>This is a bound property.</p>
155      *
156      * @param iconSize icon size, must not be null
157      */
158     public void setIconSize(final IconSize iconSize)
159     {
160         if (iconSize == null)
161         {
162             throw new IllegalArgumentException("iconSize must not be null");
163         }
164         IconSize oldIconSize = this.iconSize;
165         this.iconSize = iconSize;
166 
167         if (!this.iconSize.equals(oldIconSize))
168         {
169             firePropertyChange("iconSize", oldIconSize, this.iconSize);
170             setDirty(true);
171         }
172     }
173 
174     /**
175      * Return the icon text direction for this check box menu item.
176      *
177      * @return the icon text direction for this check box menu item
178      */
179     public IconTextDirection getIconTextDirection()
180     {
181         return iconTextDirection;
182     }
183 
184     /** {@inheritDoc} */
185     public void setComponentOrientation(final ComponentOrientation orientation)
186     {
187         ComponentOrientation oldOrientation = getComponentOrientation();
188 
189         if (!oldOrientation.equals(orientation))
190         {
191             if (orientation != null)
192             {
193                 iconTextDirection = orientation.isLeftToRight()
194                     ? IconTextDirection.LEFT_TO_RIGHT : IconTextDirection.RIGHT_TO_LEFT;
195 
196                 setDirty(true);
197             }
198         }
199 
200         super.setComponentOrientation(orientation);
201     }
202 
203     /** {@inheritDoc} */
204     public void applyComponentOrientation(final ComponentOrientation orientation)
205     {
206         ComponentOrientation oldOrientation = getComponentOrientation();
207 
208         if (!oldOrientation.equals(orientation))
209         {
210             if (orientation != null)
211             {
212                 iconTextDirection = orientation.isLeftToRight()
213                     ? IconTextDirection.LEFT_TO_RIGHT : IconTextDirection.RIGHT_TO_LEFT;
214 
215                 setDirty(true);
216             }
217         }
218 
219         super.applyComponentOrientation(orientation);
220     }
221 
222     /** {@inheritDoc} */
223     protected void configurePropertiesFromAction(final Action action)
224     {
225         super.configurePropertiesFromAction(action);
226 
227         if (isDirty())
228         {
229             rebuild();
230         }
231     }
232 
233     /**
234      * Set the dirty flag to the logical OR of <code>dirty</code>
235      * and the previous dirty state.
236      *
237      * @param dirty dirty flag
238      */
239     private void setDirty(final boolean dirty)
240     {
241         this.dirty = (this.dirty || dirty);
242     }
243 
244     /**
245      * Return true if a rebuild of the icons for this check box menu item is necessary.
246      *
247      * @return true if a rebuild of the icons for this check box menu item is necessary
248      */
249     private boolean isDirty()
250     {
251         return dirty;
252     }
253 
254     /**
255      * Rebuild the icons for this check box menu item from the icon bundle
256      * provided by the identifiable action for this check box menu item.
257      */
258     private void rebuild()
259     {
260         Action action = getAction();
261         if ((action != null) && (action instanceof IdentifiableAction))
262         {
263             IdentifiableAction identifiableAction = (IdentifiableAction) action;
264             IconBundle bndl = identifiableAction.getIconBundle();
265             setIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.NORMAL, iconSize)));
266             setPressedIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.ACTIVE, iconSize)));
267             setSelectedIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.SELECTED, iconSize)));
268             setRolloverIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.MOUSEOVER, iconSize)));
269             setRolloverSelectedIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.SELECTED, iconSize)));
270             setDisabledIcon(new ImageIcon(bndl.getImage(this, iconTextDirection, IconState.DISABLED, iconSize)));
271         }
272         dirty = false;
273     }
274 }