OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [swing/] [JMenu.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* JMenu.java --
2
   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.swing;
40
 
41
import java.awt.Component;
42
import java.awt.Dimension;
43
import java.awt.GraphicsConfiguration;
44
import java.awt.GraphicsDevice;
45
import java.awt.GraphicsEnvironment;
46
import java.awt.Insets;
47
import java.awt.Point;
48
import java.awt.Rectangle;
49
import java.awt.Toolkit;
50
import java.awt.event.KeyEvent;
51
import java.awt.event.WindowAdapter;
52
import java.awt.event.WindowEvent;
53
import java.beans.PropertyChangeEvent;
54
import java.beans.PropertyChangeListener;
55
import java.io.Serializable;
56
import java.util.ArrayList;
57
import java.util.EventListener;
58
 
59
import javax.accessibility.Accessible;
60
import javax.accessibility.AccessibleContext;
61
import javax.accessibility.AccessibleRole;
62
import javax.accessibility.AccessibleSelection;
63
import javax.swing.event.ChangeEvent;
64
import javax.swing.event.ChangeListener;
65
import javax.swing.event.MenuEvent;
66
import javax.swing.event.MenuListener;
67
import javax.swing.plaf.MenuItemUI;
68
 
69
/**
70
 * This class represents a menu that can be added to a menu bar or
71
 * can be a submenu in some other menu. When JMenu is selected it
72
 * displays JPopupMenu containing its menu items.
73
 *
74
 * <p>
75
 * JMenu's fires MenuEvents when this menu's selection changes. If this menu
76
 * is selected, then fireMenuSelectedEvent() is invoked. In case when menu is
77
 * deselected or cancelled, then fireMenuDeselectedEvent() or
78
 * fireMenuCancelledEvent() is invoked, respectivelly.
79
 * </p>
80
 */
81
public class JMenu extends JMenuItem implements Accessible, MenuElement
82
{
83
  /**
84
   * Receives notifications when the JMenu's ButtonModel is changed and
85
   * fires menuSelected or menuDeselected events when appropriate.
86
   */
87
  private class MenuChangeListener
88
    implements ChangeListener
89
  {
90
    /**
91
     * Indicates the last selected state.
92
     */
93
    private boolean selected;
94
 
95
    /**
96
     * Receives notification when the JMenu's ButtonModel changes.
97
     */
98
    public void stateChanged(ChangeEvent ev)
99
    {
100
      ButtonModel m = (ButtonModel) ev.getSource();
101
      boolean s = m.isSelected();
102
      if (s != selected)
103
        {
104
          if (s)
105
            fireMenuSelected();
106
          else
107
            fireMenuDeselected();
108
          selected = s;
109
        }
110
    }
111
  }
112
 
113
  private static final long serialVersionUID = 4227225638931828014L;
114
 
115
  /** A Popup menu associated with this menu, which pops up when menu is selected */
116
  private JPopupMenu popupMenu = null;
117
 
118
  /** Whenever menu is selected or deselected the MenuEvent is fired to
119
     menu's registered listeners. */
120
  private MenuEvent menuEvent = new MenuEvent(this);
121
 
122
  /*Amount of time, in milliseconds, that should pass before popupMenu
123
    associated with this menu appears or disappers */
124
  private int delay;
125
 
126
  /* PopupListener */
127
  protected WinListener popupListener;
128
 
129
  /**
130
   * Location at which popup menu associated with this menu will be
131
   * displayed
132
   */
133
  private Point menuLocation;
134
 
135
  /**
136
   * The ChangeListener for the ButtonModel.
137
   *
138
   * @see MenuChangeListener
139
   */
140
  private ChangeListener menuChangeListener;
141
 
142
  /**
143
   * Creates a new JMenu object.
144
   */
145
  public JMenu()
146
  {
147
    super();
148
    setOpaque(false);
149
  }
150
 
151
  /**
152
   * Creates a new <code>JMenu</code> with the specified label.
153
   *
154
   * @param text label for this menu
155
   */
156
  public JMenu(String text)
157
  {
158
    super(text);
159
    popupMenu = new JPopupMenu();
160
    popupMenu.setInvoker(this);
161
    setOpaque(false);
162
  }
163
 
164
  /**
165
   * Creates a new <code>JMenu</code> object.
166
   *
167
   * @param action Action that is used to create menu item tha will be
168
   * added to the menu.
169
   */
170
  public JMenu(Action action)
171
  {
172
    super(action);
173
    createActionChangeListener(this);
174
    popupMenu = new JPopupMenu();
175
    popupMenu.setInvoker(this);
176
    setOpaque(false);
177
  }
178
 
179
  /**
180
   * Creates a new <code>JMenu</code> with specified label and an option
181
   * for this menu to be tear-off menu.
182
   *
183
   * @param text label for this menu
184
   * @param tearoff true if this menu should be tear-off and false otherwise
185
   */
186
  public JMenu(String text, boolean tearoff)
187
  {
188
    // FIXME: tearoff not implemented
189
    this(text);
190
  }
191
 
192
  /**
193
   * Adds specified menu item to this menu
194
   *
195
   * @param item Menu item to add to this menu
196
   *
197
   * @return Menu item that was added
198
   */
199
  public JMenuItem add(JMenuItem item)
200
  {
201
    return getPopupMenu().add(item);
202
  }
203
 
204
  /**
205
   * Adds specified component to this menu.
206
   *
207
   * @param component Component to add to this menu
208
   *
209
   * @return Component that was added
210
   */
211
  public Component add(Component component)
212
  {
213
    getPopupMenu().insert(component, -1);
214
    return component;
215
  }
216
 
217
  /**
218
   * Adds specified component to this menu at the given index
219
   *
220
   * @param component Component to add
221
   * @param index Position of this menu item in the menu
222
   *
223
   * @return Component that was added
224
   */
225
  public Component add(Component component, int index)
226
  {
227
    return getPopupMenu().add(component, index);
228
  }
229
 
230
  /**
231
   * Adds JMenuItem constructed with the specified label to this menu
232
   *
233
   * @param text label for the menu item that will be added
234
   *
235
   * @return Menu Item that was added to this menu
236
   */
237
  public JMenuItem add(String text)
238
  {
239
    return add(new JMenuItem(text));
240
  }
241
 
242
  /**
243
   * Adds JMenuItem constructed using properties from specified action.
244
   *
245
   * @param action action to construct the menu item with
246
   *
247
   * @return Menu Item that was added to this menu
248
   */
249
  public JMenuItem add(Action action)
250
  {
251
    JMenuItem i = createActionComponent(action);
252
    i.setAction(action);
253
    add(i);
254
    return i;
255
  }
256
 
257
  /**
258
   * Removes given menu item from this menu. Nothing happens if
259
   * this menu doesn't contain specified menu item.
260
   *
261
   * @param item Menu Item which needs to be removed
262
   */
263
  public void remove(JMenuItem item)
264
  {
265
    getPopupMenu().remove(item);
266
  }
267
 
268
  /**
269
   * Removes component at the specified index from this menu
270
   *
271
   * @param index Position of the component that needs to be removed in the menu
272
   */
273
  public void remove(int index)
274
  {
275
    if (index < 0 || (index > 0 && getMenuComponentCount() == 0))
276
      throw new IllegalArgumentException();
277
 
278
    if (getMenuComponentCount() > 0)
279
      popupMenu.remove(index);
280
  }
281
 
282
  /**
283
   * Removes given component from this menu.
284
   *
285
   * @param component Component to remove
286
   */
287
  public void remove(Component component)
288
  {
289
    int index = getPopupMenu().getComponentIndex(component);
290
    if (index >= 0)
291
      getPopupMenu().remove(index);
292
  }
293
 
294
  /**
295
   * Removes all menu items from the menu
296
   */
297
  public void removeAll()
298
  {
299
    if (popupMenu != null)
300
      popupMenu.removeAll();
301
  }
302
 
303
  /**
304
   * Creates JMenuItem with the specified text and inserts it in the
305
   * at the specified index
306
   *
307
   * @param text label for the new menu item
308
   * @param index index at which to insert newly created menu item.
309
   */
310
  public void insert(String text, int index)
311
  {
312
    this.insert(new JMenuItem(text), index);
313
  }
314
 
315
  /**
316
   * Creates JMenuItem with the specified text and inserts it in the
317
   * at the specified index. IllegalArgumentException is thrown
318
   * if index is less than 0
319
   *
320
   * @param item menu item to insert
321
   * @param index index at which to insert menu item.
322
   * @return Menu item that was added to the menu
323
   */
324
  public JMenuItem insert(JMenuItem item, int index)
325
  {
326
    if (index < 0)
327
      throw new IllegalArgumentException("index less than zero");
328
 
329
    getPopupMenu().insert(item, index);
330
    return item;
331
  }
332
 
333
  /**
334
   * Creates JMenuItem with the associated action and inserts it to the menu
335
   * at the specified index. IllegalArgumentException is thrown
336
   * if index is less than 0
337
   *
338
   * @param action Action for the new menu item
339
   * @param index index at which to insert newly created menu item.
340
   * @return Menu item that was added to the menu
341
   */
342
  public JMenuItem insert(Action action, int index)
343
  {
344
    JMenuItem item = new JMenuItem(action);
345
    this.insert(item, index);
346
 
347
    return item;
348
  }
349
 
350
  /**
351
   * This method sets this menuItem's UI to the UIManager's default for the
352
   * current look and feel.
353
   */
354
  public void updateUI()
355
  {
356
    setUI((MenuItemUI) UIManager.getUI(this));
357
  }
358
 
359
  /**
360
   * This method returns a name to identify which look and feel class will be
361
   * the UI delegate for the menu.
362
   *
363
   * @return The Look and Feel classID. "MenuUI"
364
   */
365
  public String getUIClassID()
366
  {
367
    return "MenuUI";
368
  }
369
 
370
  /**
371
   * Sets model for this menu.
372
   *
373
   * @param model model to set
374
   */
375
  public void setModel(ButtonModel model)
376
  {
377
    ButtonModel oldModel = getModel();
378
    if (oldModel != null && menuChangeListener != null)
379
      oldModel.removeChangeListener(menuChangeListener);
380
 
381
    super.setModel(model);
382
 
383
    if (model != null)
384
      {
385
        if (menuChangeListener == null)
386
          menuChangeListener = new MenuChangeListener();
387
        model.addChangeListener(menuChangeListener);
388
      }
389
  }
390
 
391
  /**
392
   * Returns true if the menu is selected and false otherwise
393
   *
394
   * @return true if the menu is selected and false otherwise
395
   */
396
  public boolean isSelected()
397
  {
398
    return super.isSelected();
399
  }
400
 
401
  /**
402
   * Changes this menu selected state if selected is true and false otherwise
403
   * This method fires menuEvents to menu's registered listeners.
404
   *
405
   * @param selected true if the menu should be selected and false otherwise
406
   */
407
  public void setSelected(boolean selected)
408
  {
409
    ButtonModel m = getModel();
410
    if (selected != m.isSelected())
411
      m.setSelected(selected);
412
  }
413
 
414
  /**
415
   * Checks if PopupMenu associated with this menu is visible
416
   *
417
   * @return true if the popup associated with this menu is currently visible
418
   * on the screen and false otherwise.
419
   */
420
  public boolean isPopupMenuVisible()
421
  {
422
    return getPopupMenu().isVisible();
423
  }
424
 
425
  /**
426
   * Sets popup menu visibility
427
   *
428
   * @param popup true if popup should be visible and false otherwise
429
   */
430
  public void setPopupMenuVisible(boolean popup)
431
  {
432
    if (popup != isPopupMenuVisible() && (isEnabled() || ! popup))
433
      {
434
        if (popup && isShowing())
435
          {
436
            // Set location as determined by getPopupLocation().
437
            Point loc = menuLocation == null ? getPopupMenuOrigin()
438
                                             : menuLocation;
439
            getPopupMenu().show(this, loc.x, loc.y);
440
          }
441
        else
442
          getPopupMenu().setVisible(false);
443
      }
444
  }
445
 
446
  /**
447
   * Returns origin point of the popup menu. This takes the screen bounds
448
   * into account and places the popup where it fits best.
449
   *
450
   * @return the origin of the popup menu
451
   */
452
  protected Point getPopupMenuOrigin()
453
  {
454
    // The menu's screen location and size.
455
    Point screenLoc = getLocationOnScreen();
456
    Dimension size = getSize();
457
 
458
    // Determine the popup's size.
459
    JPopupMenu popup = getPopupMenu();
460
    Dimension popupSize = popup.getSize();
461
    if (popupSize.width == 0 || popupSize.height == 0)
462
      popupSize = popup.getPreferredSize();
463
 
464
    // Determine screen bounds.
465
    Toolkit tk = Toolkit.getDefaultToolkit();
466
    Rectangle screenBounds = new Rectangle(tk.getScreenSize());
467
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
468
    GraphicsDevice gd = ge.getDefaultScreenDevice();
469
    GraphicsConfiguration gc = gd.getDefaultConfiguration();
470
    Insets screenInsets = tk.getScreenInsets(gc);
471
    screenBounds.x -= screenInsets.left;
472
    screenBounds.width -= screenInsets.left + screenInsets.right;
473
    screenBounds.y -= screenInsets.top;
474
    screenBounds.height -= screenInsets.top + screenInsets.bottom;
475
    screenLoc.x -= screenInsets.left;
476
    screenLoc.y -= screenInsets.top;
477
 
478
    Point point = new Point();
479
    if (isTopLevelMenu())
480
      {
481
        // If menu in the menu bar.
482
        int xOffset = UIManager.getInt("Menu.menuPopupOffsetX");
483
        int yOffset = UIManager.getInt("Menu.menuPopupOffsetY");
484
        // Determine X location.
485
        if (getComponentOrientation().isLeftToRight())
486
          {
487
            // Prefer popup to the right.
488
            point.x = xOffset;
489
            // Check if it fits, otherwise place popup wherever it fits.
490
            if (screenLoc.x + point.x + popupSize.width
491
                > screenBounds.width + screenBounds.width
492
                && screenBounds.width - size.width
493
                   < 2 * (screenLoc.x - screenBounds.x))
494
              // Popup to the right if there's not enough room.
495
              point.x = size.width - xOffset - popupSize.width;
496
          }
497
        else
498
          {
499
            // Prefer popup to the left.
500
            point.x = size.width - xOffset - popupSize.width;
501
            if (screenLoc.x + point.x < screenBounds.x
502
                && screenBounds.width - size.width
503
                   > 2 * (screenLoc.x - screenBounds.x))
504
              // Popup to the left if there's not enough room.
505
              point.x = xOffset;
506
          }
507
        // Determine Y location. Prefer popping down.
508
        point.y = size.height + yOffset;
509
        if (screenLoc.y + point.y + popupSize.height >= screenBounds.height
510
            && screenBounds.height - size.height
511
               < 2 * (screenLoc.y - screenBounds.y))
512
          // Position above if there's not enough room below.
513
          point.y = - yOffset - popupSize.height;
514
      }
515
    else
516
      {
517
        // If submenu.
518
        int xOffset = UIManager.getInt("Menu.submenuPopupOffsetX");
519
        int yOffset = UIManager.getInt("Menu.submenuPopupOffsetY");
520
        // Determine X location.
521
        if (getComponentOrientation().isLeftToRight())
522
          {
523
            // Prefer popup to the right.
524
            point.x = size.width + xOffset;
525
            if (screenLoc.x + point.x + popupSize.width
526
                >= screenBounds.x + screenBounds.width
527
                && screenBounds.width - size.width
528
                   < 2 * (screenLoc.x - screenBounds.x))
529
              // Position to the left if there's not enough room on the right.
530
              point.x = - xOffset - popupSize.width;
531
          }
532
        else
533
          {
534
            // Prefer popup on the left side.
535
            point.x = - xOffset - popupSize.width;
536
            if (screenLoc.x + point.x < screenBounds.x
537
                && screenBounds.width - size.width
538
                > 2 * (screenLoc.x - screenBounds.x))
539
              // Popup to the right if there's not enough room.
540
              point.x = size.width + xOffset;
541
          }
542
        // Determine Y location. Prefer popping down.
543
        point.y = yOffset;
544
        if (screenLoc.y + point.y + popupSize.height
545
            >= screenBounds.y + screenBounds.height
546
            && screenBounds.height - size.height
547
            < 2 * (screenLoc.y - screenBounds.y))
548
          // Pop up if there's not enough room below.
549
          point.y = size.height - yOffset - popupSize.height;
550
      }
551
    return point;
552
  }
553
 
554
  /**
555
   * Returns delay property.
556
   *
557
   * @return delay property, indicating number of milliseconds before
558
   * popup menu associated with the menu appears or disappears after
559
   * menu was selected or deselected respectively
560
   */
561
  public int getDelay()
562
  {
563
    return delay;
564
  }
565
 
566
  /**
567
   * Sets delay property for this menu. If given time for the delay
568
   * property is negative, then IllegalArgumentException is thrown
569
   *
570
   * @param delay number of milliseconds before
571
   * popup menu associated with the menu appears or disappears after
572
   * menu was selected or deselected respectively
573
   */
574
  public void setDelay(int delay)
575
  {
576
    if (delay < 0)
577
      throw new IllegalArgumentException("delay less than 0");
578
    this.delay = delay;
579
  }
580
 
581
  /**
582
   * Sets location at which popup menu should be displayed
583
   * The location given is relative to this menu item
584
   *
585
   * @param x x-coordinate of the menu location
586
   * @param y y-coordinate of the menu location
587
   */
588
  public void setMenuLocation(int x, int y)
589
  {
590
    menuLocation = new Point(x, y);
591
    if (popupMenu != null)
592
      popupMenu.setLocation(x, y);
593
  }
594
 
595
  /**
596
   * Creates and returns JMenuItem associated with the given action
597
   *
598
   * @param action Action to use for creation of JMenuItem
599
   *
600
   * @return JMenuItem that was creted with given action
601
   */
602
  protected JMenuItem createActionComponent(Action action)
603
  {
604
    return new JMenuItem(action);
605
  }
606
 
607
  /**
608
   * Creates ActionChangeListener to listen for PropertyChangeEvents occuring
609
   * in the action that is associated with this menu
610
   *
611
   * @param item menu that contains action to listen to
612
   *
613
   * @return The PropertyChangeListener
614
   */
615
  protected PropertyChangeListener createActionChangeListener(JMenuItem item)
616
  {
617
    return new ActionChangedListener(item);
618
  }
619
 
620
  /**
621
   * Adds separator to the end of the menu items in the menu.
622
   */
623
  public void addSeparator()
624
  {
625
    getPopupMenu().addSeparator();
626
  }
627
 
628
  /**
629
   * Inserts separator in the menu at the specified index.
630
   *
631
   * @param index Index at which separator should be inserted
632
   */
633
  public void insertSeparator(int index)
634
  {
635
    if (index < 0)
636
      throw new IllegalArgumentException("index less than 0");
637
 
638
    getPopupMenu().insert(new JPopupMenu.Separator(), index);
639
  }
640
 
641
  /**
642
   * Returns menu item located at the specified index in the menu
643
   *
644
   * @param index Index at which to look for the menu item
645
   *
646
   * @return menu item located at the specified index in the menu
647
   */
648
  public JMenuItem getItem(int index)
649
  {
650
    if (index < 0)
651
      throw new IllegalArgumentException("index less than 0");
652
 
653
    if (getItemCount() == 0)
654
      return null;
655
 
656
    Component c = popupMenu.getComponentAtIndex(index);
657
 
658
    if (c instanceof JMenuItem)
659
      return (JMenuItem) c;
660
    else
661
      return null;
662
  }
663
 
664
  /**
665
   * Returns number of items in the menu including separators.
666
   *
667
   * @return number of items in the menu
668
   *
669
   * @see #getMenuComponentCount()
670
   */
671
  public int getItemCount()
672
  {
673
    return getMenuComponentCount();
674
  }
675
 
676
  /**
677
   * Checks if this menu is a tear-off menu.
678
   *
679
   * @return true if this menu is a tear-off menu and false otherwise
680
   */
681
  public boolean isTearOff()
682
  {
683
    // NOT YET IMPLEMENTED
684
    throw new Error("The method isTearOff() has not yet been implemented.");
685
  }
686
 
687
  /**
688
   * Returns number of menu components in this menu
689
   *
690
   * @return number of menu components in this menu
691
   */
692
  public int getMenuComponentCount()
693
  {
694
    return getPopupMenu().getComponentCount();
695
  }
696
 
697
  /**
698
   * Returns menu component located at the givent index
699
   * in the menu
700
   *
701
   * @param index index at which to get the menu component in the menu
702
   *
703
   * @return Menu Component located in the menu at the specified index
704
   */
705
  public Component getMenuComponent(int index)
706
  {
707
    if (getPopupMenu() == null || getMenuComponentCount() == 0)
708
      return null;
709
 
710
    return popupMenu.getComponentAtIndex(index);
711
  }
712
 
713
  /**
714
   * Return components belonging to this menu
715
   *
716
   * @return components belonging to this menu
717
   */
718
  public Component[] getMenuComponents()
719
  {
720
    return getPopupMenu().getComponents();
721
  }
722
 
723
  /**
724
   * Checks if this menu is a top level menu. The menu is top
725
   * level menu if it is inside the menu bar. While if the menu
726
   * inside some other menu, it is considered to be a pull-right menu.
727
   *
728
   * @return true if this menu is top level menu, and false otherwise
729
   */
730
  public boolean isTopLevelMenu()
731
  {
732
    return getParent() instanceof JMenuBar;
733
  }
734
 
735
  /**
736
   * Checks if given component exists in this menu. The submenus of
737
   * this menu are checked as well
738
   *
739
   * @param component Component to look for
740
   *
741
   * @return true if the given component exists in this menu, and false otherwise
742
   */
743
  public boolean isMenuComponent(Component component)
744
  {
745
    return false;
746
  }
747
 
748
  /**
749
   * Returns popup menu associated with the menu.
750
   *
751
   * @return popup menu associated with the menu.
752
   */
753
  public JPopupMenu getPopupMenu()
754
  {
755
    if (popupMenu == null)
756
      {
757
        popupMenu = new JPopupMenu();
758
        popupMenu.setInvoker(this);
759
      }
760
    return popupMenu;
761
  }
762
 
763
  /**
764
   * Adds MenuListener to the menu
765
   *
766
   * @param listener MenuListener to add
767
   */
768
  public void addMenuListener(MenuListener listener)
769
  {
770
    listenerList.add(MenuListener.class, listener);
771
  }
772
 
773
  /**
774
   * Removes MenuListener from the menu
775
   *
776
   * @param listener MenuListener to remove
777
   */
778
  public void removeMenuListener(MenuListener listener)
779
  {
780
    listenerList.remove(MenuListener.class, listener);
781
  }
782
 
783
  /**
784
   * Returns all registered <code>MenuListener</code> objects.
785
   *
786
   * @return an array of listeners
787
   *
788
   * @since 1.4
789
   */
790
  public MenuListener[] getMenuListeners()
791
  {
792
    return (MenuListener[]) listenerList.getListeners(MenuListener.class);
793
  }
794
 
795
  /**
796
   * This method fires MenuEvents to all menu's MenuListeners. In this case
797
   * menuSelected() method of MenuListeners is called to indicated that the menu
798
   * was selected.
799
   */
800
  protected void fireMenuSelected()
801
  {
802
    MenuListener[] listeners = getMenuListeners();
803
 
804
    for (int index = 0; index < listeners.length; ++index)
805
      listeners[index].menuSelected(menuEvent);
806
  }
807
 
808
  /**
809
   * This method fires MenuEvents to all menu's MenuListeners. In this case
810
   * menuDeselected() method of MenuListeners is called to indicated that the menu
811
   * was deselected.
812
   */
813
  protected void fireMenuDeselected()
814
  {
815
    EventListener[] ll = listenerList.getListeners(MenuListener.class);
816
 
817
    for (int i = 0; i < ll.length; i++)
818
      ((MenuListener) ll[i]).menuDeselected(menuEvent);
819
  }
820
 
821
  /**
822
   * This method fires MenuEvents to all menu's MenuListeners. In this case
823
   * menuSelected() method of MenuListeners is called to indicated that the menu
824
   * was cancelled. The menu is cancelled when it's popup menu is close without selection.
825
   */
826
  protected void fireMenuCanceled()
827
  {
828
    EventListener[] ll = listenerList.getListeners(MenuListener.class);
829
 
830
    for (int i = 0; i < ll.length; i++)
831
      ((MenuListener) ll[i]).menuCanceled(menuEvent);
832
  }
833
 
834
  /**
835
   * Creates WinListener that listens to the menu;s popup menu.
836
   *
837
   * @param popup JPopupMenu to listen to
838
   *
839
   * @return The WinListener
840
   */
841
  protected WinListener createWinListener(JPopupMenu popup)
842
  {
843
    return new WinListener(popup);
844
  }
845
 
846
  /**
847
   * Method of the MenuElementInterface. It reacts to the selection
848
   * changes in the menu. If this menu was selected, then it
849
   * displayes popup menu associated with it and if this menu was
850
   * deselected it hides the popup menu.
851
   *
852
   * @param changed true if the menu was selected and false otherwise
853
   */
854
  public void menuSelectionChanged(boolean changed)
855
  {
856
    // if this menu selection is true, then activate this menu and
857
    // display popup associated with this menu
858
    setSelected(changed);
859
  }
860
 
861
  /**
862
   * Method of MenuElement interface. Returns sub components of
863
   * this menu.
864
   *
865
   * @return array containing popupMenu that is associated with this menu
866
   */
867
  public MenuElement[] getSubElements()
868
  {
869
    return new MenuElement[] { popupMenu };
870
  }
871
 
872
  /**
873
   * @return Returns reference to itself
874
   */
875
  public Component getComponent()
876
  {
877
    return this;
878
  }
879
 
880
  /**
881
   * This method is overriden with empty implementation, s.t the
882
   * accelerator couldn't be set for the menu. The mnemonic should
883
   * be used for the menu instead.
884
   *
885
   * @param keystroke accelerator for this menu
886
   */
887
  public void setAccelerator(KeyStroke keystroke)
888
  {
889
    throw new Error("setAccelerator() is not defined for JMenu.  Use setMnemonic() instead.");
890
  }
891
 
892
  /**
893
   * This method process KeyEvent occuring when the menu is visible
894
   *
895
   * @param event The KeyEvent
896
   */
897
  protected void processKeyEvent(KeyEvent event)
898
  {
899
    MenuSelectionManager.defaultManager().processKeyEvent(event);
900
  }
901
 
902
  /**
903
   * Programatically performs click
904
   *
905
   * @param time Number of milliseconds for which this menu stays pressed
906
   */
907
  public void doClick(int time)
908
  {
909
    getModel().setArmed(true);
910
    getModel().setPressed(true);
911
    try
912
      {
913
        java.lang.Thread.sleep(time);
914
      }
915
    catch (java.lang.InterruptedException e)
916
      {
917
        // probably harmless
918
      }
919
 
920
    getModel().setPressed(false);
921
    getModel().setArmed(false);
922
    popupMenu.show(this, this.getWidth(), 0);
923
  }
924
 
925
  /**
926
   * A string that describes this JMenu. Normally only used
927
   * for debugging.
928
   *
929
   * @return A string describing this JMenu
930
   */
931
  protected String paramString()
932
  {
933
    return super.paramString();
934
  }
935
 
936
  public AccessibleContext getAccessibleContext()
937
  {
938
    if (accessibleContext == null)
939
      accessibleContext = new AccessibleJMenu();
940
 
941
    return accessibleContext;
942
  }
943
 
944
  /**
945
   * Implements support for assisitive technologies for <code>JMenu</code>.
946
   */
947
  protected class AccessibleJMenu extends AccessibleJMenuItem
948
    implements AccessibleSelection
949
  {
950
    private static final long serialVersionUID = -8131864021059524309L;
951
 
952
    protected AccessibleJMenu()
953
    {
954
      // Nothing to do here.
955
    }
956
 
957
    /**
958
     * Returns the number of accessible children of this object.
959
     *
960
     * @return the number of accessible children of this object
961
     */
962
    public int getAccessibleChildrenCount()
963
    {
964
      Component[] children = getMenuComponents();
965
      int count = 0;
966
      for (int i = 0; i < children.length; i++)
967
        {
968
          if (children[i] instanceof Accessible)
969
            count++;
970
        }
971
      return count;
972
    }
973
 
974
    /**
975
     * Returns the accessible child with the specified <code>index</code>.
976
     *
977
     * @param index the index of the child to fetch
978
     *
979
     * @return the accessible child with the specified <code>index</code>
980
     */
981
    public Accessible getAccessibleChild(int index)
982
    {
983
      Component[] children = getMenuComponents();
984
      int count = 0;
985
      Accessible found = null;
986
      for (int i = 0; i < children.length; i++)
987
        {
988
          if (children[i] instanceof Accessible)
989
            {
990
              if (count == index)
991
                {
992
                  found = (Accessible) children[i];
993
                  break;
994
                }
995
              count++;
996
            }
997
        }
998
      return found;
999
    }
1000
 
1001
    /**
1002
     * Returns the accessible selection of this object. AccessibleJMenus handle
1003
     * their selection themselves, so we always return <code>this</code> here.
1004
     *
1005
     * @return the accessible selection of this object
1006
     */
1007
    public AccessibleSelection getAccessibleSelection()
1008
    {
1009
      return this;
1010
    }
1011
 
1012
    /**
1013
     * Returns the selected accessible child with the specified
1014
     * <code>index</code>.
1015
     *
1016
     * @param index the index of the accessible selected child to return
1017
     *
1018
     * @return the selected accessible child with the specified
1019
     *         <code>index</code>
1020
     */
1021
    public Accessible getAccessibleSelection(int index)
1022
    {
1023
      Accessible selected = null;
1024
      // Only one item can be selected, which must therefore have index == 0.
1025
      if (index == 0)
1026
        {
1027
          MenuSelectionManager msm = MenuSelectionManager.defaultManager();
1028
          MenuElement[] me = msm.getSelectedPath();
1029
          if (me != null)
1030
            {
1031
              for (int i = 0; i < me.length; i++)
1032
                {
1033
                  if (me[i] == JMenu.this)
1034
                    {
1035
                      // This JMenu is selected, find and return the next
1036
                      // JMenuItem in the path.
1037
                      do
1038
                        {
1039
                          if (me[i] instanceof Accessible)
1040
                            {
1041
                              selected = (Accessible) me[i];
1042
                              break;
1043
                            }
1044
                          i++;
1045
                        } while (i < me.length);
1046
                    }
1047
                  if (selected != null)
1048
                    break;
1049
                }
1050
            }
1051
        }
1052
      return selected;
1053
    }
1054
 
1055
    /**
1056
     * Returns <code>true</code> if the accessible child with the specified
1057
     * index is selected, <code>false</code> otherwise.
1058
     *
1059
     * @param index the index of the accessible child to check
1060
     *
1061
     * @return <code>true</code> if the accessible child with the specified
1062
     *         index is selected, <code>false</code> otherwise
1063
     */
1064
    public boolean isAccessibleChildSelected(int index)
1065
    {
1066
      boolean selected = false;
1067
      MenuSelectionManager msm = MenuSelectionManager.defaultManager();
1068
      MenuElement[] me = msm.getSelectedPath();
1069
      if (me != null)
1070
        {
1071
          Accessible toBeFound = getAccessibleChild(index);
1072
          for (int i = 0; i < me.length; i++)
1073
            {
1074
              if (me[i] == toBeFound)
1075
                {
1076
                  selected = true;
1077
                  break;
1078
                }
1079
            }
1080
        }
1081
      return selected;
1082
    }
1083
 
1084
    /**
1085
     * Returns the accessible role of this object, which is
1086
     * {@link AccessibleRole#MENU} for the AccessibleJMenu.
1087
     *
1088
     * @return the accessible role of this object
1089
     */
1090
    public AccessibleRole getAccessibleRole()
1091
    {
1092
      return AccessibleRole.MENU;
1093
    }
1094
 
1095
    /**
1096
     * Returns the number of selected accessible children. This will be
1097
     * <code>0</code> if no item is selected, or <code>1</code> if an item
1098
     * is selected. AccessibleJMenu can have maximum 1 selected item.
1099
     *
1100
     * @return the number of selected accessible children
1101
     */
1102
    public int getAccessibleSelectionCount()
1103
    {
1104
      int count = 0;
1105
      MenuSelectionManager msm = MenuSelectionManager.defaultManager();
1106
      MenuElement[] me = msm.getSelectedPath();
1107
      if (me != null)
1108
        {
1109
          for (int i = 0; i < me.length; i++)
1110
            {
1111
              if (me[i] == JMenu.this)
1112
                {
1113
                  if (i + 1 < me.length)
1114
                    {
1115
                      count = 1;
1116
                      break;
1117
                    }
1118
                }
1119
            }
1120
        }
1121
      return count;
1122
    }
1123
 
1124
    /**
1125
     * Selects the accessible child with the specified index.
1126
     *
1127
     * @param index the index of the accessible child to select
1128
     */
1129
    public void addAccessibleSelection(int index)
1130
    {
1131
      Accessible child = getAccessibleChild(index);
1132
      if (child != null && child instanceof JMenuItem)
1133
        {
1134
          JMenuItem mi = (JMenuItem) child;
1135
          MenuSelectionManager msm = MenuSelectionManager.defaultManager();
1136
          msm.setSelectedPath(createPath(JMenu.this));
1137
        }
1138
    }
1139
 
1140
    /**
1141
     * Removes the item with the specified index from the selection.
1142
     *
1143
     * @param index the index of the selected item to remove from the selection
1144
     */
1145
    public void removeAccessibleSelection(int index)
1146
    {
1147
      Accessible child = getAccessibleChild(index);
1148
      if (child != null)
1149
        {
1150
          MenuSelectionManager msm = MenuSelectionManager.defaultManager();
1151
          MenuElement[] oldSelection = msm.getSelectedPath();
1152
          for (int i = 0; i < oldSelection.length; i++)
1153
            {
1154
              if (oldSelection[i] == child)
1155
                {
1156
                  // Found the specified child in the selection. Remove it
1157
                  // from the selection.
1158
                  MenuElement[] newSel = new MenuElement[i - 1];
1159
                  System.arraycopy(oldSelection, 0, newSel, 0, i - 1);
1160
                  msm.setSelectedPath(newSel);
1161
                  break;
1162
                }
1163
            }
1164
        }
1165
    }
1166
 
1167
    /**
1168
     * Removes all possibly selected accessible children of this object from
1169
     * the selection.
1170
     */
1171
    public void clearAccessibleSelection()
1172
    {
1173
      MenuSelectionManager msm = MenuSelectionManager.defaultManager();
1174
      MenuElement[] oldSelection = msm.getSelectedPath();
1175
      for (int i = 0; i < oldSelection.length; i++)
1176
        {
1177
          if (oldSelection[i] == JMenu.this)
1178
            {
1179
              // Found this menu in the selection. Remove all children from
1180
              // the selection.
1181
              MenuElement[] newSel = new MenuElement[i];
1182
              System.arraycopy(oldSelection, 0, newSel, 0, i);
1183
              msm.setSelectedPath(newSel);
1184
              break;
1185
            }
1186
        }
1187
    }
1188
 
1189
    /**
1190
     * AccessibleJMenu don't support multiple selection, so this method
1191
     * does nothing.
1192
     */
1193
    public void selectAllAccessibleSelection()
1194
    {
1195
      // Nothing to do here.
1196
    }
1197
  }
1198
 
1199
  protected class WinListener extends WindowAdapter implements Serializable
1200
  {
1201
    private static final long serialVersionUID = -6415815570638474823L;
1202
 
1203
    /**
1204
     * Creates a new <code>WinListener</code>.
1205
     *
1206
     * @param popup the popup menu which is observed
1207
     */
1208
    public WinListener(JPopupMenu popup)
1209
    {
1210
      // TODO: What should we do with the popup argument?
1211
    }
1212
 
1213
    /**
1214
     * Receives notification when the popup menu is closing and deselects
1215
     * the menu.
1216
     *
1217
     * @param event the window event
1218
     */
1219
    public void windowClosing(WindowEvent event)
1220
    {
1221
      setSelected(false);
1222
    }
1223
  }
1224
 
1225
  /**
1226
   * This class listens to PropertyChangeEvents occuring in menu's action
1227
   */
1228
  private class ActionChangedListener implements PropertyChangeListener
1229
  {
1230
    /** menu item associated with the action */
1231
    private JMenuItem menuItem;
1232
 
1233
    /** Creates new ActionChangedListener and adds it to menuItem's action */
1234
    public ActionChangedListener(JMenuItem menuItem)
1235
    {
1236
      this.menuItem = menuItem;
1237
 
1238
      Action a = menuItem.getAction();
1239
      if (a != null)
1240
        a.addPropertyChangeListener(this);
1241
    }
1242
 
1243
    /**This method is invoked when some change occures in menuItem's action*/
1244
    public void propertyChange(PropertyChangeEvent evt)
1245
    {
1246
      // FIXME: Need to implement
1247
    }
1248
  }
1249
 
1250
  /**
1251
   * Creates an array to be feeded as argument to
1252
   * {@link MenuSelectionManager#setSelectedPath(MenuElement[])} for the
1253
   * specified element. This has the effect of selecting the specified element
1254
   * and all its parents.
1255
   *
1256
   * @param leaf the leaf element for which to create the selected path
1257
   *
1258
   * @return the selected path array
1259
   */
1260
  MenuElement[] createPath(JMenu leaf)
1261
  {
1262
    ArrayList path = new ArrayList();
1263
    MenuElement[] array = null;
1264
    Component current = leaf.getPopupMenu();
1265
    while (true)
1266
      {
1267
        if (current instanceof JPopupMenu)
1268
          {
1269
            JPopupMenu popupMenu = (JPopupMenu) current;
1270
            path.add(0, popupMenu);
1271
            current = popupMenu.getInvoker();
1272
          }
1273
        else if (current instanceof JMenu)
1274
          {
1275
            JMenu menu = (JMenu) current;
1276
            path.add(0, menu);
1277
            current = menu.getParent();
1278
          }
1279
        else if (current instanceof JMenuBar)
1280
          {
1281
            JMenuBar menuBar = (JMenuBar) current;
1282
            path.add(0, menuBar);
1283
            array = new MenuElement[path.size()];
1284
            array = (MenuElement[]) path.toArray(array);
1285
            break;
1286
          }
1287
      }
1288
    return array;
1289
  }
1290
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.