KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > menus > SMenuManager


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.ui.internal.menus;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Collection JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.Set JavaDoc;
20
21 import org.eclipse.core.commands.common.HandleObject;
22 import org.eclipse.core.commands.common.HandleObjectManager;
23 import org.eclipse.jface.util.IPropertyChangeListener;
24 import org.eclipse.jface.util.PropertyChangeEvent;
25 import org.eclipse.ui.internal.misc.Policy;
26
27 /**
28  * <p>
29  * Manages a group of menu elements. These menu elements include things like
30  * menus, groups, and items. The manager is responsible for handling the layout
31  * of these items with respect to each other. Visibility is controlled
32  * externally by updating the visibility of the menu elements themselves. The
33  * painting of these menu elements on the application window(s) is handler by a
34  * renderer.
35  * </p>
36  * <p>
37  * Clients may instantiate, but must not extend.
38  * </p>
39  * <p>
40  * <strong>PROVISIONAL</strong>. This class or interface has been added as
41  * part of a work in progress. There is a guarantee neither that this API will
42  * work nor that it will remain the same. Please do not use this API without
43  * consulting with the Platform/UI team.
44  * </p>
45  * <p>
46  * This class will eventually exist in <code>org.eclipse.jface.menus</code>.
47  * </p>
48  *
49  * @since 3.2
50  */

51 public final class SMenuManager extends HandleObjectManager implements
52         IPropertyChangeListener {
53
54     /**
55      * The map of action set identifiers (<code>String</code>) to action set (
56      * <code>SActionSet</code>). This collection may be empty, but it is
57      * never <code>null</code>.
58      */

59     private final Map JavaDoc actionSetsById = new HashMap JavaDoc();
60
61     /**
62      * The set of action sets that are defined. This value may be empty, but it
63      * is never <code>null</code>.
64      */

65     private final Set JavaDoc definedActionSets = new HashSet JavaDoc();
66
67     /**
68      * The set of groups that are defined. This value may be empty, but it is
69      * never <code>null</code>.
70      */

71     private final Set JavaDoc definedGroups = new HashSet JavaDoc();
72
73     /**
74      * The set of identifiers for those menus that are defined. This value may
75      * be empty, but it is never <code>null</code>.
76      */

77     private final Set JavaDoc definedMenus = new HashSet JavaDoc();
78
79     /**
80      * The set of identifiers for those widgets that are defined. This value may
81      * be empty, but it is never <code>null</code>.
82      */

83     private final Set JavaDoc definedWidgets = new HashSet JavaDoc();
84
85     /**
86      * The map of group identifiers (<code>String</code>) to groups (
87      * <code>SGroup</code>). This collection may be empty, but it is never
88      * <code>null</code>.
89      */

90     private final Map JavaDoc groupsById = new HashMap JavaDoc();
91
92     /**
93      * The layout for this menu manager. This layout is <code>null</code> if
94      * the menu manager has changed since the last layout was built.
95      */

96     private SMenuLayout layout = null;
97
98     /**
99      * The map of menu identifiers (<code>String</code>) to menus (
100      * <code>SMenu</code>). This collection may be empty, but it is never
101      * <code>null</code>.
102      */

103     private final Map JavaDoc menusById = new HashMap JavaDoc();
104
105     /**
106      * The map of widget identifiers (<code>String</code>) to widgets (
107      * <code>SWidget</code>). This collection may be empty, but it is never
108      * <code>null</code>.
109      */

110     private final Map JavaDoc widgetsById = new HashMap JavaDoc();
111
112     /**
113      * Adds a listener to this menu manager that will be notified when this
114      * manager's state changes.
115      *
116      * @param listener
117      * The listener to be added; must not be <code>null</code>.
118      */

119     public final void addListener(final IMenuManagerListener listener) {
120         addListenerObject(listener);
121     }
122
123     /**
124      * Notifies listeners to this menu manager that it has changed in some way.
125      *
126      * @param event
127      * The event to fire; may be <code>null</code>.
128      */

129     private final void fireMenuManagerChanged(final MenuManagerEvent event) {
130         if (event == null) {
131             return;
132         }
133
134         final Object JavaDoc[] listeners = getListeners();
135         for (int i = 0; i < listeners.length; i++) {
136             final IMenuManagerListener listener = (IMenuManagerListener) listeners[i];
137             listener.menuManagerChanged(event);
138         }
139     }
140
141     /**
142      * Gets the action set with the given identifier. If no such action set
143      * currently exists, then the action set will be created (but will be
144      * undefined).
145      *
146      * @param actionSetId
147      * The identifier to find; must not be <code>null</code> and
148      * must not be zero-length.
149      * @return The action set with the given identifier; this value will never
150      * be <code>null</code>, but it might be undefined.
151      * @see SActionSet
152      */

153     public final SActionSet getActionSet(final String JavaDoc actionSetId) {
154         checkId(actionSetId);
155
156         SActionSet actionSet = (SActionSet) actionSetsById.get(actionSetId);
157         if (actionSet == null) {
158             actionSet = new SActionSet(actionSetId);
159             actionSetsById.put(actionSetId, actionSet);
160             actionSet.addListener(this);
161         }
162
163         return actionSet;
164     }
165
166     /**
167      * Returns those action sets that are defined.
168      *
169      * @return The defined action sets; this value may be empty, but it is never
170      * <code>null</code>.
171      */

172     public final SActionSet[] getDefinedActionSets() {
173         return (SActionSet[]) definedActionSets
174                 .toArray(new SActionSet[definedActionSets.size()]);
175     }
176
177     /**
178      * Returns those groups that are defined.
179      *
180      * @return The defined groups; this value may be empty, but it is never
181      * <code>null</code>.
182      */

183     public final SGroup[] getDefinedGroups() {
184         return (SGroup[]) definedGroups
185                 .toArray(new SGroup[definedGroups.size()]);
186     }
187
188     /**
189      * Returns those items that are defined.
190      *
191      * @return The defined items; this value may be empty, but it is never
192      * <code>null</code>.
193      */

194     public final SItem[] getDefinedItems() {
195         return (SItem[]) definedHandleObjects
196                 .toArray(new SItem[definedHandleObjects.size()]);
197     }
198
199     /**
200      * Returns those menus that are defined.
201      *
202      * @return The defined menus; this value may be empty, but it is never
203      * <code>null</code>.
204      */

205     public final SMenu[] getDefinedMenus() {
206         return (SMenu[]) definedMenus.toArray(new SMenu[definedMenus.size()]);
207     }
208
209     /**
210      * Returns those widgets that are defined.
211      *
212      * @return The defined widgets; this value may be empty, but it is never
213      * <code>null</code>.
214      */

215     public final SWidget[] getDefinedWidgets() {
216         return (SWidget[]) definedWidgets.toArray(new SWidget[definedWidgets
217                 .size()]);
218     }
219
220     /**
221      * Gets the group with the given identifier. If no such group currently
222      * exists, then the group will be created (but will be undefined).
223      *
224      * @param groupId
225      * The identifier to find; must not be <code>null</code> and
226      * must not be zero-length.
227      * @return The group with the given identifier; this value will never be
228      * <code>null</code>, but it might be undefined.
229      * @see SGroup
230      */

231     public final SGroup getGroup(final String JavaDoc groupId) {
232         checkId(groupId);
233
234         if (Policy.EXPERIMENTAL_MENU
235                 && groupId.indexOf(LeafLocationElement.BREAKPOINT_PATH)>-1) {
236             System.err.println("getMenu: " + groupId); //$NON-NLS-1$
237
}
238         SGroup group = (SGroup) groupsById.get(groupId);
239         if (group == null) {
240             group = new SGroup(groupId);
241             groupsById.put(groupId, group);
242             group.addListener(this);
243         }
244
245         return group;
246     }
247
248     /**
249      * Gets the item with the given identifier. If no such item currently
250      * exists, then the item will be created (but will be undefined).
251      *
252      * @param itemId
253      * The identifier to find; must not be <code>null</code> and
254      * must not be zero-length.
255      * @return The item with the given identifier; this value will never be
256      * <code>null</code>, but it might be undefined.
257      * @see SItem
258      */

259     public final SItem getItem(final String JavaDoc itemId) {
260         checkId(itemId);
261
262         SItem item = (SItem) handleObjectsById.get(itemId);
263         if (item == null) {
264             item = new SItem(itemId);
265             handleObjectsById.put(itemId, item);
266             item.addListener(this);
267         }
268
269         return item;
270     }
271
272     /**
273      * <p>
274      * Retrieves the layout for the menu elements held by this menu manager.
275      * This layout does not consider visibility or whether the elements are
276      * currently shown. It is simply the layout if everything was visible and
277      * showing. It also does not consider dynamic menu elements, which will be
278      * asked to make changes to the layout before the menu element is shown.
279      * </p>
280      * <p>
281      * The result of this computation is cached between subsequent calls. So, if
282      * no changes are made to the menu elements, the layout can be retrieved in
283      * constant time. Otherwise, it will take <code>O(n)</code> time to
284      * compute, where <code>n</code> is the number of menu elements held by
285      * this manager.
286      * </p>
287      *
288      * @return The menu layout; never <code>null</code>.
289      */

290     public final SMenuLayout getLayout() {
291 // if (layout == null) {
292
// Generate the layout
293
final Collection JavaDoc menuElements = new ArrayList JavaDoc(definedMenus.size()
294                     + definedGroups.size() + definedHandleObjects.size()
295                     + definedWidgets.size());
296             menuElements.addAll(definedMenus);
297             menuElements.addAll(definedGroups);
298             menuElements.addAll(definedHandleObjects);
299             menuElements.addAll(definedWidgets);
300             layout = SMenuLayout.computeLayout(menuElements);
301 // }
302

303         return layout;
304     }
305
306     /**
307      * Gets the menu with the given identifier. If no such menu currently
308      * exists, then the menu will be created (but will be undefined).
309      *
310      * @param menuId
311      * The identifier to find; must not be <code>null</code> and
312      * must not be zero-length.
313      * @return The menu with the given identifier; this value will never be
314      * <code>null</code>, but it might be undefined.
315      * @see SMenu
316      */

317     public final SMenu getMenu(final String JavaDoc menuId) {
318         checkId(menuId);
319
320         if (Policy.EXPERIMENTAL_MENU
321                 && menuId.indexOf(LeafLocationElement.BREAKPOINT_PATH)>-1) {
322             System.err.println("getMenu: " + menuId); //$NON-NLS-1$
323
}
324         
325         SMenu menu = (SMenu) menusById.get(menuId);
326         if (menu == null) {
327             menu = new SMenu(menuId);
328             menusById.put(menuId, menu);
329             menu.addListener(this);
330         }
331
332         return menu;
333     }
334
335     /**
336      * Gets the widget with the given identifier. If no such widget currently
337      * exists, then the widget will be created (but will be undefined).
338      *
339      * @param widgetId
340      * The identifier to find; must not be <code>null</code> and
341      * must not be zero-length.
342      * @return The item with the given identifier; this value will never be
343      * <code>null</code>, but it might be undefined.
344      * @see SWidget
345      */

346     public final SWidget getWidget(final String JavaDoc widgetId) {
347         checkId(widgetId);
348
349         SWidget widget = (SWidget) widgetsById.get(widgetId);
350         if (widget == null) {
351             widget = new SWidget(widgetId);
352             widgetsById.put(widgetId, widget);
353             widget.addListener(this);
354         }
355
356         return widget;
357     }
358
359     public final void propertyChange(final PropertyChangeEvent event) {
360         if (MenuElement.PROPERTY_DEFINED.equals(event.getProperty())) {
361             final HandleObject handle = (HandleObject) event.getSource();
362             final String JavaDoc id = handle.getId();
363             final boolean added = ((Boolean JavaDoc) event.getNewValue())
364                     .booleanValue();
365             if (added) {
366                 if (handle instanceof SActionSet) {
367                     definedActionSets.add(handle);
368                     if (isListenerAttached()) {
369                         fireMenuManagerChanged(new MenuManagerEvent(this, null,
370                                 false, null, false, null, false, null, false,
371                                 id, added));
372                     }
373                 } else if (handle instanceof SGroup) {
374                     definedGroups.add(handle);
375                     if (isListenerAttached()) {
376                         fireMenuManagerChanged(new MenuManagerEvent(this, id,
377                                 added, null, false, null, false, null, false,
378                                 null, false));
379                     }
380                 } else if (handle instanceof SItem) {
381                     definedHandleObjects.add(handle);
382                     if (isListenerAttached()) {
383                         fireMenuManagerChanged(new MenuManagerEvent(this, null,
384                                 false, id, added, null, false, null, false,
385                                 null, false));
386                     }
387                 } else if (handle instanceof SMenu) {
388                     definedMenus.add(handle);
389                     if (isListenerAttached()) {
390                         fireMenuManagerChanged(new MenuManagerEvent(this, null,
391                                 false, null, false, id, added, null, false,
392                                 null, false));
393                     }
394                 } else if (handle instanceof SWidget) {
395                     definedWidgets.add(handle);
396                     if (isListenerAttached()) {
397                         fireMenuManagerChanged(new MenuManagerEvent(this, null,
398                                 false, null, false, null, false, id, added,
399                                 null, false));
400                     }
401                 }
402             } else {
403                 if (handle instanceof SActionSet) {
404                     definedActionSets.remove(handle);
405                     if (isListenerAttached()) {
406                         fireMenuManagerChanged(new MenuManagerEvent(this, null,
407                                 false, null, false, null, false, null, false,
408                                 id, added));
409                     }
410                 } else if (handle instanceof SGroup) {
411                     definedGroups.remove(handle);
412                     if (isListenerAttached()) {
413                         fireMenuManagerChanged(new MenuManagerEvent(this, id,
414                                 added, null, false, null, false, null, false,
415                                 null, false));
416                     }
417                 } else if (handle instanceof SItem) {
418                     definedHandleObjects.remove(handle);
419                     if (isListenerAttached()) {
420                         fireMenuManagerChanged(new MenuManagerEvent(this, null,
421                                 false, id, added, null, false, null, false,
422                                 null, false));
423                     }
424                 } else if (handle instanceof SMenu) {
425                     definedMenus.remove(handle);
426                     if (isListenerAttached()) {
427                         fireMenuManagerChanged(new MenuManagerEvent(this, null,
428                                 false, null, false, id, added, null, false,
429                                 null, false));
430                     }
431                 } else if (handle instanceof SWidget) {
432                     definedWidgets.remove(handle);
433                     if (isListenerAttached()) {
434                         fireMenuManagerChanged(new MenuManagerEvent(this, null,
435                                 false, null, false, null, false, id, added,
436                                 null, false));
437                     }
438                 }
439             }
440         }
441     }
442
443     /**
444      * Removes a listener from this menu manager.
445      *
446      * @param listener
447      * The listener to be removed; must not be <code>null</code>.
448      */

449     public final void removeListener(final IMenuManagerListener listener) {
450         removeListenerObject(listener);
451     }
452 }
453
Popular Tags