View Javadoc
1   package com.vaadin.contextmenu;
2   
3   import java.io.Serializable;
4   import java.util.ArrayList;
5   import java.util.List;
6   import java.util.UUID;
7   
8   import com.vaadin.contextmenu.Menu.Command;
9   import com.vaadin.server.Resource;
10  
11  /**
12   * A composite class for menu items and sub-menus. You can set commands to be
13   * fired on user click by implementing the {@link Menu.Command} interface. You
14   * can also add multiple MenuItems to a MenuItem and create a sub-menu.
15   * 
16   */
17  @SuppressWarnings("serial")
18  class MenuItemImpl implements Serializable, MenuItem {
19  
20      /** Private members * */
21      private final int itsId;
22      private Command itsCommand;
23      private String itsText;
24      private List<MenuItem> itsChildren;
25      private Resource itsIcon;
26      private MenuItem itsParent;
27      private boolean enabled = true;
28      private boolean visible = true;
29      private boolean isSeparator = false;
30      private String styleName;
31      private String description;
32      private boolean checkable = false;
33      private boolean checked = false;
34  
35      private void markAsDirty() {
36          // FIXME we need to delegate this to the MenuBar or better convert the
37          // menubar to Vaadin 7 communication
38          // and remove this method
39      }
40  
41      /**
42       * Constructs a new menu item that can optionally have an icon and a command
43       * associated with it. Icon and command can be null, but a caption must be
44       * given.
45       * 
46       * @param caption
47       *            The text associated with the command
48       * @param command
49       *            The command to be fired
50       * @throws IllegalArgumentException
51       */
52      public MenuItemImpl(String caption, Resource icon, Command command) {
53          if (caption == null) {
54              throw new IllegalArgumentException("caption cannot be null");
55          }
56  
57          itsId = getNextId();
58          itsText = caption;
59          itsIcon = icon;
60          itsCommand = command;
61      }
62  
63      public MenuItemImpl(MenuItem parent, String trim, Resource icon,
64              Command object) {
65          this(trim, icon, object);
66          setParent(parent);
67      }
68  
69      protected int getNextId() {
70          // FIXME is this good enough? maybe just random?
71          return UUID.randomUUID().hashCode();
72      }
73  
74      /*
75       * (non-Javadoc)
76       * 
77       * @see com.example.contextmenu.menubar.MenuItem#hasChildren()
78       */
79      @Override
80      public boolean hasChildren() {
81          return !isSeparator() && itsChildren != null;
82      }
83  
84      /*
85       * (non-Javadoc)
86       * 
87       * @see com.example.contextmenu.menubar.MenuItem#addSeparator()
88       */
89      @Override
90      public MenuItem addSeparator() {
91          MenuItem item = addItem(true, "", null, null);
92          return item;
93      }
94  
95      /*
96       * (non-Javadoc)
97       * 
98       * @see
99       * com.example.contextmenu.menubar.MenuItem#addSeparatorBefore(com.example
100      * .contextmenu.menubar.MenuItem)
101      */
102     @Override
103     public MenuItem addSeparatorBefore(MenuItem itemToAddBefore) {
104         MenuItem item = addItemBefore(true, "", null, null, itemToAddBefore);
105         return item;
106     }
107 
108     /*
109      * (non-Javadoc)
110      * 
111      * @see com.example.contextmenu.menubar.MenuItem#addItem(java.lang.String,
112      * com.example.contextmenu.menubar.Menu.Command)
113      */
114     @Override
115     public MenuItem addItem(String caption, Command command) {
116         return addItem(caption, null, command);
117     }
118 
119     /*
120      * (non-Javadoc)
121      * 
122      * @see com.example.contextmenu.menubar.MenuItem#addItem(java.lang.String,
123      * com.vaadin.server.Resource, com.example.contextmenu.menubar.Menu.Command)
124      */
125     @Override
126     public MenuItem addItem(String caption, Resource icon, Command command)
127             throws IllegalStateException {
128         return addItem(false, caption, icon, command);
129     }
130 
131     private MenuItem addItem(boolean separator, String caption, Resource icon,
132             Command command) throws IllegalStateException {
133         if (isSeparator()) {
134             throw new UnsupportedOperationException(
135                     "Cannot add items to a separator");
136         }
137         if (isCheckable()) {
138             throw new IllegalStateException(
139                     "A checkable item cannot have children");
140         }
141         if (caption == null) {
142             throw new IllegalArgumentException("Caption cannot be null");
143         }
144 
145         if (itsChildren == null) {
146             itsChildren = new ArrayList<MenuItem>();
147         }
148 
149         MenuItemImpl newItem = new MenuItemImpl(this, caption, icon, command);
150 
151         newItem.setSeparator(separator);
152 
153         itsChildren.add(newItem);
154 
155         markAsDirty();
156 
157         return newItem;
158     }
159 
160     /*
161      * (non-Javadoc)
162      * 
163      * @see
164      * com.example.contextmenu.menubar.MenuItem#addItemBefore(java.lang.String,
165      * com.vaadin.server.Resource, com.example.contextmenu.menubar.Menu.Command,
166      * com.example.contextmenu.menubar.MenuItem)
167      */
168     @Override
169     public MenuItem addItemBefore(String caption, Resource icon,
170             Command command, MenuItem itemToAddBefore) {
171         return addItemBefore(false, caption, icon, command, itemToAddBefore);
172     }
173 
174     private MenuItem addItemBefore(boolean separator, String caption,
175             Resource icon, Command command, MenuItem itemToAddBefore)
176             throws IllegalStateException {
177         if (isCheckable()) {
178             throw new IllegalStateException(
179                     "A checkable item cannot have children");
180         }
181         MenuItem newItem = null;
182 
183         if (hasChildren() && itsChildren.contains(itemToAddBefore)) {
184             int index = itsChildren.indexOf(itemToAddBefore);
185             newItem = new MenuItemImpl(this, caption, icon, command);
186             itsChildren.add(index, newItem);
187         } else {
188             newItem = addItem(caption, icon, command);
189         }
190 
191         markAsDirty();
192 
193         return newItem;
194     }
195 
196     /*
197      * (non-Javadoc)
198      * 
199      * @see com.example.contextmenu.menubar.MenuItem#getCommand()
200      */
201     @Override
202     public Command getCommand() {
203         return itsCommand;
204     }
205 
206     /*
207      * (non-Javadoc)
208      * 
209      * @see com.example.contextmenu.menubar.MenuItem#getIcon()
210      */
211     @Override
212     public Resource getIcon() {
213         return itsIcon;
214     }
215 
216     /*
217      * (non-Javadoc)
218      * 
219      * @see com.example.contextmenu.menubar.MenuItem#getParent()
220      */
221     @Override
222     public MenuItem getParent() {
223         return itsParent;
224     }
225 
226     /*
227      * (non-Javadoc)
228      * 
229      * @see com.example.contextmenu.menubar.MenuItem#getChildren()
230      */
231     @Override
232     public List<MenuItem> getChildren() {
233         return itsChildren;
234     }
235 
236     /*
237      * (non-Javadoc)
238      * 
239      * @see com.example.contextmenu.menubar.MenuItem#getText()
240      */
241     @Override
242     public java.lang.String getText() {
243         return itsText;
244     }
245 
246     /*
247      * (non-Javadoc)
248      * 
249      * @see com.example.contextmenu.menubar.MenuItem#getSize()
250      */
251     @Override
252     public int getSize() {
253         if (itsChildren != null) {
254             return itsChildren.size();
255         }
256         return -1;
257     }
258 
259     /*
260      * (non-Javadoc)
261      * 
262      * @see com.example.contextmenu.menubar.MenuItem#getId()
263      */
264     @Override
265     public int getId() {
266         return itsId;
267     }
268 
269     /*
270      * (non-Javadoc)
271      * 
272      * @see com.example.contextmenu.menubar.MenuItem#setCommand(com.example.
273      * contextmenu .menubar.Menu.Command)
274      */
275     @Override
276     public void setCommand(Command command) {
277         itsCommand = command;
278     }
279 
280     /*
281      * (non-Javadoc)
282      * 
283      * @see com.example.contextmenu.menubar.MenuItem#setIcon(com.vaadin.server.
284      * Resource )
285      */
286     @Override
287     public void setIcon(Resource icon) {
288         itsIcon = icon;
289         markAsDirty();
290     }
291 
292     /*
293      * (non-Javadoc)
294      * 
295      * @see com.example.contextmenu.menubar.MenuItem#setText(java.lang.String)
296      */
297     @Override
298     public void setText(java.lang.String text) {
299         if (text != null) {
300             itsText = text;
301         }
302         markAsDirty();
303     }
304 
305     /*
306      * (non-Javadoc)
307      * 
308      * @see com.example.contextmenu.menubar.MenuItem#removeChild(com.example.
309      * contextmenu .menubar.MenuItem)
310      */
311     @Override
312     public void removeChild(MenuItem item) {
313         if (item != null && itsChildren != null) {
314             itsChildren.remove(item);
315             if (itsChildren.isEmpty()) {
316                 itsChildren = null;
317             }
318             markAsDirty();
319         }
320     }
321 
322     /*
323      * (non-Javadoc)
324      * 
325      * @see com.example.contextmenu.menubar.MenuItem#removeChildren()
326      */
327     @Override
328     public void removeChildren() {
329         if (itsChildren != null) {
330             itsChildren.clear();
331             itsChildren = null;
332             markAsDirty();
333         }
334     }
335 
336     /**
337      * Set the parent of this item. This is called by the addItem method.
338      * 
339      * @param parent
340      *            The parent item
341      */
342     protected void setParent(MenuItem parent) {
343         itsParent = parent;
344     }
345 
346     /*
347      * (non-Javadoc)
348      * 
349      * @see com.example.contextmenu.menubar.MenuItem#setEnabled(boolean)
350      */
351     @Override
352     public void setEnabled(boolean enabled) {
353         this.enabled = enabled;
354         markAsDirty();
355     }
356 
357     /*
358      * (non-Javadoc)
359      * 
360      * @see com.example.contextmenu.menubar.MenuItem#isEnabled()
361      */
362     @Override
363     public boolean isEnabled() {
364         return enabled;
365     }
366 
367     /*
368      * (non-Javadoc)
369      * 
370      * @see com.example.contextmenu.menubar.MenuItem#setVisible(boolean)
371      */
372     @Override
373     public void setVisible(boolean visible) {
374         this.visible = visible;
375         markAsDirty();
376     }
377 
378     /*
379      * (non-Javadoc)
380      * 
381      * @see com.example.contextmenu.menubar.MenuItem#isVisible()
382      */
383     @Override
384     public boolean isVisible() {
385         return visible;
386     }
387 
388     protected void setSeparator(boolean isSeparator) {
389         this.isSeparator = isSeparator;
390         markAsDirty();
391     }
392 
393     /*
394      * (non-Javadoc)
395      * 
396      * @see com.example.contextmenu.menubar.MenuItem#isSeparator()
397      */
398     @Override
399     public boolean isSeparator() {
400         return isSeparator;
401     }
402 
403     /*
404      * (non-Javadoc)
405      * 
406      * @see
407      * com.example.contextmenu.menubar.MenuItem#setStyleName(java.lang.String)
408      */
409     @Override
410     public void setStyleName(String styleName) {
411         this.styleName = styleName;
412         markAsDirty();
413     }
414 
415     /*
416      * (non-Javadoc)
417      * 
418      * @see com.example.contextmenu.menubar.MenuItem#getStyleName()
419      */
420     @Override
421     public String getStyleName() {
422         return styleName;
423     }
424 
425     /*
426      * (non-Javadoc)
427      * 
428      * @see
429      * com.example.contextmenu.menubar.MenuItem#setDescription(java.lang.String)
430      */
431     @Override
432     public void setDescription(String description) {
433         this.description = description;
434         markAsDirty();
435     }
436 
437     /*
438      * (non-Javadoc)
439      * 
440      * @see com.example.contextmenu.menubar.MenuItem#getDescription()
441      */
442     @Override
443     public String getDescription() {
444         return description;
445     }
446 
447     /*
448      * (non-Javadoc)
449      * 
450      * @see com.example.contextmenu.menubar.MenuItem#isCheckable()
451      */
452     @Override
453     public boolean isCheckable() {
454         return checkable;
455     }
456 
457     /*
458      * (non-Javadoc)
459      * 
460      * @see com.example.contextmenu.menubar.MenuItem#setCheckable(boolean)
461      */
462     @Override
463     public void setCheckable(boolean checkable) throws IllegalStateException {
464         if (hasChildren()) {
465             throw new IllegalStateException(
466                     "A menu item with children cannot be checkable");
467         }
468         this.checkable = checkable;
469         markAsDirty();
470     }
471 
472     /*
473      * (non-Javadoc)
474      * 
475      * @see com.example.contextmenu.menubar.MenuItem#isChecked()
476      */
477     @Override
478     public boolean isChecked() {
479         return checked;
480     }
481 
482     /*
483      * (non-Javadoc)
484      * 
485      * @see com.example.contextmenu.menubar.MenuItem#setChecked(boolean)
486      */
487     @Override
488     public void setChecked(boolean checked) {
489         this.checked = checked;
490         markAsDirty();
491     }
492 
493     protected void setChildren(List<MenuItem> children) {
494         this.itsChildren = children;
495     }
496 }// class MenuItem