001/* JMenuItem.java --
002   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package javax.swing;
040
041import java.awt.Component;
042import java.awt.event.KeyEvent;
043import java.awt.event.MouseEvent;
044import java.beans.PropertyChangeEvent;
045import java.beans.PropertyChangeListener;
046import java.util.EventListener;
047
048import javax.accessibility.Accessible;
049import javax.accessibility.AccessibleContext;
050import javax.accessibility.AccessibleRole;
051import javax.accessibility.AccessibleState;
052import javax.swing.event.ChangeEvent;
053import javax.swing.event.ChangeListener;
054import javax.swing.event.MenuDragMouseEvent;
055import javax.swing.event.MenuDragMouseListener;
056import javax.swing.event.MenuKeyEvent;
057import javax.swing.event.MenuKeyListener;
058import javax.swing.plaf.MenuItemUI;
059
060/**
061 * JMenuItem represents element in the menu. It inherits most of
062 * its functionality from AbstractButton, however its behavior somewhat
063 * varies from it. JMenuItem fire different kinds of events.
064 * PropertyChangeEvents are fired when menuItems properties are modified;
065 * ChangeEvents are fired when menuItem's state changes and actionEvents are
066 * fired when menu item is selected. In addition to this events menuItem also
067 * fire MenuDragMouseEvent and MenuKeyEvents when mouse is dragged over
068 * the menu item or associated key with menu item is invoked respectively.
069 */
070public class JMenuItem extends AbstractButton implements Accessible,
071                                                         MenuElement
072{
073  private static final long serialVersionUID = -1681004643499461044L;
074
075  /** Combination of keyboard keys that can be used to activate this menu item */
076  private KeyStroke accelerator;
077
078  /**
079   * Indicates if we are currently dragging the mouse.
080   */
081  private boolean isDragging;
082
083  /**
084   * Creates a new JMenuItem object.
085   */
086  public JMenuItem()
087  {
088    this(null, null);
089  }
090
091  /**
092   * Creates a new JMenuItem with the given icon.
093   *
094   * @param icon Icon that will be displayed on the menu item
095   */
096  public JMenuItem(Icon icon)
097  {
098    // FIXME: The requestedFocusEnabled property should
099    // be set to false, when only icon is set for menu item.
100    this(null, icon);
101  }
102
103  /**
104   * Creates a new JMenuItem with the given label.
105   *
106   * @param text label for the menu item
107   */
108  public JMenuItem(String text)
109  {
110    this(text, null);
111  }
112
113  /**
114   * Creates a new JMenuItem associated with the specified action.
115   *
116   * @param action action for this menu item
117   */
118  public JMenuItem(Action action)
119  {
120    super();
121    super.setAction(action);
122    setModel(new DefaultButtonModel());
123    init(null, null);
124    if (action != null)
125      {
126        String name = (String) action.getValue(Action.NAME);
127        if (name != null)
128          setName(name);
129
130        KeyStroke accel = (KeyStroke) action.getValue(Action.ACCELERATOR_KEY);
131        if (accel != null)
132          setAccelerator(accel);
133
134        Integer mnemonic = (Integer) action.getValue(Action.MNEMONIC_KEY);
135        if (mnemonic != null)
136          setMnemonic(mnemonic.intValue());
137
138        String command = (String) action.getValue(Action.ACTION_COMMAND_KEY);
139        if (command != null)
140          setActionCommand(command);
141      }
142  }
143
144  /**
145   * Creates a new JMenuItem with specified text and icon.
146   * Text is displayed to the left of icon by default.
147   *
148   * @param text label for this menu item
149   * @param icon icon that will be displayed on this menu item
150   */
151  public JMenuItem(String text, Icon icon)
152  {
153    super();
154    setModel(new DefaultButtonModel());
155    init(text, icon);
156  }
157
158  /**
159   * Creates a new JMenuItem object.
160   *
161   * @param text label for this menu item
162   * @param mnemonic - Single key that can be used with a
163   * look-and-feel meta key to activate this menu item. However
164   * menu item should be visible on the screen when mnemonic is used.
165   */
166  public JMenuItem(String text, int mnemonic)
167  {
168    this(text, null);
169    setMnemonic(mnemonic);
170  }
171
172  /**
173   * Initializes this menu item
174   *
175   * @param text label for this menu item
176   * @param icon icon to be displayed for this menu item
177   */
178  protected void init(String text, Icon icon)
179  {
180    super.init(text, icon);
181
182    // Initializes properties for this menu item, that are different
183    // from Abstract button properties. 
184    /* NOTE: According to java specifications paint_border should be set to false,
185      since menu item should not have a border. However running few java programs
186      it seems that menu items and menues can have a border. Commenting
187      out statement below for now. */
188    //borderPainted = false;
189    focusPainted = false;
190    horizontalAlignment = JButton.LEADING;
191    horizontalTextPosition = JButton.TRAILING;
192  }
193
194  /**
195   * Set the "UI" property of the menu item, which is a look and feel class
196   * responsible for handling menuItem's input events and painting it.
197   *
198   * @param ui The new "UI" property
199   */
200  public void setUI(MenuItemUI ui)
201  {
202    super.setUI(ui);
203  }
204  
205  /**
206   * This method sets this menuItem's UI to the UIManager's default for the
207   * current look and feel.
208   */
209  public void updateUI()
210  {
211    setUI((MenuItemUI) UIManager.getUI(this));
212  }
213
214  /**
215   * This method returns a name to identify which look and feel class will be
216   * the UI delegate for the menuItem.
217   *
218   * @return The Look and Feel classID. "MenuItemUI"
219   */
220  public String getUIClassID()
221  {
222    return "MenuItemUI";
223  }
224
225  /**
226   * Returns true if button's model is armed and false otherwise. The
227   * button model is armed if menu item has focus or it is selected.
228   *
229   * @return $boolean$ true if button's model is armed and false otherwise
230   */
231  public boolean isArmed()
232  {
233    return getModel().isArmed();
234  }
235
236  /**
237   * Sets menuItem's "ARMED" property
238   *
239   * @param armed DOCUMENT ME!
240   */
241  public void setArmed(boolean armed)
242  {
243    getModel().setArmed(armed);
244  }
245
246  /**
247   * Enable or disable menu item. When menu item is disabled,
248   * its text and icon are grayed out if they exist.
249   *
250   * @param enabled if true enable menu item, and disable otherwise.
251   */
252  public void setEnabled(boolean enabled)
253  {
254    super.setEnabled(enabled);
255  }
256
257  /**
258   * Return accelerator for this menu item.
259   *
260   * @return $KeyStroke$ accelerator for this menu item.
261   */
262  public KeyStroke getAccelerator()
263  {
264    return accelerator;
265  }
266
267  /**
268   * Sets the key combination which invokes the menu item's action 
269   * listeners without navigating the menu hierarchy. Note that when the 
270   * keyboard accelerator is typed, it will work whether or not the 
271   * menu is currently displayed.
272   * 
273   * @param keystroke accelerator for this menu item.
274   */
275  public void setAccelerator(KeyStroke keystroke)
276  {
277    KeyStroke old = this.accelerator;
278    this.accelerator = keystroke;
279    firePropertyChange ("accelerator", old, keystroke);
280  }
281
282  /**
283   * Configures menu items' properties from properties of the specified action.
284   * This method overrides configurePropertiesFromAction from AbstractButton
285   * to also set accelerator property.
286   *
287   * @param action action to configure properties from
288   */
289  protected void configurePropertiesFromAction(Action action)
290  {
291    super.configurePropertiesFromAction(action);
292
293    if (! (this instanceof JMenu) && action != null)
294      {
295        setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY)));
296        if (accelerator != null)
297          super.registerKeyboardAction(action, accelerator, 
298                                       JComponent.WHEN_IN_FOCUSED_WINDOW);
299      }
300  }
301
302  /**
303   * Creates PropertyChangeListener to listen for the changes in action
304   * properties.
305   *
306   * @param action action to listen to for property changes
307   *
308   * @return $PropertyChangeListener$ Listener that listens to changes in
309   * action properties.
310   */
311  protected PropertyChangeListener createActionPropertyChangeListener(Action action)
312  {
313    return new PropertyChangeListener()
314      {
315        public void propertyChange(PropertyChangeEvent e)
316        {
317          Action act = (Action) (e.getSource());
318          configurePropertiesFromAction(act);
319        }
320      };
321  }
322
323  /**
324   * Process mouse events forwarded from MenuSelectionManager.
325   *
326   * @param ev event forwarded from MenuSelectionManager
327   * @param path path to the menu element from which event was generated
328   * @param manager MenuSelectionManager for the current menu hierarchy
329   */
330  public void processMouseEvent(MouseEvent ev, MenuElement[] path,
331                                MenuSelectionManager manager)
332  {
333    MenuDragMouseEvent e = new MenuDragMouseEvent(ev.getComponent(),
334                                                  ev.getID(), ev.getWhen(),
335                                                  ev.getModifiers(), ev.getX(),
336                                                  ev.getY(),
337                                                  ev.getClickCount(),
338                                                  ev.isPopupTrigger(), path,
339                                                  manager);
340    processMenuDragMouseEvent(e);
341  }
342
343  /**
344   * Process key events forwarded from MenuSelectionManager.
345   *
346   * @param event event forwarded from MenuSelectionManager
347   * @param path path to the menu element from which event was generated
348   * @param manager MenuSelectionManager for the current menu hierarchy
349   */
350  public void processKeyEvent(KeyEvent event, MenuElement[] path,
351                              MenuSelectionManager manager)
352  {
353    MenuKeyEvent e = new MenuKeyEvent(event.getComponent(), event.getID(),
354                                      event.getWhen(), event.getModifiers(),
355                                      event.getKeyCode(), event.getKeyChar(),
356                                      path, manager);
357    processMenuKeyEvent(e);
358
359    // Consume original key event, if the menu key event has been consumed.
360    if (e.isConsumed())
361      event.consume();
362  }
363
364  /**
365   * This method fires MenuDragMouseEvents to registered listeners.
366   * Different types of MenuDragMouseEvents are fired depending
367   * on the observed mouse event.
368   *
369   * @param event Mouse
370   */
371  public void processMenuDragMouseEvent(MenuDragMouseEvent event)
372  {
373    switch (event.getID())
374      {
375      case MouseEvent.MOUSE_ENTERED:
376        isDragging = false;
377        fireMenuDragMouseEntered(event);
378        break;
379      case MouseEvent.MOUSE_EXITED:
380        isDragging = false;
381        fireMenuDragMouseExited(event);
382        break;
383      case MouseEvent.MOUSE_DRAGGED:
384        isDragging = true;
385        fireMenuDragMouseDragged(event);
386        break;
387      case MouseEvent.MOUSE_RELEASED:
388        if (isDragging)
389          fireMenuDragMouseReleased(event);
390        break;
391      }
392  }
393
394  /**
395   * This method fires MenuKeyEvent to registered listeners.
396   * Different types of MenuKeyEvents are fired depending
397   * on the observed key event.
398   *
399   * @param event DOCUMENT ME!
400   */
401  public void processMenuKeyEvent(MenuKeyEvent event)
402  {
403    switch (event.getID())
404    {
405      case KeyEvent.KEY_PRESSED:
406        fireMenuKeyPressed(event);
407        break;
408      case KeyEvent.KEY_RELEASED:
409        fireMenuKeyReleased(event);
410        break;
411      case KeyEvent.KEY_TYPED:
412        fireMenuKeyTyped(event);
413        break;
414      default:
415        break;
416    }
417  }
418
419  /**
420   * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
421   *
422   * @param event The event signifying that mouse entered menuItem while it was dragged
423   */
424  protected void fireMenuDragMouseEntered(MenuDragMouseEvent event)
425  {
426    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
427
428    for (int i = 0; i < ll.length; i++)
429      ((MenuDragMouseListener) ll[i]).menuDragMouseEntered(event);
430  }
431
432  /**
433   * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
434   *
435   * @param event The event signifying that mouse has exited menu item, while it was dragged
436   */
437  protected void fireMenuDragMouseExited(MenuDragMouseEvent event)
438  {
439    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
440
441    for (int i = 0; i < ll.length; i++)
442      ((MenuDragMouseListener) ll[i]).menuDragMouseExited(event);
443  }
444
445  /**
446   * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
447   *
448   * @param event The event signifying that mouse is being dragged over the menuItem
449   */
450  protected void fireMenuDragMouseDragged(MenuDragMouseEvent event)
451  {
452    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
453
454    for (int i = 0; i < ll.length; i++)
455      ((MenuDragMouseListener) ll[i]).menuDragMouseDragged(event);
456  }
457
458  /**
459   * This method fires a MenuDragMouseEvent to all the MenuItem's MouseInputListeners.
460   *
461   * @param event The event signifying that mouse was released while it was dragged over the menuItem
462   */
463  protected void fireMenuDragMouseReleased(MenuDragMouseEvent event)
464  {
465    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
466
467    for (int i = 0; i < ll.length; i++)
468      ((MenuDragMouseListener) ll[i]).menuDragMouseReleased(event);
469  }
470
471  /**
472   * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
473   *
474   * @param event The event signifying that key associated with this menu was pressed
475   */
476  protected void fireMenuKeyPressed(MenuKeyEvent event)
477  {
478    EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
479
480    for (int i = 0; i < ll.length; i++)
481      ((MenuKeyListener) ll[i]).menuKeyPressed(event);
482  }
483
484  /**
485   * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
486   *
487   * @param event The event signifying that key associated with this menu was released
488   */
489  protected void fireMenuKeyReleased(MenuKeyEvent event)
490  {
491    EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
492
493    for (int i = 0; i < ll.length; i++)
494      ((MenuKeyListener) ll[i]).menuKeyTyped(event);
495  }
496
497  /**
498   * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
499   *
500   * @param event The event signifying that key associated with this menu was typed.
501   *        The key is typed when it was pressed and then released
502   */
503  protected void fireMenuKeyTyped(MenuKeyEvent event)
504  {
505    EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
506
507    for (int i = 0; i < ll.length; i++)
508      ((MenuKeyListener) ll[i]).menuKeyTyped(event);
509  }
510
511  /**
512   * Method of the MenuElement interface.
513   * This method is invoked by MenuSelectionManager when selection of
514   * this menu item has changed. If this menu item was selected then
515   * arm it's model, and disarm the model otherwise. The menu item
516   * is considered to be selected, and thus highlighted when its model
517   * is armed.
518   *
519   * @param changed indicates selection status of this menu item. If changed is
520   * true then menu item is selected and deselected otherwise.
521   */
522  public void menuSelectionChanged(boolean changed)
523  {
524    Component parent = this.getParent();
525    if (changed)
526      {
527        model.setArmed(true);
528
529        if (parent != null && parent instanceof JPopupMenu)
530          ((JPopupMenu) parent).setSelected(this);
531      }
532    else
533      {
534        model.setArmed(false);
535
536        if (parent != null && parent instanceof JPopupMenu)
537          ((JPopupMenu) parent).getSelectionModel().clearSelection();
538      }
539  }
540
541  /**
542   * Method of the MenuElement interface.
543   *
544   * @return $MenuElement[]$ Returns array of sub-components for this menu
545   *         item. By default menuItem doesn't have any subcomponents and so
546   *         empty array is returned instead.
547   */
548  public MenuElement[] getSubElements()
549  {
550    return new MenuElement[0];
551  }
552
553  /**
554   * Returns reference to the component that will paint this menu item.
555   *
556   * @return $Component$ Component that will paint this menu item.
557   *         Simply returns reference to this menu item.
558   */
559  public Component getComponent()
560  {
561    return this;
562  }
563
564  /**
565   * Adds a MenuDragMouseListener to this menu item. When mouse
566   * is dragged over the menu item the MenuDragMouseEvents will be
567   * fired, and these listeners will be called.
568   *
569   * @param listener The new listener to add
570   */
571  public void addMenuDragMouseListener(MenuDragMouseListener listener)
572  {
573    listenerList.add(MenuDragMouseListener.class, listener);
574  }
575
576  /**
577   * Removes a MenuDragMouseListener from the menuItem's listener list.
578   *
579   * @param listener The listener to remove
580   */
581  public void removeMenuDragMouseListener(MenuDragMouseListener listener)
582  {
583    listenerList.remove(MenuDragMouseListener.class, listener);
584  }
585
586  /**
587   * Returns all added MenuDragMouseListener objects.
588   *
589   * @return an array of listeners
590   *
591   * @since 1.4
592   */
593  public MenuDragMouseListener[] getMenuDragMouseListeners()
594  {
595    return (MenuDragMouseListener[]) listenerList.getListeners(MenuDragMouseListener.class);
596  }
597
598  /**
599   * Adds an MenuKeyListener to this menu item.  This listener will be
600   * invoked when MenuKeyEvents will be fired by this menu item.
601   *
602   * @param listener The new listener to add
603   */
604  public void addMenuKeyListener(MenuKeyListener listener)
605  {
606    listenerList.add(MenuKeyListener.class, listener);
607  }
608
609  /**
610   * Removes an MenuKeyListener from the menuItem's listener list.
611   *
612   * @param listener The listener to remove
613   */
614  public void removeMenuKeyListener(MenuKeyListener listener)
615  {
616    listenerList.remove(MenuKeyListener.class, listener);
617  }
618
619  /**
620   * Returns all added MenuKeyListener objects.
621   *
622   * @return an array of listeners
623   *
624   * @since 1.4
625   */
626  public MenuKeyListener[] getMenuKeyListeners()
627  {
628    return (MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class);
629  }
630
631  /**
632   * Returns a string describing the attributes for the <code>JMenuItem</code>
633   * component, for use in debugging.  The return value is guaranteed to be 
634   * non-<code>null</code>, but the format of the string may vary between
635   * implementations.
636   *
637   * @return A string describing the attributes of the <code>JMenuItem</code>.
638   */
639  protected String paramString()
640  {
641    // calling super seems to be sufficient here...
642    return super.paramString();
643  }
644
645  /**
646   * Returns the object that provides accessibility features for this
647   * <code>JMenuItem</code> component.
648   *
649   * @return The accessible context (an instance of 
650   *     {@link AccessibleJMenuItem}).
651   */
652  public AccessibleContext getAccessibleContext()
653  {
654    if (accessibleContext == null)
655      {
656        AccessibleJMenuItem ctx = new AccessibleJMenuItem(); 
657        addChangeListener(ctx);
658        accessibleContext = ctx;
659      }
660
661    return accessibleContext;
662  }
663
664  /**
665   * Provides the accessibility features for the <code>JMenuItem</code> 
666   * component.
667   * 
668   * @see JMenuItem#getAccessibleContext()
669   */
670  protected class AccessibleJMenuItem extends AccessibleAbstractButton
671    implements ChangeListener
672  {
673    private static final long serialVersionUID = 6748924232082076534L;
674
675    private boolean armed;
676    private boolean focusOwner;
677    private boolean pressed;
678    private boolean selected;
679
680    /**
681     * Creates a new <code>AccessibleJMenuItem</code> instance.
682     */
683    AccessibleJMenuItem()
684    {
685      //super(component);
686    }
687
688    /**
689     * Receives notification when the menu item's state changes and fires
690     * appropriate property change events to registered listeners.
691     *
692     * @param event the change event
693     */
694    public void stateChanged(ChangeEvent event)
695    {
696      // This is fired in all cases.
697      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
698                         Boolean.FALSE, Boolean.TRUE);
699
700      ButtonModel model = getModel();
701
702      // Handle the armed property.
703      if (model.isArmed())
704        {
705          if (! armed)
706            {
707              armed = true;
708              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
709                                 AccessibleState.ARMED, null);
710            }
711        }
712      else
713        {
714          if (armed)
715            {
716              armed = false;
717              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
718                                 null, AccessibleState.ARMED);
719            }
720        }
721
722      // Handle the pressed property.
723      if (model.isPressed())
724        {
725          if (! pressed)
726            {
727              pressed = true;
728              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
729                                 AccessibleState.PRESSED, null);
730            }
731        }
732      else
733        {
734          if (pressed)
735            {
736              pressed = false;
737              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
738                                 null, AccessibleState.PRESSED);
739            }
740        }
741
742      // Handle the selected property.
743      if (model.isSelected())
744        {
745          if (! selected)
746            {
747              selected = true;
748              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
749                                 AccessibleState.SELECTED, null);
750            }
751        }
752      else
753        {
754          if (selected)
755            {
756              selected = false;
757              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
758                                 null, AccessibleState.SELECTED);
759            }
760        }
761
762      // Handle the focusOwner property.
763      if (isFocusOwner())
764        {
765          if (! focusOwner)
766            {
767              focusOwner = true;
768              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
769                                 AccessibleState.FOCUSED, null);
770            }
771        }
772      else
773        {
774          if (focusOwner)
775            {
776              focusOwner = false;
777              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
778                                 null, AccessibleState.FOCUSED);
779            }
780        }
781    }
782
783    /**
784     * Returns the accessible role for the <code>JMenuItem</code> component.
785     *
786     * @return {@link AccessibleRole#MENU_ITEM}.
787     */
788    public AccessibleRole getAccessibleRole()
789    {
790      return AccessibleRole.MENU_ITEM;
791    }
792  }
793
794  /**
795   * Returns <code>true</code> if the component is guaranteed to be painted
796   * on top of others. This returns false by default and is overridden by
797   * components like JMenuItem, JPopupMenu and JToolTip to return true for
798   * added efficiency.
799   *
800   * @return <code>true</code> if the component is guaranteed to be painted
801   *         on top of others
802   */
803  boolean onTop()
804  {
805    return SwingUtilities.getAncestorOfClass(JInternalFrame.class, this)
806           == null;
807  }
808
809}