KickJava   Java API By Example, From Geeks To Geeks.

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


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.Map JavaDoc;
15 import java.util.WeakHashMap JavaDoc;
16
17 import org.eclipse.core.commands.common.HandleObject;
18 import org.eclipse.core.commands.common.NotDefinedException;
19 import org.eclipse.jface.util.IPropertyChangeListener;
20 import org.eclipse.jface.util.PropertyChangeEvent;
21 import org.eclipse.jface.util.Util;
22 import org.eclipse.jface.window.Window;
23
24 /**
25  * <p>
26  * A handle object existing in the menus. This can be either a menu, a group, an
27  * item or a widget.
28  * </p>
29  * <p>
30  * For menu elements, there is the concept of "showing" and "visible". "Showing"
31  * means that the menu element could potentially be visible to the end user.
32  * This property is under control of the user. So, for example, clicking on a
33  * top-level menu while make all of its contents "showing". "Visible" means that
34  * the menu element should be painted on the display if it is showing. This
35  * property is under control of the application. So, for example, an application
36  * could decide to hide some items in a context menu if they do not apply to the
37  * current selection.
38  * </p>
39  * <p>
40  * Clients must not implement or extend.
41  * </p>
42  * <p>
43  * <strong>PROVISIONAL</strong>. This class or interface has been added as
44  * part of a work in progress. There is a guarantee neither that this API will
45  * work nor that it will remain the same. Please do not use this API without
46  * consulting with the Platform/UI team.
47  * </p>
48  * <p>
49  * This class will eventually exist in <code>org.eclipse.jface.menus</code>.
50  * </p>
51  *
52  * @since 3.2
53  * @see org.eclipse.ui.internal.menus.SMenu
54  * @see org.eclipse.ui.internal.menus.SGroup
55  * @see org.eclipse.ui.internal.menus.SItem
56  * @see org.eclipse.ui.internal.menus.SWidget
57  */

58 public abstract class MenuElement extends HandleObject {
59
60     /**
61      * The array to return from {@link #getLocations()} if there are no
62      * locations.
63      */

64     private static final SLocation[] NO_LOCATIONS = new SLocation[0];
65
66     /**
67      * The property for a property change event indicating that the defined
68      * state for this menu element has changed.
69      */

70     public static final String JavaDoc PROPERTY_DEFINED = "DEFINED"; //$NON-NLS-1$
71

72     /**
73      * The property for a property change event indicating that the locations
74      * for this menu element have changed.
75      */

76     public static final String JavaDoc PROPERTY_LOCATIONS = "LOCATIONS"; //$NON-NLS-1$
77

78     /**
79      * The property for a property change event indicating that the visibility
80      * for this menu element has changed.
81      */

82     public static final String JavaDoc PROPERTY_VISIBILITY = "VISIBILITY"; //$NON-NLS-1$
83

84     /**
85      * The locations in which this menu element appears. This value may be empty
86      * or <code>null</code>.
87      */

88     protected SLocation[] locations;
89
90     /**
91      * Whether this menu element is currently showing. This is a map of
92      * {@link Window} to {@link Boolean}. This value may be <code>null</code>
93      * if all values are <code>false</code>. The default value for any item
94      * is <code>false</code>.
95      */

96     private Map JavaDoc windowToShowingMap = null;
97
98     /**
99      * Whether this menu element is currently visible. This is a map of
100      * {@link Window} to {@link Boolean}. This value may be <code>null</code>
101      * if all values are <code>false</code>. The default value for any item
102      * is <code>false</code>.
103      */

104     private Map JavaDoc windowToVisibleMap = null;
105
106     /**
107      * Constructs a new instance of <code>MenuElement</code>.
108      *
109      * @param id
110      * The identifier of the element to create; must not be
111      * <code>null</code>.
112      */

113     public MenuElement(final String JavaDoc id) {
114         super(id);
115     }
116
117     /**
118      * Adds a listener to this menu element that will be notified when this menu
119      * element's state changes.
120      *
121      * @param listener
122      * The listener to be added; must not be <code>null</code>.
123      */

124     public final void addListener(final IPropertyChangeListener listener) {
125         addListenerObject(listener);
126     }
127
128     /**
129      * Does this menu element exist at this location.
130      *
131      * @param location
132      * the location to check
133      * @return <code>true</code> if this menu element contains this location.
134      */

135     public boolean containsLocation(final SLocation location) {
136         if (locations!=null && location!=null) {
137             for (int i = 0; i < locations.length; i++) {
138                 if (location.equals(locations[i])) {
139                     return true;
140                 }
141             }
142         }
143         return false;
144     }
145     
146     /**
147      * Adds a location to an existing menu element.
148      *
149      * @param location
150      * The location to add to this element; must not be
151      * <code>null</code>.
152      */

153     public final void addLocation(final SLocation location) {
154         if (location == null) {
155             throw new NullPointerException JavaDoc("The location cannot be null"); //$NON-NLS-1$
156
}
157         
158         if (containsLocation(location)) {
159             return;
160         }
161
162         final SLocation[] newLocations;
163         if ((locations == null) || (locations.length == 0)) {
164             newLocations = new SLocation[] { location };
165         } else {
166             newLocations = new SLocation[locations.length + 1];
167             System.arraycopy(locations, 0, newLocations, 0, locations.length);
168             newLocations[locations.length] = location;
169         }
170         setLocations(newLocations);
171     }
172
173     /**
174      * Notifies listeners to this menu element that it has changed in some way.
175      *
176      * @param event
177      * The event to fire; may be <code>null</code>.
178      */

179     protected final void firePropertyChangeEvent(final PropertyChangeEvent event) {
180         if (event == null) {
181             return;
182         }
183
184         final Object JavaDoc[] listeners = getListeners();
185         for (int i = 0; i < listeners.length; i++) {
186             final IPropertyChangeListener listener = (IPropertyChangeListener) listeners[i];
187             listener.propertyChange(event);
188         }
189     }
190
191     /**
192      * Indicates that the visible property has changed.
193      *
194      * @param visible
195      * Whether this menu element is now visible.
196      */

197     protected final void fireVisibleChanged(final boolean visible) {
198         if (isListenerAttached()) {
199             final PropertyChangeEvent event;
200             if (visible) {
201                 event = new PropertyChangeEvent(this, PROPERTY_VISIBILITY,
202                         Boolean.FALSE, Boolean.TRUE);
203             } else {
204                 event = new PropertyChangeEvent(this, PROPERTY_VISIBILITY,
205                         Boolean.TRUE, Boolean.FALSE);
206             }
207             firePropertyChangeEvent(event);
208         }
209     }
210
211     /**
212      * Returns the locations for this menu collection. This performs a copy of
213      * the internal data structure.
214      *
215      * @return The locations for this menu collection; never <code>null</code>.
216      * @throws NotDefinedException
217      * If the handle is not currently defined.
218      */

219     public final SLocation[] getLocations() throws NotDefinedException {
220         if (!isDefined()) {
221             throw new NotDefinedException(
222                     "Cannot get the locations from an undefined menu element"); //$NON-NLS-1$
223
}
224
225         if (locations == null) {
226             return NO_LOCATIONS;
227         }
228
229         final SLocation[] result = new SLocation[locations.length];
230         System.arraycopy(locations, 0, result, 0, locations.length);
231         return result;
232     }
233
234     /**
235      * Returns whether this menu element is showing within the given window. A
236      * menu element is showing if it could be visible to the user. A menu
237      * element must be showing before the <code>isVisible</code> is checked.
238      *
239      * @param window
240      * The window in which to check if this menu element is showing;
241      * must not be <code>null</code>.
242      * @return <code>true</code> if the menu element is showing;
243      * <code>false</code> otherwise.
244      */

245     public final boolean isShowing(final Window window) {
246         if (windowToShowingMap != null) {
247             Object JavaDoc value = windowToShowingMap.get(window);
248             if (value == null) {
249                 value = windowToShowingMap.get(null);
250             }
251             if (value == Boolean.TRUE) {
252                 return true;
253             }
254         }
255
256         return false;
257     }
258
259     /**
260      * Returns whether this menu element is visible within the given menu. A
261      * menu element is visible if it will be visible to the user if showing.
262      *
263      * @param window
264      * The window in which to check if this menu element is showing;
265      * must not be <code>null</code>.
266      * @return <code>true</code> if the menu element is visible;
267      * <code>false</code> otherwise.
268      */

269     public final boolean isVisible(final Window window) {
270         if (windowToVisibleMap != null) {
271             Object JavaDoc value = windowToVisibleMap.get(window);
272             if (value == null) {
273                 value = windowToVisibleMap.get(null);
274             }
275             if (value == Boolean.FALSE) {
276                 return false;
277             }
278         }
279
280         return true;
281     }
282
283     /**
284      * Removes a listener from this menu element.
285      *
286      * @param listener
287      * The listener to be removed; must not be <code>null</code>.
288      */

289     public final void removeListener(final IPropertyChangeListener listener) {
290         removeListenerObject(listener);
291     }
292
293     /**
294      * Sets whether this menu element is defined. This will fire a property
295      * change event if anyone cares.
296      *
297      * @param defined
298      * Whether the menu element is defined.
299      */

300     protected final void setDefined(final boolean defined) {
301         if (this.defined != defined) {
302             PropertyChangeEvent event = null;
303             if (isListenerAttached()) {
304                 event = new PropertyChangeEvent(this, PROPERTY_DEFINED,
305                         (this.defined ? Boolean.TRUE : Boolean.FALSE),
306                         (defined ? Boolean.TRUE : Boolean.FALSE));
307             }
308             this.defined = defined;
309             firePropertyChangeEvent(event);
310         }
311     }
312
313     /**
314      * Sets the locations in which this menu element will appear. This will fire
315      * a property change event if anyone cares.
316      *
317      * @param locations
318      * The locations in which this menu element will appear; may be
319      * <code>null</code> or empty.
320      */

321     protected final void setLocations(final SLocation[] locations) {
322         if (!Util.equals(this.locations, locations)) {
323             PropertyChangeEvent event = null;
324             if (isListenerAttached()) {
325                 event = new PropertyChangeEvent(this, PROPERTY_LOCATIONS,
326                         this.locations, locations);
327             }
328             this.locations = locations;
329             firePropertyChangeEvent(event);
330         }
331     }
332
333     /**
334      * Sets the showing property for this menu element within the given window.
335      * Changing this property does not trigger a property change event.
336      * Developers interested in listening to changes in this property should
337      * attach a listener to the <code>SMenuManager</code>.
338      *
339      * @param window
340      * The window in which to change if this menu element is showing;
341      * must not be <code>null</code>.
342      * @param showing
343      * Whether the menu element should be showing.
344      * @see SMenuManager#addListener(IMenuManagerListener)
345      */

346     final void setShowing(final Window window, final boolean showing) {
347         if (window == null) {
348             throw new NullPointerException JavaDoc(
349                     "The window in which a menu element is showing must not be null"); //$NON-NLS-1$
350
}
351
352         if (windowToShowingMap == null) {
353             windowToShowingMap = new WeakHashMap JavaDoc(3);
354         }
355         windowToShowingMap.put(window, showing ? Boolean.TRUE : Boolean.FALSE);
356     }
357
358     /**
359      * Sets the visible property. Changing this property triggers an event
360      * appropriate for the subclasses. If no window is provided, then this is
361      * the default visibility.
362      *
363      * @param window
364      * The window in which to change if this menu element is visible;
365      * may be <code>null</code>.
366      * @param visible
367      * Whether the menu element should be visible.
368      */

369     public final void setVisible(final Window window, final boolean visible) {
370         final boolean initialVisible = isVisible(window);
371         if (initialVisible != visible) {
372             if (windowToVisibleMap == null) {
373                 windowToVisibleMap = new WeakHashMap JavaDoc(3);
374             }
375             windowToVisibleMap.put(window, visible ? Boolean.TRUE
376                     : Boolean.FALSE);
377             fireVisibleChanged(visible);
378         }
379     }
380 }
381
Popular Tags