8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javax.swing.plaf.basic;
27
28 import java.awt.*;
29 import java.awt.event.*;
30 import java.beans.PropertyChangeEvent;
31 import java.beans.PropertyChangeListener;
32
33 import javax.swing.*;
34 import javax.swing.event.*;
35 import javax.swing.plaf.*;
36 import javax.swing.text.View;
37
38 import sun.swing.*;
39
40 /**
41 * BasicMenuItem implementation
42 *
43 * @author Georges Saab
44 * @author David Karlton
45 * @author Arnaud Weber
46 * @author Fredrik Lagerblad
47 */
108 *
109 * @since 1.6
110 * @see #createPropertyChangeListener
111 */
112 protected PropertyChangeListener propertyChangeListener;
113 // BasicMenuUI also uses this.
114 Handler handler;
115 /**
116 * The arrow icon.
117 */
118 protected Icon arrowIcon = null;
119 /**
120 * The check icon.
121 */
122 protected Icon checkIcon = null;
123 /**
124 * The value represents if the old border is painted.
125 */
126 protected boolean oldBorderPainted;
127
128 /* diagnostic aids -- should be false for production builds. */
129 private static final boolean TRACE = false; // trace creates and disposes
130
131 private static final boolean VERBOSE = false; // show reuse hits/misses
132 private static final boolean DEBUG = false; // show bad params, misc.
133
134 static void loadActionMap(LazyActionMap map) {
135 // NOTE: BasicMenuUI also calls into this method.
136 map.put(new Actions(Actions.CLICK));
137 BasicLookAndFeel.installAudioActionMap(map);
138 }
139
140 /**
141 * Returns a new instance of {@code BasicMenuItemUI}.
142 *
143 * @param c a component
144 * @return a new instance of {@code BasicMenuItemUI}
145 */
146 public static ComponentUI createUI(JComponent c) {
147 return new BasicMenuItemUI();
230 }
231 if (checkIcon == null ||
232 checkIcon instanceof UIResource) {
233 checkIcon = UIManager.getIcon(prefix + ".checkIcon");
234 //In case of column layout, .checkIconFactory is defined for this UI,
235 //the icon is compatible with it and useCheckAndArrow() is true,
236 //then the icon is handled by the checkIcon.
237 boolean isColumnLayout = MenuItemLayoutHelper.isColumnLayout(
238 BasicGraphicsUtils.isLeftToRight(menuItem), menuItem);
239 if (isColumnLayout) {
240 MenuItemCheckIconFactory iconFactory =
241 (MenuItemCheckIconFactory) UIManager.get(prefix
242 + ".checkIconFactory");
243 if (iconFactory != null
244 && MenuItemLayoutHelper.useCheckAndArrow(menuItem)
245 && iconFactory.isCompatible(checkIcon, prefix)) {
246 checkIcon = iconFactory.getIcon(menuItem);
247 }
248 }
249 }
250 }
251
252 /**
253 *
254 * @param menuItem a menu item
255 * @since 1.3
256 */
257 protected void installComponents(JMenuItem menuItem){
258 BasicHTML.updateRenderer(menuItem, menuItem.getText());
259 }
260
261 /**
262 * Returns a property prefix.
263 *
264 * @return a property prefix
265 */
266 protected String getPropertyPrefix() {
267 return "MenuItem";
268 }
269
304 uninstallDefaults();
305 uninstallComponents(menuItem);
306 uninstallListeners();
307 uninstallKeyboardActions();
308 MenuItemLayoutHelper.clearUsedParentClientProperties(menuItem);
309 menuItem = null;
310 }
311
312 /**
313 * Uninstalls default properties.
314 */
315 protected void uninstallDefaults() {
316 LookAndFeel.uninstallBorder(menuItem);
317 LookAndFeel.installProperty(menuItem, "borderPainted", oldBorderPainted);
318 if (menuItem.getMargin() instanceof UIResource)
319 menuItem.setMargin(null);
320 if (arrowIcon instanceof UIResource)
321 arrowIcon = null;
322 if (checkIcon instanceof UIResource)
323 checkIcon = null;
324 }
325
326 /**
327 * Unregisters components.
328 *
329 * @param menuItem a menu item
330 * @since 1.3
331 */
332 protected void uninstallComponents(JMenuItem menuItem){
333 BasicHTML.updateRenderer(menuItem, "");
334 }
335
336 /**
337 * Unregisters listeners.
338 */
339 protected void uninstallListeners() {
340 if (mouseInputListener != null) {
341 menuItem.removeMouseListener(mouseInputListener);
342 menuItem.removeMouseMotionListener(mouseInputListener);
343 }
657 } else {
658 g.setColor(holdc);
659 }
660 if (lh.useCheckAndArrow()) {
661 lh.getCheckIcon().paintIcon(lh.getMenuItem(), g,
662 lr.getCheckRect().x, lr.getCheckRect().y);
663 }
664 g.setColor(holdc);
665 }
666 }
667
668 private void paintAccText(Graphics g, MenuItemLayoutHelper lh,
669 MenuItemLayoutHelper.LayoutResult lr) {
670 if (!lh.getAccText().equals("")) {
671 ButtonModel model = lh.getMenuItem().getModel();
672 g.setFont(lh.getAccFontMetrics().getFont());
673 if (!model.isEnabled()) {
674 // *** paint the accText disabled
675 if (disabledForeground != null) {
676 g.setColor(disabledForeground);
677 SwingUtilities2.drawString(lh.getMenuItem(), g,
678 lh.getAccText(), lr.getAccRect().x,
679 lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
680 } else {
681 g.setColor(lh.getMenuItem().getBackground().brighter());
682 SwingUtilities2.drawString(lh.getMenuItem(), g,
683 lh.getAccText(), lr.getAccRect().x,
684 lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
685 g.setColor(lh.getMenuItem().getBackground().darker());
686 SwingUtilities2.drawString(lh.getMenuItem(), g,
687 lh.getAccText(), lr.getAccRect().x - 1,
688 lr.getAccRect().y + lh.getFontMetrics().getAscent() - 1);
689 }
690 } else {
691 // *** paint the accText normally
692 if (model.isArmed()
693 || (lh.getMenuItem() instanceof JMenu
694 && model.isSelected())) {
695 g.setColor(acceleratorSelectionForeground);
696 } else {
697 g.setColor(acceleratorForeground);
698 }
699 SwingUtilities2.drawString(lh.getMenuItem(), g, lh.getAccText(),
700 lr.getAccRect().x, lr.getAccRect().y +
701 lh.getAccFontMetrics().getAscent());
702 }
703 }
704 }
705
706 private void paintText(Graphics g, MenuItemLayoutHelper lh,
707 MenuItemLayoutHelper.LayoutResult lr) {
708 if (!lh.getText().equals("")) {
709 if (lh.getHtmlView() != null) {
710 // Text is HTML
711 lh.getHtmlView().paint(g, lr.getTextRect());
712 } else {
713 // Text isn't HTML
714 paintText(g, lh.getMenuItem(), lr.getTextRect(), lh.getText());
715 }
716 }
717 }
718
719 private void paintArrowIcon(Graphics g, MenuItemLayoutHelper lh,
774 }
775
776 /**
777 * Renders the text of the current menu item.
778 *
779 * @param g graphics context
780 * @param menuItem menu item to render
781 * @param textRect bounding rectangle for rendering the text
782 * @param text string to render
783 * @since 1.4
784 */
785 protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) {
786 ButtonModel model = menuItem.getModel();
787 FontMetrics fm = SwingUtilities2.getFontMetrics(menuItem, g);
788 int mnemIndex = menuItem.getDisplayedMnemonicIndex();
789
790 if(!model.isEnabled()) {
791 // *** paint the text disabled
792 if ( UIManager.get("MenuItem.disabledForeground") instanceof Color ) {
793 g.setColor( UIManager.getColor("MenuItem.disabledForeground") );
794 SwingUtilities2.drawStringUnderlineCharAt(menuItem, g,text,
795 mnemIndex, textRect.x, textRect.y + fm.getAscent());
796 } else {
797 g.setColor(menuItem.getBackground().brighter());
798 SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text,
799 mnemIndex, textRect.x, textRect.y + fm.getAscent());
800 g.setColor(menuItem.getBackground().darker());
801 SwingUtilities2.drawStringUnderlineCharAt(menuItem, g,text,
802 mnemIndex, textRect.x - 1, textRect.y +
803 fm.getAscent() - 1);
804 }
805 } else {
806 // *** paint the text normally
807 if (model.isArmed()|| (menuItem instanceof JMenu && model.isSelected())) {
808 g.setColor(selectionForeground); // Uses protected field.
809 }
810 SwingUtilities2.drawStringUnderlineCharAt(menuItem, g,text,
811 mnemIndex, textRect.x, textRect.y + fm.getAscent());
812 }
813 }
814
815 /**
816 * Returns a menu element path.
817 *
818 * @return a menu element path
819 */
820 public MenuElement[] getPath() {
821 MenuSelectionManager m = MenuSelectionManager.defaultManager();
822 MenuElement oldPath[] = m.getSelectedPath();
823 MenuElement newPath[];
824 int i = oldPath.length;
825 if (i == 0)
826 return new MenuElement[0];
827 Component parent = menuItem.getParent();
828 if (oldPath[i-1].getComponent() == parent) {
829 // The parent popup menu is the last so far
830 newPath = new MenuElement[i+1];
|
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javax.swing.plaf.basic;
27
28 import javax.swing.plaf.TextUIDrawing;
29 import java.awt.*;
30 import java.awt.event.*;
31 import java.beans.PropertyChangeEvent;
32 import java.beans.PropertyChangeListener;
33
34 import javax.swing.*;
35 import javax.swing.event.*;
36 import javax.swing.plaf.*;
37 import javax.swing.text.View;
38
39 import sun.swing.*;
40
41 /**
42 * BasicMenuItem implementation
43 *
44 * @author Georges Saab
45 * @author David Karlton
46 * @author Arnaud Weber
47 * @author Fredrik Lagerblad
48 */
109 *
110 * @since 1.6
111 * @see #createPropertyChangeListener
112 */
113 protected PropertyChangeListener propertyChangeListener;
114 // BasicMenuUI also uses this.
115 Handler handler;
116 /**
117 * The arrow icon.
118 */
119 protected Icon arrowIcon = null;
120 /**
121 * The check icon.
122 */
123 protected Icon checkIcon = null;
124 /**
125 * The value represents if the old border is painted.
126 */
127 protected boolean oldBorderPainted;
128
129 private TextUIDrawing textUIDrawing;
130
131 /* diagnostic aids -- should be false for production builds. */
132 private static final boolean TRACE = false; // trace creates and disposes
133
134 private static final boolean VERBOSE = false; // show reuse hits/misses
135 private static final boolean DEBUG = false; // show bad params, misc.
136
137 static void loadActionMap(LazyActionMap map) {
138 // NOTE: BasicMenuUI also calls into this method.
139 map.put(new Actions(Actions.CLICK));
140 BasicLookAndFeel.installAudioActionMap(map);
141 }
142
143 /**
144 * Returns a new instance of {@code BasicMenuItemUI}.
145 *
146 * @param c a component
147 * @return a new instance of {@code BasicMenuItemUI}
148 */
149 public static ComponentUI createUI(JComponent c) {
150 return new BasicMenuItemUI();
233 }
234 if (checkIcon == null ||
235 checkIcon instanceof UIResource) {
236 checkIcon = UIManager.getIcon(prefix + ".checkIcon");
237 //In case of column layout, .checkIconFactory is defined for this UI,
238 //the icon is compatible with it and useCheckAndArrow() is true,
239 //then the icon is handled by the checkIcon.
240 boolean isColumnLayout = MenuItemLayoutHelper.isColumnLayout(
241 BasicGraphicsUtils.isLeftToRight(menuItem), menuItem);
242 if (isColumnLayout) {
243 MenuItemCheckIconFactory iconFactory =
244 (MenuItemCheckIconFactory) UIManager.get(prefix
245 + ".checkIconFactory");
246 if (iconFactory != null
247 && MenuItemLayoutHelper.useCheckAndArrow(menuItem)
248 && iconFactory.isCompatible(checkIcon, prefix)) {
249 checkIcon = iconFactory.getIcon(menuItem);
250 }
251 }
252 }
253 textUIDrawing = SwingUtilities2.getTextUIDrawing(textUIDrawing);
254 }
255
256 /**
257 *
258 * @param menuItem a menu item
259 * @since 1.3
260 */
261 protected void installComponents(JMenuItem menuItem){
262 BasicHTML.updateRenderer(menuItem, menuItem.getText());
263 }
264
265 /**
266 * Returns a property prefix.
267 *
268 * @return a property prefix
269 */
270 protected String getPropertyPrefix() {
271 return "MenuItem";
272 }
273
308 uninstallDefaults();
309 uninstallComponents(menuItem);
310 uninstallListeners();
311 uninstallKeyboardActions();
312 MenuItemLayoutHelper.clearUsedParentClientProperties(menuItem);
313 menuItem = null;
314 }
315
316 /**
317 * Uninstalls default properties.
318 */
319 protected void uninstallDefaults() {
320 LookAndFeel.uninstallBorder(menuItem);
321 LookAndFeel.installProperty(menuItem, "borderPainted", oldBorderPainted);
322 if (menuItem.getMargin() instanceof UIResource)
323 menuItem.setMargin(null);
324 if (arrowIcon instanceof UIResource)
325 arrowIcon = null;
326 if (checkIcon instanceof UIResource)
327 checkIcon = null;
328 if (textUIDrawing != SwingUtilities2.DEFAULT_UI_TEXT_DRAWING
329 && textUIDrawing instanceof UIResource) {
330 textUIDrawing = SwingUtilities2.DEFAULT_UI_TEXT_DRAWING;
331 }
332 }
333
334 /**
335 * Unregisters components.
336 *
337 * @param menuItem a menu item
338 * @since 1.3
339 */
340 protected void uninstallComponents(JMenuItem menuItem){
341 BasicHTML.updateRenderer(menuItem, "");
342 }
343
344 /**
345 * Unregisters listeners.
346 */
347 protected void uninstallListeners() {
348 if (mouseInputListener != null) {
349 menuItem.removeMouseListener(mouseInputListener);
350 menuItem.removeMouseMotionListener(mouseInputListener);
351 }
665 } else {
666 g.setColor(holdc);
667 }
668 if (lh.useCheckAndArrow()) {
669 lh.getCheckIcon().paintIcon(lh.getMenuItem(), g,
670 lr.getCheckRect().x, lr.getCheckRect().y);
671 }
672 g.setColor(holdc);
673 }
674 }
675
676 private void paintAccText(Graphics g, MenuItemLayoutHelper lh,
677 MenuItemLayoutHelper.LayoutResult lr) {
678 if (!lh.getAccText().equals("")) {
679 ButtonModel model = lh.getMenuItem().getModel();
680 g.setFont(lh.getAccFontMetrics().getFont());
681 if (!model.isEnabled()) {
682 // *** paint the accText disabled
683 if (disabledForeground != null) {
684 g.setColor(disabledForeground);
685 textUIDrawing.drawString(lh.getMenuItem(), g,
686 lh.getAccText(), lr.getAccRect().x,
687 lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
688 } else {
689 g.setColor(lh.getMenuItem().getBackground().brighter());
690 textUIDrawing.drawString(lh.getMenuItem(), g,
691 lh.getAccText(), lr.getAccRect().x,
692 lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
693 g.setColor(lh.getMenuItem().getBackground().darker());
694 textUIDrawing.drawString(lh.getMenuItem(), g,
695 lh.getAccText(), lr.getAccRect().x - 1,
696 lr.getAccRect().y + lh.getFontMetrics().getAscent() - 1);
697 }
698 } else {
699 // *** paint the accText normally
700 if (model.isArmed()
701 || (lh.getMenuItem() instanceof JMenu
702 && model.isSelected())) {
703 g.setColor(acceleratorSelectionForeground);
704 } else {
705 g.setColor(acceleratorForeground);
706 }
707 textUIDrawing.drawString(lh.getMenuItem(), g, lh.getAccText(),
708 lr.getAccRect().x, lr.getAccRect().y +
709 lh.getAccFontMetrics().getAscent());
710 }
711 }
712 }
713
714 private void paintText(Graphics g, MenuItemLayoutHelper lh,
715 MenuItemLayoutHelper.LayoutResult lr) {
716 if (!lh.getText().equals("")) {
717 if (lh.getHtmlView() != null) {
718 // Text is HTML
719 lh.getHtmlView().paint(g, lr.getTextRect());
720 } else {
721 // Text isn't HTML
722 paintText(g, lh.getMenuItem(), lr.getTextRect(), lh.getText());
723 }
724 }
725 }
726
727 private void paintArrowIcon(Graphics g, MenuItemLayoutHelper lh,
782 }
783
784 /**
785 * Renders the text of the current menu item.
786 *
787 * @param g graphics context
788 * @param menuItem menu item to render
789 * @param textRect bounding rectangle for rendering the text
790 * @param text string to render
791 * @since 1.4
792 */
793 protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) {
794 ButtonModel model = menuItem.getModel();
795 FontMetrics fm = SwingUtilities2.getFontMetrics(menuItem, g);
796 int mnemIndex = menuItem.getDisplayedMnemonicIndex();
797
798 if(!model.isEnabled()) {
799 // *** paint the text disabled
800 if ( UIManager.get("MenuItem.disabledForeground") instanceof Color ) {
801 g.setColor( UIManager.getColor("MenuItem.disabledForeground") );
802 textUIDrawing.drawStringUnderlineCharAt(menuItem, g,text,
803 mnemIndex, textRect.x, textRect.y + fm.getAscent());
804 } else {
805 g.setColor(menuItem.getBackground().brighter());
806 textUIDrawing.drawStringUnderlineCharAt(menuItem, g, text,
807 mnemIndex, textRect.x, textRect.y + fm.getAscent());
808 g.setColor(menuItem.getBackground().darker());
809 textUIDrawing.drawStringUnderlineCharAt(menuItem, g,text,
810 mnemIndex, textRect.x - 1, textRect.y +
811 fm.getAscent() - 1);
812 }
813 } else {
814 // *** paint the text normally
815 if (model.isArmed()|| (menuItem instanceof JMenu && model.isSelected())) {
816 g.setColor(selectionForeground); // Uses protected field.
817 }
818 textUIDrawing.drawStringUnderlineCharAt(menuItem, g,text,
819 mnemIndex, textRect.x, textRect.y + fm.getAscent());
820 }
821 }
822
823 /**
824 * Returns a menu element path.
825 *
826 * @return a menu element path
827 */
828 public MenuElement[] getPath() {
829 MenuSelectionManager m = MenuSelectionManager.defaultManager();
830 MenuElement oldPath[] = m.getSelectedPath();
831 MenuElement newPath[];
832 int i = oldPath.length;
833 if (i == 0)
834 return new MenuElement[0];
835 Component parent = menuItem.getParent();
836 if (oldPath[i-1].getComponent() == parent) {
837 // The parent popup menu is the last so far
838 newPath = new MenuElement[i+1];
|