1. /*
  2. * @(#)WindowsMenuUI.java 1.20 03/05/06
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.windows;
  8. import java.awt.*;
  9. import java.awt.event.MouseEvent;
  10. import javax.swing.plaf.ComponentUI;
  11. import javax.swing.plaf.basic.BasicMenuUI;
  12. import javax.swing.plaf.basic.BasicGraphicsUtils;
  13. import javax.swing.event.MouseInputListener;
  14. import javax.swing.*;
  15. /**
  16. * Windows rendition of the component.
  17. * <p>
  18. * <strong>Warning:</strong>
  19. * Serialized objects of this class will not be compatible with
  20. * future Swing releases. The current serialization support is appropriate
  21. * for short term storage or RMI between applications running the same
  22. * version of Swing. A future release of Swing will provide support for
  23. * long term persistence.
  24. */
  25. public class WindowsMenuUI extends BasicMenuUI {
  26. private boolean isMouseOver = false;
  27. public static ComponentUI createUI(JComponent x) {
  28. return new WindowsMenuUI();
  29. }
  30. /**
  31. * Draws the background of the menu.
  32. * @since 1.4
  33. */
  34. protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) {
  35. JMenu menu = (JMenu)menuItem;
  36. ButtonModel model = menuItem.getModel();
  37. // Use superclass method for the old Windows LAF,
  38. // for submenus, and for XP toplevel if selected or pressed
  39. if (WindowsLookAndFeel.isClassicWindows() ||
  40. !menu.isTopLevelMenu() ||
  41. (XPStyle.getXP() != null && (model.isArmed() || model.isSelected()))) {
  42. super.paintBackground(g, menuItem, bgColor);
  43. return;
  44. }
  45. Color oldColor = g.getColor();
  46. int menuWidth = menuItem.getWidth();
  47. int menuHeight = menuItem.getHeight();
  48. UIDefaults table = UIManager.getLookAndFeelDefaults();
  49. Color highlight = table.getColor("controlLtHighlight");
  50. Color shadow = table.getColor("controlShadow");
  51. g.setColor(menuItem.getBackground());
  52. g.fillRect(0,0, menuWidth, menuHeight);
  53. if(menuItem.isOpaque()) {
  54. if (model.isArmed()|| (menuItem instanceof JMenu && model.isSelected())) {
  55. // Draw a lowered bevel border
  56. g.setColor(shadow);
  57. g.drawLine(0,0, menuWidth - 1,0);
  58. g.drawLine(0,0, 0,menuHeight - 2);
  59. g.setColor(highlight);
  60. g.drawLine(menuWidth - 1,0, menuWidth - 1,menuHeight - 2);
  61. g.drawLine(0,menuHeight - 2, menuWidth - 1,menuHeight - 2);
  62. } else {
  63. if (isMouseOver() && model.isEnabled()) {
  64. if (XPStyle.getXP() != null) {
  65. g.setColor(selectionBackground); // Uses protected field.
  66. g.fillRect(0, 0, menuWidth, menuHeight);
  67. } else {
  68. // Draw a raised bevel border
  69. g.setColor(highlight);
  70. g.drawLine(0,0, menuWidth - 1,0);
  71. g.drawLine(0,0, 0,menuHeight - 2);
  72. g.setColor(shadow);
  73. g.drawLine(menuWidth - 1,0, menuWidth - 1,menuHeight - 2);
  74. g.drawLine(0,menuHeight - 2, menuWidth - 1,menuHeight - 2);
  75. }
  76. } else {
  77. g.setColor(menuItem.getBackground());
  78. g.fillRect(0,0, menuWidth, menuHeight);
  79. }
  80. }
  81. }
  82. g.setColor(oldColor);
  83. }
  84. /**
  85. * Method which renders the text of the current menu item.
  86. * <p>
  87. * @param g Graphics context
  88. * @param menuItem Current menu item to render
  89. * @param textRect Bounding rectangle to render the text.
  90. * @param text String to render
  91. * @since 1.4
  92. */
  93. protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) {
  94. // Note: This method is almost identical to the same method in WindowsMenuItemUI
  95. JMenu menu = (JMenu)menuItem;
  96. ButtonModel model = menuItem.getModel();
  97. if(!model.isEnabled()) {
  98. // *** paint the text disabled
  99. WindowsGraphicsUtils.paintText(g, menuItem, textRect, text, 0);
  100. } else {
  101. FontMetrics fm = g.getFontMetrics();
  102. int mnemonicIndex = menuItem.getDisplayedMnemonicIndex();
  103. // W2K Feature: Check to see if the Underscore should be rendered.
  104. if (WindowsLookAndFeel.isMnemonicHidden()) {
  105. mnemonicIndex = -1;
  106. }
  107. Color oldColor = g.getColor();
  108. // For Win95, the selected text color is the selection forground color
  109. if ((model.isSelected() && (WindowsLookAndFeel.isClassicWindows() ||
  110. !menu.isTopLevelMenu())) ||
  111. (XPStyle.getXP() != null && (isMouseOver() ||
  112. model.isArmed() ||
  113. model.isSelected()))) {
  114. g.setColor(selectionForeground); // Uses protected field.
  115. }
  116. BasicGraphicsUtils.drawStringUnderlineCharAt(g,text,
  117. mnemonicIndex,
  118. textRect.x,
  119. textRect.y + fm.getAscent());
  120. g.setColor(oldColor);
  121. }
  122. }
  123. /**
  124. * Set the temporary flag to indicate if the mouse has entered the menu.
  125. */
  126. private void setMouseOver(boolean over) {
  127. isMouseOver = over;
  128. }
  129. /**
  130. * Get the temporary flag to indicate if the mouse has entered the menu.
  131. */
  132. private boolean isMouseOver() {
  133. return isMouseOver;
  134. }
  135. protected MouseInputListener createMouseInputListener(JComponent c) {
  136. return new WindowsMouseInputHandler();
  137. }
  138. /**
  139. * This class implements a mouse handler that sets the rollover flag to
  140. * true when the mouse enters the menu and false when it exits.
  141. * @since 1.4
  142. */
  143. protected class WindowsMouseInputHandler extends BasicMenuUI.MouseInputHandler {
  144. public void mouseEntered(MouseEvent evt) {
  145. super.mouseEntered(evt);
  146. if (!WindowsLookAndFeel.isClassicWindows()) {
  147. setMouseOver(true);
  148. menuItem.repaint();
  149. }
  150. }
  151. public void mouseExited(MouseEvent evt) {
  152. super.mouseExited(evt);
  153. if (!WindowsLookAndFeel.isClassicWindows()) {
  154. setMouseOver(false);
  155. menuItem.repaint();
  156. }
  157. }
  158. }
  159. }