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 }