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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [javax/] [swing/] [plaf/] [basic/] [BasicMenuItemUI.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* BasicMenuItemUI.java --
2
   Copyright (C) 2002, 2004, 2005  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.plaf.basic;
40
 
41
import java.awt.Color;
42
import java.awt.Component;
43
import java.awt.Dimension;
44
import java.awt.Font;
45
import java.awt.FontMetrics;
46
import java.awt.Graphics;
47
import java.awt.Insets;
48
import java.awt.Rectangle;
49
import java.awt.event.ActionEvent;
50
import java.awt.event.ItemEvent;
51
import java.awt.event.ItemListener;
52
import java.awt.event.KeyEvent;
53
import java.awt.event.MouseEvent;
54
import java.beans.PropertyChangeEvent;
55
import java.beans.PropertyChangeListener;
56
import java.util.ArrayList;
57
 
58
import javax.swing.AbstractAction;
59
import javax.swing.ActionMap;
60
import javax.swing.ButtonModel;
61
import javax.swing.Icon;
62
import javax.swing.InputMap;
63
import javax.swing.JCheckBoxMenuItem;
64
import javax.swing.JComponent;
65
import javax.swing.JMenu;
66
import javax.swing.JMenuItem;
67
import javax.swing.JPopupMenu;
68
import javax.swing.KeyStroke;
69
import javax.swing.LookAndFeel;
70
import javax.swing.MenuElement;
71
import javax.swing.MenuSelectionManager;
72
import javax.swing.SwingConstants;
73
import javax.swing.SwingUtilities;
74
import javax.swing.UIDefaults;
75
import javax.swing.UIManager;
76
import javax.swing.event.MenuDragMouseEvent;
77
import javax.swing.event.MenuDragMouseListener;
78
import javax.swing.event.MenuKeyEvent;
79
import javax.swing.event.MenuKeyListener;
80
import javax.swing.event.MouseInputListener;
81
import javax.swing.plaf.ActionMapUIResource;
82
import javax.swing.plaf.ComponentInputMapUIResource;
83
import javax.swing.plaf.ComponentUI;
84
import javax.swing.plaf.MenuItemUI;
85
 
86
/**
87
 * UI Delegate for JMenuItem.
88
 */
89
public class BasicMenuItemUI extends MenuItemUI
90
{
91
  /**
92
   * Font to be used when displaying menu item's accelerator.
93
   */
94
  protected Font acceleratorFont;
95
 
96
  /**
97
   * Color to be used when displaying menu item's accelerator.
98
   */
99
  protected Color acceleratorForeground;
100
 
101
  /**
102
   * Color to be used when displaying menu item's accelerator when menu item is
103
   * selected.
104
   */
105
  protected Color acceleratorSelectionForeground;
106
 
107
  /**
108
   * Icon that is displayed after the text to indicated that this menu contains
109
   * submenu.
110
   */
111
  protected Icon arrowIcon;
112
 
113
  /**
114
   * Icon that is displayed before the text. This icon is only used in
115
   * JCheckBoxMenuItem or JRadioBoxMenuItem.
116
   */
117
  protected Icon checkIcon;
118
 
119
  /**
120
   * Number of spaces between icon and text.
121
   */
122
  protected int defaultTextIconGap = 4;
123
 
124
  /**
125
   * Color of the text when menu item is disabled
126
   */
127
  protected Color disabledForeground;
128
 
129
  /**
130
   * The menu Drag mouse listener listening to the menu item.
131
   */
132
  protected MenuDragMouseListener menuDragMouseListener;
133
 
134
  /**
135
   * The menu item itself
136
   */
137
  protected JMenuItem menuItem;
138
 
139
  /**
140
   * Menu Key listener listening to the menu item.
141
   */
142
  protected MenuKeyListener menuKeyListener;
143
 
144
  /**
145
   * mouse input listener listening to menu item.
146
   */
147
  protected MouseInputListener mouseInputListener;
148
 
149
  /**
150
   * Indicates if border should be painted
151
   */
152
  protected boolean oldBorderPainted;
153
 
154
  /**
155
   * Color of text that is used when menu item is selected
156
   */
157
  protected Color selectionBackground;
158
 
159
  /**
160
   * Color of the text that is used when menu item is selected.
161
   */
162
  protected Color selectionForeground;
163
 
164
  /**
165
   * String that separates description of the modifiers and the key
166
   */
167
  private String acceleratorDelimiter;
168
 
169
  /**
170
   * ItemListener to listen for item changes in the menu item
171
   */
172
  private ItemListener itemListener;
173
 
174
  /**
175
   * Number of spaces between accelerator and menu item's label.
176
   */
177
  private int defaultAcceleratorLabelGap = 10;
178
 
179
  /**
180
   * The gap between different menus on the MenuBar.
181
   */
182
  private int MenuGap = 10;
183
 
184
  /** A PropertyChangeListener to make UI updates after property changes **/
185
  PropertyChangeHandler propertyChangeListener;
186
 
187
  /**
188
   * A class to handle PropertChangeEvents for the JMenuItem
189
   * @author Anthony Balkissoon abalkiss at redhat dot com.
190
   */
191
  class PropertyChangeHandler implements PropertyChangeListener
192
  {
193
    /**
194
     * This method is called when a property of the menuItem is changed.
195
     * Currently it is only used to update the accelerator key bindings.
196
     *
197
     * @param e
198
     *          the PropertyChangeEvent
199
     */
200
    public void propertyChange(PropertyChangeEvent e)
201
    {
202
      if (e.getPropertyName() == "accelerator")
203
        {
204
          InputMap map = SwingUtilities.getUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW);
205
          if (map != null)
206
            map.remove((KeyStroke)e.getOldValue());
207
          else
208
            map = new ComponentInputMapUIResource(menuItem);
209
          map.put((KeyStroke)e.getNewValue(), "doClick");
210
        }
211
    }
212
  }
213
 
214
  /**
215
   * A class to handle accelerator keys.  This is the Action we will
216
   * perform when the accelerator key for this JMenuItem is pressed.
217
   * @author Anthony Balkissoon abalkiss at redhat dot com
218
   *
219
   */
220
  class ClickAction extends AbstractAction
221
  {
222
    /**
223
     * This is what is done when the accelerator key for the JMenuItem is
224
     * pressed.
225
     */
226
    public void actionPerformed(ActionEvent event)
227
    {
228
      doClick(MenuSelectionManager.defaultManager());
229
    }
230
  }
231
 
232
  /**
233
   * Creates a new BasicMenuItemUI object.
234
   */
235
  public BasicMenuItemUI()
236
  {
237
    mouseInputListener = createMouseInputListener(menuItem);
238
    menuDragMouseListener = createMenuDragMouseListener(menuItem);
239
    menuKeyListener = createMenuKeyListener(menuItem);
240
    itemListener = new ItemHandler();
241
    propertyChangeListener = new PropertyChangeHandler();
242
  }
243
 
244
  /**
245
   * Create MenuDragMouseListener to listen for mouse dragged events.
246
   *
247
   * @param c
248
   *          menu item to listen to
249
   * @return The MenuDragMouseListener
250
   */
251
  protected MenuDragMouseListener createMenuDragMouseListener(JComponent c)
252
  {
253
    return new MenuDragMouseHandler();
254
  }
255
 
256
  /**
257
   * Creates MenuKeyListener to listen to key events occuring when menu item is
258
   * visible on the screen.
259
   *
260
   * @param c
261
   *          menu item to listen to
262
   * @return The MenuKeyListener
263
   */
264
  protected MenuKeyListener createMenuKeyListener(JComponent c)
265
  {
266
    return new MenuKeyHandler();
267
  }
268
 
269
  /**
270
   * Handles mouse input events occuring for this menu item
271
   *
272
   * @param c
273
   *          menu item to listen to
274
   * @return The MouseInputListener
275
   */
276
  protected MouseInputListener createMouseInputListener(JComponent c)
277
  {
278
    return new MouseInputHandler();
279
  }
280
 
281
  /**
282
   * Factory method to create a BasicMenuItemUI for the given {@link
283
   * JComponent}, which should be a {@link JMenuItem}.
284
   *
285
   * @param c
286
   *          The {@link JComponent} a UI is being created for.
287
   * @return A BasicMenuItemUI for the {@link JComponent}.
288
   */
289
  public static ComponentUI createUI(JComponent c)
290
  {
291
    return new BasicMenuItemUI();
292
  }
293
 
294
  /**
295
   * Programatically clicks menu item.
296
   *
297
   * @param msm
298
   *          MenuSelectionManager for the menu hierarchy
299
   */
300
  protected void doClick(MenuSelectionManager msm)
301
  {
302
    menuItem.doClick();
303
    msm.clearSelectedPath();
304
  }
305
 
306
  /**
307
   * Returns maximum size for the specified menu item
308
   *
309
   * @param c
310
   *          component for which to get maximum size
311
   * @return Maximum size for the specified menu item.
312
   */
313
  public Dimension getMaximumSize(JComponent c)
314
  {
315
    return null;
316
  }
317
 
318
  /**
319
   * Returns minimum size for the specified menu item
320
   *
321
   * @param c
322
   *          component for which to get minimum size
323
   * @return Minimum size for the specified menu item.
324
   */
325
  public Dimension getMinimumSize(JComponent c)
326
  {
327
    return null;
328
  }
329
 
330
  /**
331
   * Returns path to this menu item.
332
   *
333
   * @return $MenuElement[]$ Returns array of menu elements that constitute a
334
   *         path to this menu item.
335
   */
336
  public MenuElement[] getPath()
337
  {
338
    ArrayList path = new ArrayList();
339
 
340
    // Path to menu should also include its popup menu.
341
    if (menuItem instanceof JMenu)
342
      path.add(((JMenu) menuItem).getPopupMenu());
343
 
344
    Component c = menuItem;
345
    while (c instanceof MenuElement)
346
      {
347
        path.add(0, (MenuElement) c);
348
 
349
        if (c instanceof JPopupMenu)
350
          c = ((JPopupMenu) c).getInvoker();
351
        else
352
          c = c.getParent();
353
      }
354
 
355
    MenuElement[] pathArray = new MenuElement[path.size()];
356
    path.toArray(pathArray);
357
    return pathArray;
358
  }
359
 
360
  /**
361
   * Returns preferred size for the given menu item.
362
   *
363
   * @param c
364
   *          menu item for which to get preferred size
365
   * @param checkIcon
366
   *          check icon displayed in the given menu item
367
   * @param arrowIcon
368
   *          arrow icon displayed in the given menu item
369
   * @param defaultTextIconGap
370
   *          space between icon and text in the given menuItem
371
   * @return $Dimension$ preferred size for the given menu item
372
   */
373
  protected Dimension getPreferredMenuItemSize(JComponent c, Icon checkIcon,
374
                                               Icon arrowIcon,
375
                                               int defaultTextIconGap)
376
  {
377
    JMenuItem m = (JMenuItem) c;
378
    Dimension d = BasicGraphicsUtils.getPreferredButtonSize(m,
379
                                                            defaultTextIconGap);
380
 
381
    // if menu item has accelerator then take accelerator's size into account
382
    // when calculating preferred size.
383
    KeyStroke accelerator = m.getAccelerator();
384
    Rectangle rect;
385
 
386
    if (accelerator != null)
387
      {
388
        rect = getAcceleratorRect(
389
                                  accelerator,
390
                                  m.getToolkit().getFontMetrics(acceleratorFont));
391
 
392
        // add width of accelerator's text
393
        d.width += rect.width + defaultAcceleratorLabelGap;
394
 
395
        // adjust the heigth of the preferred size if necessary
396
        if (d.height < rect.height)
397
          d.height = rect.height;
398
      }
399
 
400
    if (checkIcon != null)
401
      {
402
        d.width += checkIcon.getIconWidth() + defaultTextIconGap;
403
 
404
        if (checkIcon.getIconHeight() > d.height)
405
          d.height = checkIcon.getIconHeight();
406
      }
407
 
408
    if (arrowIcon != null && (c instanceof JMenu))
409
      {
410
        int pWidth = m.getParent().getWidth();
411
        if (!((JMenu)c).isTopLevelMenu() && d.width < pWidth)
412
          d.width = pWidth
413
          - m.getInsets().left - m.getInsets().right;
414
        else
415
          d.width += arrowIcon.getIconWidth() + MenuGap;
416
 
417
        if (arrowIcon.getIconHeight() > d.height)
418
          d.height = arrowIcon.getIconHeight();
419
      }
420
 
421
    return d;
422
  }
423
 
424
  /**
425
   * Returns preferred size of the given component
426
   *
427
   * @param c
428
   *          component for which to return preferred size
429
   * @return $Dimension$ preferred size for the given component
430
   */
431
  public Dimension getPreferredSize(JComponent c)
432
  {
433
    return getPreferredMenuItemSize(c, checkIcon, arrowIcon, defaultTextIconGap);
434
  }
435
 
436
  /**
437
   * Returns the prefix for entries in the {@link UIDefaults} table.
438
   *
439
   * @return "MenuItem"
440
   */
441
  protected String getPropertyPrefix()
442
  {
443
    return "MenuItem";
444
  }
445
 
446
  /**
447
   * This method installs the components for this {@link JMenuItem}.
448
   *
449
   * @param menuItem
450
   *          The {@link JMenuItem} to install components for.
451
   */
452
  protected void installComponents(JMenuItem menuItem)
453
  {
454
    // FIXME: Need to implement
455
  }
456
 
457
  /**
458
   * This method installs the defaults that are defined in the Basic look and
459
   * feel for this {@link JMenuItem}.
460
   */
461
  protected void installDefaults()
462
  {
463
    String prefix = getPropertyPrefix();
464
    LookAndFeel.installBorder(menuItem, prefix + ".border");
465
    LookAndFeel.installColorsAndFont(menuItem, prefix + ".background",
466
                                     prefix + ".foreground", prefix + ".font");
467
    menuItem.setMargin(UIManager.getInsets(prefix + ".margin"));
468
    acceleratorFont = UIManager.getFont(prefix + ".acceleratorFont");
469
    acceleratorForeground = UIManager.getColor(prefix + ".acceleratorForeground");
470
    acceleratorSelectionForeground = UIManager.getColor(prefix + ".acceleratorSelectionForeground");
471
    selectionBackground = UIManager.getColor(prefix + ".selectionBackground");
472
    selectionForeground = UIManager.getColor(prefix + ".selectionForeground");
473
    acceleratorDelimiter = UIManager.getString(prefix + ".acceleratorDelimiter");
474
    checkIcon = UIManager.getIcon(prefix + ".checkIcon");
475
 
476
    menuItem.setHorizontalTextPosition(SwingConstants.TRAILING);
477
    menuItem.setHorizontalAlignment(SwingConstants.LEADING);
478
  }
479
 
480
  /**
481
   * This method installs the keyboard actions for this {@link JMenuItem}.
482
   */
483
  protected void installKeyboardActions()
484
  {
485
    InputMap focusedWindowMap = SwingUtilities.getUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW);
486
    if (focusedWindowMap == null)
487
      focusedWindowMap = new ComponentInputMapUIResource(menuItem);
488
    focusedWindowMap.put(menuItem.getAccelerator(), "doClick");
489
    SwingUtilities.replaceUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW, focusedWindowMap);
490
 
491
    ActionMap UIActionMap = SwingUtilities.getUIActionMap(menuItem);
492
    if (UIActionMap == null)
493
      UIActionMap = new ActionMapUIResource();
494
    UIActionMap.put("doClick", new ClickAction());
495
    SwingUtilities.replaceUIActionMap(menuItem, UIActionMap);
496
  }
497
 
498
  /**
499
   * This method installs the listeners for the {@link JMenuItem}.
500
   */
501
  protected void installListeners()
502
  {
503
    menuItem.addMouseListener(mouseInputListener);
504
    menuItem.addMouseMotionListener(mouseInputListener);
505
    menuItem.addMenuDragMouseListener(menuDragMouseListener);
506
    menuItem.addMenuKeyListener(menuKeyListener);
507
    menuItem.addItemListener(itemListener);
508
    menuItem.addPropertyChangeListener(propertyChangeListener);
509
  }
510
 
511
  /**
512
   * Installs and initializes all fields for this UI delegate. Any properties of
513
   * the UI that need to be initialized and/or set to defaults will be done now.
514
   * It will also install any listeners necessary.
515
   *
516
   * @param c
517
   *          The {@link JComponent} that is having this UI installed.
518
   */
519
  public void installUI(JComponent c)
520
  {
521
    super.installUI(c);
522
    menuItem = (JMenuItem) c;
523
    installDefaults();
524
    installComponents(menuItem);
525
    installListeners();
526
    installKeyboardActions();
527
  }
528
 
529
  /**
530
   * Paints given menu item using specified graphics context
531
   *
532
   * @param g
533
   *          The graphics context used to paint this menu item
534
   * @param c
535
   *          Menu Item to paint
536
   */
537
  public void paint(Graphics g, JComponent c)
538
  {
539
    paintMenuItem(g, c, checkIcon, arrowIcon, c.getBackground(),
540
                  c.getForeground(), defaultTextIconGap);
541
  }
542
 
543
  /**
544
   * Paints background of the menu item
545
   *
546
   * @param g
547
   *          The graphics context used to paint this menu item
548
   * @param menuItem
549
   *          menu item to paint
550
   * @param bgColor
551
   *          Background color to use when painting menu item
552
   */
553
  protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor)
554
  {
555
    // Menu item is considered to be highlighted when it is selected.
556
    // But we don't want to paint the background of JCheckBoxMenuItems
557
    ButtonModel mod = menuItem.getModel();
558
    if ((menuItem.isSelected() && checkIcon == null) || (mod != null &&
559
        mod.isArmed())
560
        && (menuItem.getParent() instanceof MenuElement))
561
      {
562
        if (menuItem.isContentAreaFilled())
563
          {
564
            g.setColor(selectionBackground);
565
            g.fillRect(0, 0, menuItem.getWidth(), menuItem.getHeight());
566
          }
567
      }
568
 
569
  }
570
 
571
  /**
572
   * Paints specified menu item
573
   *
574
   * @param g
575
   *          The graphics context used to paint this menu item
576
   * @param c
577
   *          menu item to paint
578
   * @param checkIcon
579
   *          check icon to use when painting menu item
580
   * @param arrowIcon
581
   *          arrow icon to use when painting menu item
582
   * @param background
583
   *          Background color of the menu item
584
   * @param foreground
585
   *          Foreground color of the menu item
586
   * @param defaultTextIconGap
587
   *          space to use between icon and text when painting menu item
588
   */
589
  protected void paintMenuItem(Graphics g, JComponent c, Icon checkIcon,
590
                               Icon arrowIcon, Color background,
591
                               Color foreground, int defaultTextIconGap)
592
  {
593
    JMenuItem m = (JMenuItem) c;
594
    Rectangle tr = new Rectangle(); // text rectangle
595
    Rectangle ir = new Rectangle(); // icon rectangle
596
    Rectangle vr = new Rectangle(); // view rectangle
597
    Rectangle br = new Rectangle(); // border rectangle
598
    Rectangle ar = new Rectangle(); // accelerator rectangle
599
    Rectangle cr = new Rectangle(); // checkIcon rectangle
600
 
601
    int vertAlign = m.getVerticalAlignment();
602
    int horAlign = m.getHorizontalAlignment();
603
    int vertTextPos = m.getVerticalTextPosition();
604
    int horTextPos = m.getHorizontalTextPosition();
605
 
606
    Font f = m.getFont();
607
    g.setFont(f);
608
    FontMetrics fm = g.getFontMetrics(f);
609
    SwingUtilities.calculateInnerArea(m, br);
610
    SwingUtilities.calculateInsetArea(br, m.getInsets(), vr);
611
    paintBackground(g, m, m.getBackground());
612
 
613
    /*
614
     * MenuItems insets are equal to menuItems margin, space between text and
615
     * menuItems border. We need to paint insets region as well.
616
     */
617
    Insets insets = m.getInsets();
618
    br.x -= insets.left;
619
    br.y -= insets.top;
620
    br.width += insets.right + insets.left;
621
    br.height += insets.top + insets.bottom;
622
 
623
    // If this menu item is a JCheckBoxMenuItem then paint check icon
624
    if (checkIcon != null)
625
      {
626
        SwingUtilities.layoutCompoundLabel(m, fm, null, checkIcon, vertAlign,
627
                                           horAlign, vertTextPos, horTextPos,
628
                                           vr, cr, tr, defaultTextIconGap);
629
        checkIcon.paintIcon(m, g, cr.x, cr.y);
630
        // We need to calculate position of the menu text and position of
631
        // user menu icon if there exists one relative to the check icon.
632
        // So we need to adjust view rectangle s.t. its starting point is at
633
        // checkIcon.width + defaultTextIconGap.
634
        vr.x = cr.x + cr.width + defaultTextIconGap;
635
      }
636
 
637
    // if this is a submenu, then paint arrow icon to indicate it.
638
    if (arrowIcon != null && (c instanceof JMenu))
639
      {
640
        if (!((JMenu) c).isTopLevelMenu())
641
          {
642
            int width = arrowIcon.getIconWidth();
643
            int height = arrowIcon.getIconHeight();
644
            int offset = (vr.height - height) / 2;
645
            arrowIcon.paintIcon(m, g, vr.width - width, vr.y + offset);
646
          }
647
      }
648
 
649
    // paint text and user menu icon if it exists
650
    Icon i = m.getIcon();
651
    SwingUtilities.layoutCompoundLabel(c, fm, m.getText(), i, vertAlign,
652
                                       horAlign, vertTextPos, horTextPos, vr,
653
                                       ir, tr, defaultTextIconGap);
654
    if (i != null)
655
      i.paintIcon(c, g, ir.x, ir.y);
656
    paintText(g, m, tr, m.getText());
657
 
658
    // paint accelerator
659
    String acceleratorText = "";
660
 
661
    if (m.getAccelerator() != null)
662
      {
663
        acceleratorText = getAcceleratorText(m.getAccelerator());
664
        fm = g.getFontMetrics(acceleratorFont);
665
        ar.width = fm.stringWidth(acceleratorText);
666
        ar.x = br.width - ar.width;
667
        vr.x = br.width - ar.width - defaultTextIconGap;
668
 
669
        SwingUtilities.layoutCompoundLabel(m, fm, acceleratorText, null,
670
                                           vertAlign, horAlign, vertTextPos,
671
                                           horTextPos, vr, ir, ar,
672
                                           defaultTextIconGap);
673
 
674
        paintAccelerator(g, m, ar, acceleratorText);
675
      }
676
  }
677
 
678
  /**
679
   * Paints label for the given menu item
680
   *
681
   * @param g
682
   *          The graphics context used to paint this menu item
683
   * @param menuItem
684
   *          menu item for which to draw its label
685
   * @param textRect
686
   *          rectangle specifiying position of the text relative to the given
687
   *          menu item
688
   * @param text
689
   *          label of the menu item
690
   */
691
  protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect,
692
                           String text)
693
  {
694
    Font f = menuItem.getFont();
695
    g.setFont(f);
696
    FontMetrics fm = g.getFontMetrics(f);
697
 
698
    if (text != null && !text.equals(""))
699
      {
700
        if (menuItem.isEnabled())
701
          {
702
            // Menu item is considered to be highlighted when it is selected.
703
            // But not if it's a JCheckBoxMenuItem
704
            ButtonModel mod = menuItem.getModel();
705
            if ((menuItem.isSelected() && checkIcon == null)
706
                || (mod != null && mod.isArmed())
707
                && (menuItem.getParent() instanceof MenuElement))
708
              g.setColor(selectionForeground);
709
            else
710
              g.setColor(menuItem.getForeground());
711
          }
712
        else
713
          // FIXME: should fix this to use 'disabledForeground', but its
714
          // default value in BasicLookAndFeel is null.
715
 
716
          // FIXME: should there be different foreground colours for selected
717
          // or deselected, when disabled?
718
          g.setColor(Color.gray);
719
 
720
        int mnemonicIndex = menuItem.getDisplayedMnemonicIndex();
721
 
722
        if (mnemonicIndex != -1)
723
          BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, mnemonicIndex,
724
                                                       textRect.x,
725
                                                       textRect.y
726
                                                           + fm.getAscent());
727
        else
728
          BasicGraphicsUtils.drawString(g, text, 0, textRect.x,
729
                                        textRect.y + fm.getAscent());
730
      }
731
  }
732
 
733
  /**
734
   * This method uninstalls the components for this {@link JMenuItem}.
735
   *
736
   * @param menuItem
737
   *          The {@link JMenuItem} to uninstall components for.
738
   */
739
  protected void uninstallComponents(JMenuItem menuItem)
740
  {
741
    // FIXME: need to implement
742
  }
743
 
744
  /**
745
   * This method uninstalls the defaults and sets any objects created during
746
   * install to null
747
   */
748
  protected void uninstallDefaults()
749
  {
750
    menuItem.setForeground(null);
751
    menuItem.setBackground(null);
752
    menuItem.setBorder(null);
753
    menuItem.setMargin(null);
754
    menuItem.setBackground(null);
755
    menuItem.setBorder(null);
756
    menuItem.setFont(null);
757
    menuItem.setForeground(null);
758
    menuItem.setMargin(null);
759
    acceleratorFont = null;
760
    acceleratorForeground = null;
761
    acceleratorSelectionForeground = null;
762
    arrowIcon = null;
763
    selectionBackground = null;
764
    selectionForeground = null;
765
    acceleratorDelimiter = null;
766
  }
767
 
768
  /**
769
   * Uninstalls any keyboard actions.
770
   */
771
  protected void uninstallKeyboardActions()
772
  {
773
    SwingUtilities.replaceUIInputMap(menuItem,
774
                                     JComponent.WHEN_IN_FOCUSED_WINDOW, null);
775
  }
776
 
777
  /**
778
   * Unregisters all the listeners that this UI delegate was using.
779
   */
780
  protected void uninstallListeners()
781
  {
782
    menuItem.removeMouseListener(mouseInputListener);
783
    menuItem.removeMenuDragMouseListener(menuDragMouseListener);
784
    menuItem.removeMenuKeyListener(menuKeyListener);
785
    menuItem.removeItemListener(itemListener);
786
    menuItem.removePropertyChangeListener(propertyChangeListener);
787
  }
788
 
789
  /**
790
   * Performs the opposite of installUI. Any properties or resources that need
791
   * to be cleaned up will be done now. It will also uninstall any listeners it
792
   * has. In addition, any properties of this UI will be nulled.
793
   *
794
   * @param c
795
   *          The {@link JComponent} that is having this UI uninstalled.
796
   */
797
  public void uninstallUI(JComponent c)
798
  {
799
    uninstallListeners();
800
    uninstallDefaults();
801
    uninstallComponents(menuItem);
802
    menuItem = null;
803
  }
804
 
805
  /**
806
   * This method calls paint.
807
   *
808
   * @param g
809
   *          The graphics context used to paint this menu item
810
   * @param c
811
   *          The menu item to paint
812
   */
813
  public void update(Graphics g, JComponent c)
814
  {
815
    paint(g, c);
816
  }
817
 
818
  /**
819
   * Return text representation of the specified accelerator
820
   *
821
   * @param accelerator
822
   *          Accelerator for which to return string representation
823
   * @return $String$ Text representation of the given accelerator
824
   */
825
  private String getAcceleratorText(KeyStroke accelerator)
826
  {
827
    // convert keystroke into string format
828
    String modifiersText = "";
829
    int modifiers = accelerator.getModifiers();
830
    char keyChar = accelerator.getKeyChar();
831
    int keyCode = accelerator.getKeyCode();
832
 
833
    if (modifiers != 0)
834
      modifiersText = KeyEvent.getKeyModifiersText(modifiers)
835
                      + acceleratorDelimiter;
836
 
837
    if (keyCode == KeyEvent.VK_UNDEFINED)
838
      return modifiersText + keyChar;
839
    else
840
      return modifiersText + KeyEvent.getKeyText(keyCode);
841
  }
842
 
843
  /**
844
   * Calculates and return rectange in which accelerator should be displayed
845
   *
846
   * @param accelerator
847
   *          accelerator for which to return the display rectangle
848
   * @param fm
849
   *          The font metrics used to measure the text
850
   * @return $Rectangle$ reactangle which will be used to display accelerator
851
   */
852
  private Rectangle getAcceleratorRect(KeyStroke accelerator, FontMetrics fm)
853
  {
854
    int width = fm.stringWidth(getAcceleratorText(accelerator));
855
    int height = fm.getHeight();
856
    return new Rectangle(0, 0, width, height);
857
  }
858
 
859
  /**
860
   * Paints accelerator inside menu item
861
   *
862
   * @param g
863
   *          The graphics context used to paint the border
864
   * @param menuItem
865
   *          Menu item for which to draw accelerator
866
   * @param acceleratorRect
867
   *          rectangle representing position of the accelerator relative to the
868
   *          menu item
869
   * @param acceleratorText
870
   *          accelerator's text
871
   */
872
  private void paintAccelerator(Graphics g, JMenuItem menuItem,
873
                                Rectangle acceleratorRect,
874
                                String acceleratorText)
875
  {
876
    g.setFont(acceleratorFont);
877
    FontMetrics fm = g.getFontMetrics(acceleratorFont);
878
 
879
    if (menuItem.isEnabled())
880
      g.setColor(acceleratorForeground);
881
    else
882
      // FIXME: should fix this to use 'disabledForeground', but its
883
      // default value in BasicLookAndFeel is null.
884
      g.setColor(Color.gray);
885
 
886
    BasicGraphicsUtils.drawString(g, acceleratorText, 0, acceleratorRect.x,
887
                                  acceleratorRect.y + fm.getAscent());
888
  }
889
 
890
  /**
891
   * This class handles mouse events occuring inside the menu item. Most of the
892
   * events are forwarded for processing to MenuSelectionManager of the current
893
   * menu hierarchy.
894
   */
895
  protected class MouseInputHandler implements MouseInputListener
896
  {
897
    /**
898
     * Creates a new MouseInputHandler object.
899
     */
900
    protected MouseInputHandler()
901
    {
902
      // Nothing to do here.
903
    }
904
 
905
    /**
906
     * This method is called when mouse is clicked on the menu item. It forwards
907
     * this event to MenuSelectionManager.
908
     *
909
     * @param e
910
     *          A {@link MouseEvent}.
911
     */
912
    public void mouseClicked(MouseEvent e)
913
    {
914
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
915
      manager.processMouseEvent(e);
916
    }
917
 
918
    /**
919
     * This method is called when mouse is dragged inside the menu item. It
920
     * forwards this event to MenuSelectionManager.
921
     *
922
     * @param e
923
     *          A {@link MouseEvent}.
924
     */
925
    public void mouseDragged(MouseEvent e)
926
    {
927
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
928
      manager.processMouseEvent(e);
929
    }
930
 
931
    /**
932
     * This method is called when mouse enters menu item. When this happens menu
933
     * item is considered to be selected and selection path in
934
     * MenuSelectionManager is set. This event is also forwarded to
935
     * MenuSelection Manager for further processing.
936
     *
937
     * @param e
938
     *          A {@link MouseEvent}.
939
     */
940
    public void mouseEntered(MouseEvent e)
941
    {
942
      Component source = (Component) e.getSource();
943
      if (source.getParent() instanceof MenuElement)
944
        {
945
          MenuSelectionManager manager = MenuSelectionManager.defaultManager();
946
          manager.setSelectedPath(getPath());
947
          manager.processMouseEvent(e);
948
        }
949
    }
950
 
951
    /**
952
     * This method is called when mouse exits menu item. The event is forwarded
953
     * to MenuSelectionManager for processing.
954
     *
955
     * @param e
956
     *          A {@link MouseEvent}.
957
     */
958
    public void mouseExited(MouseEvent e)
959
    {
960
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
961
      manager.processMouseEvent(e);
962
    }
963
 
964
    /**
965
     * This method is called when mouse is inside the menu item. This event is
966
     * forwarder to MenuSelectionManager for further processing.
967
     *
968
     * @param e
969
     *          A {@link MouseEvent}.
970
     */
971
    public void mouseMoved(MouseEvent e)
972
    {
973
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
974
      manager.processMouseEvent(e);
975
    }
976
 
977
    /**
978
     * This method is called when mouse is pressed. This event is forwarded to
979
     * MenuSelectionManager for further processing.
980
     *
981
     * @param e
982
     *          A {@link MouseEvent}.
983
     */
984
    public void mousePressed(MouseEvent e)
985
    {
986
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
987
      manager.processMouseEvent(e);
988
    }
989
 
990
    /**
991
     * This method is called when mouse is released. If the mouse is released
992
     * inside this menuItem, then this menu item is considered to be chosen and
993
     * the menu hierarchy should be closed.
994
     *
995
     * @param e
996
     *          A {@link MouseEvent}.
997
     */
998
    public void mouseReleased(MouseEvent e)
999
    {
1000
      Rectangle size = menuItem.getBounds();
1001
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
1002
      if (e.getX() > 0 && e.getX() < size.width && e.getY() > 0
1003
          && e.getY() < size.height)
1004
        {
1005
          manager.clearSelectedPath();
1006
          menuItem.doClick();
1007
        }
1008
 
1009
      else
1010
        manager.processMouseEvent(e);
1011
    }
1012
  }
1013
 
1014
  /**
1015
   * This class handles mouse dragged events.
1016
   */
1017
  private class MenuDragMouseHandler implements MenuDragMouseListener
1018
  {
1019
    /**
1020
     * Tbis method is invoked when mouse is dragged over the menu item.
1021
     *
1022
     * @param e
1023
     *          The MenuDragMouseEvent
1024
     */
1025
    public void menuDragMouseDragged(MenuDragMouseEvent e)
1026
    {
1027
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
1028
      manager.setSelectedPath(e.getPath());
1029
    }
1030
 
1031
    /**
1032
     * Tbis method is invoked when mouse enters the menu item while it is being
1033
     * dragged.
1034
     *
1035
     * @param e
1036
     *          The MenuDragMouseEvent
1037
     */
1038
    public void menuDragMouseEntered(MenuDragMouseEvent e)
1039
    {
1040
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
1041
      manager.setSelectedPath(e.getPath());
1042
    }
1043
 
1044
    /**
1045
     * Tbis method is invoked when mouse exits the menu item while it is being
1046
     * dragged
1047
     *
1048
     * @param e the MenuDragMouseEvent
1049
     */
1050
    public void menuDragMouseExited(MenuDragMouseEvent e)
1051
    {
1052
      // TODO: What should be done here, if anything?
1053
    }
1054
 
1055
    /**
1056
     * Tbis method is invoked when mouse was dragged and released inside the
1057
     * menu item.
1058
     *
1059
     * @param e
1060
     *          The MenuDragMouseEvent
1061
     */
1062
    public void menuDragMouseReleased(MenuDragMouseEvent e)
1063
    {
1064
      MenuElement[] path = e.getPath();
1065
 
1066
      if (path[path.length - 1] instanceof JMenuItem)
1067
        ((JMenuItem) path[path.length - 1]).doClick();
1068
 
1069
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
1070
      manager.clearSelectedPath();
1071
    }
1072
  }
1073
 
1074
  /**
1075
   * This class handles key events occuring when menu item is visible on the
1076
   * screen.
1077
   */
1078
  private class MenuKeyHandler implements MenuKeyListener
1079
  {
1080
    /**
1081
     * This method is invoked when key has been pressed
1082
     *
1083
     * @param e
1084
     *          A {@link MenuKeyEvent}.
1085
     */
1086
    public void menuKeyPressed(MenuKeyEvent e)
1087
    {
1088
      // TODO: What should be done here, if anything?
1089
    }
1090
 
1091
    /**
1092
     * This method is invoked when key has been pressed
1093
     *
1094
     * @param e
1095
     *          A {@link MenuKeyEvent}.
1096
     */
1097
    public void menuKeyReleased(MenuKeyEvent e)
1098
    {
1099
      // TODO: What should be done here, if anything?
1100
    }
1101
 
1102
    /**
1103
     * This method is invoked when key has been typed It handles the mnemonic
1104
     * key for the menu item.
1105
     *
1106
     * @param e
1107
     *          A {@link MenuKeyEvent}.
1108
     */
1109
    public void menuKeyTyped(MenuKeyEvent e)
1110
    {
1111
      // TODO: What should be done here, if anything?
1112
    }
1113
  }
1114
 
1115
  /**
1116
   * Helper class that listens for item changes to the properties of the {@link
1117
   * JMenuItem}.
1118
   */
1119
  private class ItemHandler implements ItemListener
1120
  {
1121
    /**
1122
     * This method is called when one of the menu item changes.
1123
     *
1124
     * @param evt A {@link ItemEvent}.
1125
     */
1126
    public void itemStateChanged(ItemEvent evt)
1127
    {
1128
      boolean state = false;
1129
      if (menuItem instanceof JCheckBoxMenuItem)
1130
        {
1131
          if (evt.getStateChange() == ItemEvent.SELECTED)
1132
            state = true;
1133
          ((JCheckBoxMenuItem) menuItem).setState(state);
1134
        }
1135
      menuItem.revalidate();
1136
      menuItem.repaint();
1137
    }
1138
  }
1139
}

powered by: WebSVN 2.1.0

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