1 /*
2  * @(#)QuaquaMenuItemUI.java 1.1  2008-05-04
3  *
4  * Copyright (c) 2003-2008 Werner Randelshofer
5  * Staldenmattweg 2, Immensee, CH-6405, Switzerland.
6  * All rights reserved.
7  *
8  * The copyright of this software is owned by Werner Randelshofer.
9  * You may not use, copy or modify this software, except in
10  * accordance with the license agreement you entered into with
11  * Werner Randelshofer. For details see accompanying license terms.
12  */
13 package ch.randelshofer.quaqua;
14 
15 import ch.randelshofer.quaqua.border.BackgroundBorder;
16 import ch.randelshofer.quaqua.color.PaintableColor;
17 import java.awt.*;
18 import java.awt.event.*;
19 import java.awt.image.*;
20 import java.beans.*;
21 import javax.swing.*;
22 import javax.swing.border.Border;
23 import javax.swing.event.*;
24 import javax.swing.plaf.*;
25 import javax.swing.plaf.basic.*;
26 import javax.swing.plaf.metal.*;
27 import javax.swing.text.View;
28 
29 /**
30  * A replacement for the AquaMenuItemUI.
31  * <p>
32  * This class provides the following workarounds for issues in Apple's
33  * implementation of the Aqua Look and Feel in Java 1.4.1:
34  * <ul>
35  * <li>MenuItems are highlighted with a blue background color and white text and
36  * accelerator instead of higlighting with a striped background, white text and black
37  * accelerator.
38  * </li>
39  * <li>Menu item accelerators use character symbols instead of writing "Meta",
40  * "Delete" or "Backspace".
41  * </li>
42  * </ul>
43  *
44  * @author Werner Randelshofer, Staldenmattweg 2, CH-6405 Immensee, Switzerland
45  * @version 1.1 2008-05-04 Added support for background border.
46  * <br>1.0.2 2007-07-25 Don't override installListeners from BasicMenuItemUI.
47  * <br>1.0.1 2003-10-04 A 'break' in getAcceleratorText was missing which
48  * resulted in a bad text for the VK_ENTER key code.
49  * <br>1.0 2003-07-19 Created.
50  */
51 public class QuaquaMenuItemUI extends BasicMenuItemUI
52         implements QuaquaMenuPainterClient {
53 
54     boolean fIsScreenMenuItem = false;
55     int fType;
56     static final int kPlain = 0;
57     static final int kCheckBox = 1;
58     static final int kRadioButton = 2;
59     static final String[] sPropertyPrefixes = {"MenuItem", "CheckBoxMenuItem", "RadioButtonMenuItem"};
60     // BasicMenuUI also uses this.
61     //Handler handler;
62 
QuaquaMenuItemUI(int type)63     QuaquaMenuItemUI(int type) {
64         fType = type;
65     }
66 
createUI(JComponent jcomponent)67     public static ComponentUI createUI(JComponent jcomponent) {
68         int i = 0;
69         if (jcomponent instanceof JCheckBoxMenuItem) {
70             i = 1;
71         } else if (jcomponent instanceof JRadioButtonMenuItem) {
72             i = 2;
73         }
74         return new QuaquaMenuItemUI(i);
75     }
76 
getPropertyPrefix()77     protected String getPropertyPrefix() {
78         return sPropertyPrefixes[fType];
79     }
80 
81     /*
82     protected void installListeners() {
83     if ((mouseInputListener = createMouseInputListener(menuItem)) != null) {
84     menuItem.addMouseListener(mouseInputListener);
85     menuItem.addMouseMotionListener(mouseInputListener);
86     }
87     if ((menuDragMouseListener = createMenuDragMouseListener(menuItem)) != null) {
88     menuItem.addMenuDragMouseListener(menuDragMouseListener);
89     }
90     if ((menuKeyListener = createMenuKeyListener(menuItem)) != null) {
91     menuItem.addMenuKeyListener(menuKeyListener);
92     if (menuKeyListener instanceof PropertyChangeListener) {
93     menuItem.addPropertyChangeListener((PropertyChangeListener) menuKeyListener);
94     }
95     }
96     }*/
updateListenersForScreenMenuItem()97     protected void updateListenersForScreenMenuItem() {
98         setIsScreenMenu(true);
99     }
100 
setIsScreenMenu(boolean bool)101     protected void setIsScreenMenu(boolean bool) {
102         if (fIsScreenMenuItem != bool) {
103             fIsScreenMenuItem = bool;
104             if (fIsScreenMenuItem) {
105                 removeListeners();
106             } else {
107                 addListeners();
108             }
109         }
110     }
111 
removeListeners()112     protected void removeListeners() {
113         //menuItem.removeMouseListener(getHandler());
114         //menuItem.removeMouseMotionListener(getHandler());
115         //menuItem.removeMenuDragMouseListener(getHandler());
116         menuItem.removeMouseListener(mouseInputListener);
117         menuItem.removeMouseMotionListener(mouseInputListener);
118         menuItem.removeMenuDragMouseListener(menuDragMouseListener);
119     }
120 
addListeners()121     protected void addListeners() {
122         menuItem.addMouseListener(mouseInputListener);
123         menuItem.addMouseMotionListener(mouseInputListener);
124         menuItem.addMenuDragMouseListener(menuDragMouseListener);
125     }
126 
paintMenuItem(Graphics g, JComponent c, Icon checkIcon, Icon arrowIcon, Color background, Color foreground, int defaultTextIconGap)127     protected void paintMenuItem(Graphics g, JComponent c,
128             Icon checkIcon, Icon arrowIcon, Color background,
129             Color foreground, int defaultTextIconGap) {
130 
131         QuaquaMenuPainter.getInstance().paintMenuItem(this, g, c, checkIcon,
132                 arrowIcon, background, foreground,
133                 disabledForeground,
134                 selectionForeground, defaultTextIconGap,
135                 acceleratorFont);
136     }
137 
getPreferredMenuItemSize(JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap)138     protected Dimension getPreferredMenuItemSize(JComponent c,
139             Icon checkIcon,
140             Icon arrowIcon,
141             int defaultTextIconGap) {
142         return QuaquaMenuPainter.getInstance().getPreferredMenuItemSize(c, checkIcon, arrowIcon, defaultTextIconGap, acceleratorFont);
143     }
144 
update(Graphics graphics, JComponent jcomponent)145     public void update(Graphics graphics, JComponent jcomponent) {
146         this.paint(graphics, jcomponent);
147     }
148 
paintBackground(Graphics g, JComponent component, int menuWidth, int menuHeight)149     public void paintBackground(Graphics g, JComponent component, int menuWidth, int menuHeight) {
150         Color bgColor = selectionBackground;
151         AbstractButton menuItem = (AbstractButton) component;
152         ButtonModel model = menuItem.getModel();
153         Color oldColor = g.getColor();
154 
155         if (menuItem.isOpaque()) {
156             if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) {
157                 //g.setColor(bgColor);
158                 ((Graphics2D) g).setPaint(PaintableColor.getPaint(bgColor, component));
159                 g.fillRect(0, 0, menuWidth, menuHeight);
160             } else {
161                 //g.setColor(menuItem.getBackground());
162                 ((Graphics2D) g).setPaint(PaintableColor.getPaint(menuItem.getBackground(), component));
163                 g.fillRect(0, 0, menuWidth, menuHeight);
164             }
165             g.setColor(oldColor);
166         }
167 
168         if (component.getBorder() instanceof BackgroundBorder) {
169             Border b = ((BackgroundBorder) component.getBorder()).getBackgroundBorder();
170             b.paintBorder(component, g, 0, 0, component.getWidth(), component.getHeight());
171         }
172     }
173 }
174