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.Component;
27  
28  import java.awt.event.ActionEvent;
29  
30  import java.util.Arrays;
31  import java.util.ArrayList;
32  import java.util.Collections;
33  import java.util.HashMap;
34  import java.util.List;
35  import java.util.Map;
36  
37  import javax.swing.AbstractAction;
38  import javax.swing.Action;
39  import javax.swing.ButtonGroup;
40  import javax.swing.JCheckBoxMenuItem;
41  import javax.swing.JPopupMenu;
42  import javax.swing.JToolBar;
43  import javax.swing.UIManager;
44  
45  import org.dishevelled.iconbundle.IconSize;
46  import org.dishevelled.iconbundle.IconTextDirection;
47  
48  /**
49   * An extension of JToolBar that accepts identifiable actions
50   * and provides actions for changing display properties and
51   * icon sizes.
52   *
53   * @author  Michael Heuer
54   * @version $Revision$ $Date$
55   */
56  public final class IdToolBar
57      extends JToolBar
58  {
59      /** Action selected key, Action.SELECTED_KEY only available in JDK 1.6+. */
60      private static final String SELECTED_KEY = "SwingSelectedKey";
61  
62      /** Display icons action. */
63      private final AbstractAction displayIcons = new AbstractAction("Display icons")
64          {
65              /** {@inheritDoc} */
66              public void actionPerformed(final ActionEvent event)
67              {
68                  displayIcons();
69              }
70          };
71  
72      /** Display text action. */
73      private final AbstractAction displayText = new AbstractAction("Display text")
74          {
75              /** {@inheritDoc} */
76              public void actionPerformed(final ActionEvent event)
77              {
78                  displayText();
79              }
80          };
81  
82      /** Display icons and text action. */
83      private final AbstractAction displayIconsAndText = new AbstractAction("Display icons and text")
84          {
85              /** {@inheritDoc} */
86              public void actionPerformed(final ActionEvent event)
87              {
88                  displayIconsAndText();
89              }
90          };
91  
92      /** Display. */
93      private int display = DISPLAY_ICONS;
94  
95      /** Icon size. */
96      private IconSize iconSize = DEFAULT_ICON_SIZE;
97  
98      /** Icon text direction. */
99      private IconTextDirection iconTextDirection = DEFAULT_ICON_TEXT_DIRECTION;
100 
101     /** Display icons. */
102     private static final int DISPLAY_ICONS = 0;
103 
104     /** Display text. */
105     private static final int DISPLAY_TEXT = 1;
106 
107     /** Display icons and text. */
108     private static final int DISPLAY_ICONS_AND_TEXT = 2;
109 
110     /** Default icon size, <code>IconSize.DEFAULT_16X16</code>. */
111     public static final IconSize DEFAULT_ICON_SIZE = IconSize.DEFAULT_16X16;
112 
113     /** Default icon text direction, <code>IconTextDirection.LEFT_TO_RIGHT</code>. */
114     public static final IconTextDirection DEFAULT_ICON_TEXT_DIRECTION = IconTextDirection.LEFT_TO_RIGHT;
115 
116     /** List of display actions. */
117     private final List/*<AbstractAction>*/ displayActions = Arrays.asList(new AbstractAction[] { displayIcons, displayText, displayIconsAndText });
118 
119     /** List of display menu items. */
120     private final List/*<JCheckBoxMenuItem>*/ displayMenuItems = new ArrayList/*<JCheckBoxMenuItem>*/(displayActions.size());
121 
122     /** Map of icon size actions keyed by icon size. */
123     private final Map/*<IconSize, Action>*/ iconSizeActions = new HashMap/*<IconSize, Action>*/();
124 
125     /** Map of icon size menu items keyed by icon size. */
126     private final Map/*<IconSize, JCheckBoxMenuItem>*/ iconSizeMenuItems = new HashMap/*<IconSize, JCheckBoxMenuItem>*/();
127 
128     /** Icon size menu item button group. */
129     private final ButtonGroup iconSizeButtonGroup = new ButtonGroup();
130 
131 
132     /**
133      * Create a new tool bar.
134      */
135     public IdToolBar()
136     {
137         super();
138         // clear gradient for Metal/Ocean L&F
139         UIManager.put("MenuBar.gradient", null);
140         UIManager.getDefaults().put("MenuBar.gradient", null);
141         UIManager.getLookAndFeelDefaults().put("MenuBar.gradient", null);
142 
143         createDisplayMenuItems();
144         displayIcons();
145         setIconSize(iconSize);
146     }
147 
148     /**
149      * Create a new tool bar with the specified orientation.
150      *
151      * @param orientation orientation, must be either <code>HORIZONTAL<code>
152      *    or <code>VERTICAL</code>
153      */
154     public IdToolBar(final int orientation)
155     {
156         super(orientation);
157         // clear gradient for Metal/Ocean L&F
158         UIManager.put("MenuBar.gradient", null);
159         UIManager.getDefaults().put("MenuBar.gradient", null);
160         UIManager.getLookAndFeelDefaults().put("MenuBar.gradient", null);
161 
162         createDisplayMenuItems();
163         displayIcons();
164         setIconSize(iconSize);
165     }
166 
167     /**
168      * Create a new tool bar with the specified name.
169      *
170      * @param name name of this tool bar
171      */
172     public IdToolBar(final String name)
173     {
174         super(name);
175         createDisplayMenuItems();
176         displayIcons();
177         setIconSize(iconSize);
178     }
179 
180     /**
181      * Create a new tool bar with the specified name and orientation.
182      *
183      * @param name name of this tool bar
184      * @param orientation orientation, must be either <code>HORIZONTAL<code>
185      *    or <code>VERTICAL</code>
186      */
187     public IdToolBar(final String name, final int orientation)
188     {
189         super(name, orientation);
190         createDisplayMenuItems();
191         displayIcons();
192         setIconSize(iconSize);
193     }
194 
195 
196     /**
197      * Create the display menu items.
198      */
199     private void createDisplayMenuItems() {
200         ButtonGroup buttonGroup = new ButtonGroup();
201         //for (AbstractAction displayAction : displayActions)
202         for (int i = 0, size = displayActions.size(); i < size; i++)
203         {
204             AbstractAction displayAction = (AbstractAction) displayActions.get(i);
205             JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(displayAction);
206             displayMenuItems.add(menuItem);
207             buttonGroup.add(menuItem);
208         }
209     }
210 
211     /**
212      * Add and return a new context menu button to this tool bar which raises the specified
213      * context menu.  The context menu button will not be null.
214      *
215      * @param contextMenu context menu to add to this tool bar, must not be null
216      * @return a new context menu button which raises the specified context menu
217      */
218     public ContextMenuButton add(final JPopupMenu contextMenu)
219     {
220         ContextMenuButton contextMenuButton = new ContextMenuButton(contextMenu);
221 
222         // tweak visual settings; might be L&F dependent
223         contextMenuButton.setBorderPainted(false);
224         contextMenuButton.setFocusPainted(false);
225 
226         super.add(contextMenuButton);
227         return contextMenuButton;
228     }
229 
230     /**
231      * Add and return a new identifiable button to this tool bar which dispatches the specified
232      * identifiable action.  The identifiable button will not be null.
233      *
234      * @param identifiableAction identifiable action to add to this tool bar, must not be null
235      * @return a new identifiable button which dispatches the specified identifiable action
236      */
237     public IdButton add(final IdentifiableAction identifiableAction)
238     {
239         IdButton idButton = new IdButton(identifiableAction);
240         idButton.setIconSize(iconSize);
241         switch (display)
242         {
243             case DISPLAY_ICONS:
244                 idButton.displayIcon();
245                 break;
246             case DISPLAY_TEXT:
247                 idButton.displayText();
248                 break;
249             case DISPLAY_ICONS_AND_TEXT:
250                 idButton.displayIconAndText();
251                 break;
252             default:
253                 break;
254         }
255 
256         if (IdentifyUtils.isGTKLookAndFeel())
257         {
258             idButton.setHorizontalAlignment(IdButton.LEFT);
259             idButton.setHorizontalTextPosition(IdButton.TRAILING);
260             idButton.setVerticalTextPosition(IdButton.CENTER);
261         }
262         else
263         {
264             // default to icon over centered text layout
265             idButton.setHorizontalAlignment(IdButton.CENTER);
266             idButton.setHorizontalTextPosition(IdButton.CENTER);
267             idButton.setVerticalTextPosition(IdButton.BOTTOM);
268         }
269 
270         // tweak visual settings; might be L&F dependent
271         idButton.setBorderPainted(false);
272         idButton.setFocusPainted(false);
273 
274         super.add(idButton);
275         return idButton;
276     }
277 
278     /**
279      * Remove the identifiable button for the specified identifiable action from
280      * this tool bar, if such exists.
281      *
282      * @param identifiableAction identifiable action to remove from this tool bar
283      * @return the identifiable button removed from this tool bar, or null if no such button exists
284      */
285     public IdButton remove(final IdentifiableAction identifiableAction)
286     {
287         for (int i = 0; i < getComponentCount(); i++)
288         {
289             Component c = getComponent(i);
290             if (c instanceof IdButton)
291             {
292                 IdButton idButton = (IdButton) c;
293                 Action action = idButton.getAction();
294                 if (action != null && action.equals(identifiableAction))
295                 {
296                     remove(idButton);
297                     return idButton;
298                 }
299             }
300         }
301         return null;
302     }
303 
304     /**
305      * Display icons only for the buttons in this tool bar.
306      */
307     public void displayIcons()
308     {
309         display = DISPLAY_ICONS;
310         displayIcons.putValue(SELECTED_KEY, Boolean.TRUE);
311 
312         for (int i = 0, size = getComponentCount(); i < size; i++)
313         {
314             Component component = getComponentAtIndex(i);
315             if (component instanceof IdButton)
316             {
317                 IdButton idButton = (IdButton) component;
318                 idButton.displayIcon();
319             }
320         }
321     }
322 
323     /**
324      * Display text only for the buttons in this tool bar.
325      */
326     public void displayText()
327     {
328         display = DISPLAY_TEXT;
329         displayText.putValue(SELECTED_KEY, Boolean.TRUE);
330 
331         for (int i = 0, size = getComponentCount(); i < size; i++)
332         {
333             Component component = getComponentAtIndex(i);
334             if (component instanceof IdButton)
335             {
336                 IdButton idButton = (IdButton) component;
337                 idButton.displayText();
338             }
339         }
340     }
341 
342     /**
343      * Display icons and text for the buttons in this tool bar.
344      */
345     public void displayIconsAndText()
346     {
347         display = DISPLAY_ICONS_AND_TEXT;
348         displayIconsAndText.putValue(SELECTED_KEY, Boolean.TRUE);
349 
350         for (int i = 0, size = getComponentCount(); i < size; i++)
351         {
352             Component component = getComponentAtIndex(i);
353             if (component instanceof IdButton)
354             {
355                 IdButton idButton = (IdButton) component;
356                 idButton.displayIconAndText();
357             }
358         }
359     }
360 
361     /**
362      * Return the icon size for all identifiable buttons in this tool bar.
363      *
364      * @return the icon size for all identifiable buttons in this tool bar
365      */
366     public IconSize getIconSize()
367     {
368         return iconSize;
369     }
370 
371     /**
372      * Set the icon size for all identifiable buttons in this tool bar to <code>iconSize</code>.
373      *
374      * @param iconSize icon size for all identifiable buttons in this tool bar, must not be null
375      */
376     public void setIconSize(final IconSize iconSize)
377     {
378         if (iconSize == null)
379         {
380             throw new IllegalArgumentException("iconSize must not be null");
381         }
382         Action iconSizeAction = createIconSizeAction(iconSize);
383         iconSizeAction.putValue(SELECTED_KEY, Boolean.TRUE);
384 
385         for (int i = 0, size = getComponentCount(); i < size; i++)
386         {
387             Component component = getComponentAtIndex(i);
388             if (component instanceof IdButton)
389             {
390                 IdButton idButton = (IdButton) component;
391                 idButton.setIconSize(iconSize);
392             }
393         }
394     }
395 
396     /**
397      * Return the icon text direction for all identifiable buttons in this tool bar.
398      *
399      * @return the icon text direction for all identifiable buttons in this tool bar
400      */
401     public IconTextDirection getIconTextDirection()
402     {
403         return iconTextDirection;
404     }
405 
406     /**
407      * Return an unmodifiable list of display actions.  The list will not be null.
408      *
409      * @return an unmodifiable list of display actions
410      */
411     public List/*<Action>*/ getDisplayActions()
412     {
413         return displayActions;
414     }
415 
416     /**
417      * Return an unmodifiable list of check box menu items for the display actions.  The list
418      * will not be null.
419      *
420      * @return an unmodifiable list of check box menu items for the display actions
421      */
422     public List/*<JCheckBoxMenuItem>*/ getDisplayMenuItems()
423     {
424         return Collections.unmodifiableList(displayMenuItems);
425     }
426 
427     /**
428      * Create and return a new icon size action for this tool bar for the specified icon size.
429      * The new icon size action will not be null.
430      *
431      * @param iconSize icon size for the new icon size action, must not be null
432      * @return a new icon size action for the specified icon size
433      */
434     public Action createIconSizeAction(final IconSize iconSize)
435     {
436         if (iconSize == null)
437         {
438             throw new IllegalArgumentException("iconSize must not be null");
439         }
440         if (!iconSizeActions.containsKey(iconSize))
441         {
442             iconSizeActions.put(iconSize, new IconSizeAction(iconSize));
443         }
444         return (Action) iconSizeActions.get(iconSize);
445     }
446 
447     /**
448      * Create and return a new icon size menu item for this tool bar for the specified icon size.
449      * The new icon size menu item will not be null.
450      *
451      * @param iconSize icon size for the new icon size menu item, must not be null
452      * @return a new icon size menu item for the specified icon size
453      */
454     public JCheckBoxMenuItem createIconSizeMenuItem(final IconSize iconSize)
455     {
456         if (iconSize == null)
457         {
458             throw new IllegalArgumentException("iconSize must not be null");
459         }
460         if (!iconSizeMenuItems.containsKey(iconSize))
461         {
462             Action iconSizeAction = createIconSizeAction(iconSize);
463             JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(iconSizeAction);
464             iconSizeButtonGroup.add(menuItem);
465             iconSizeMenuItems.put(iconSize, menuItem);
466         }
467         return (JCheckBoxMenuItem) iconSizeMenuItems.get(iconSize);
468     }
469 
470     /**
471      * Return an unmodifiable list of the default icon size actions.  The list will not be null.
472      *
473      * @return an unmodifiable list of the default icon size actions
474      */
475     public List/*<Action>*/ getDefaultIconSizeActions()
476     {
477         List/*<Action>*/ actions = new ArrayList/*<Action>*/(IconSize.VALUES.size());
478         //for (IconSize iconSize : IconSize.VALUES)
479         for (int i = 0, size = IconSize.VALUES.size(); i < size; i++)
480         {
481             Action iconSizeAction = createIconSizeAction((IconSize) IconSize.VALUES.get(i));
482             actions.add(iconSizeAction);
483         }
484         return Collections.unmodifiableList(actions);
485     }
486 
487     /**
488      * Return an unmodifiable list of check box menu items for the default icon size actions.  The list
489      * will not be null.
490      *
491      * @return an unmodifiable list of check box menu items for the default icon size actions
492      */
493     public List/*<JCheckBoxMenuItem>*/ getDefaultIconSizeMenuItems()
494     {
495         List/*<Action>*/ menuItems = new ArrayList/*<Action>*/(IconSize.VALUES.size());
496         //for (IconSize iconSize : IconSize.VALUES)
497         for (int i = 0, size = IconSize.VALUES.size(); i < size; i++)
498         {
499             JCheckBoxMenuItem iconSizeMenuItem = createIconSizeMenuItem((IconSize) IconSize.VALUES.get(i));
500             menuItems.add(iconSizeMenuItem);
501         }
502         return Collections.unmodifiableList(menuItems);
503     }
504 
505     /**
506      * Icon size action.
507      */
508     private class IconSizeAction extends AbstractAction
509     {
510         /** Icon size. */
511         private final IconSize iconSize;
512 
513 
514         /**
515          * Create a new icon size action for the specified icon size.
516          *
517          * @param iconSize icon size, must not be null
518          */
519         IconSizeAction(final IconSize iconSize)
520         {
521             super();
522             if (iconSize == null)
523             {
524                 throw new IllegalArgumentException("iconSize must not be null");
525             }
526             this.iconSize = iconSize;
527             putValue(Action.NAME, "Use icon size " + iconSize);
528         }
529 
530 
531         /** {@inheritDoc} */
532         public void actionPerformed(final ActionEvent event)
533         {
534             setIconSize(iconSize);
535         }
536     }
537 }