1. /*
  2. * @(#)WindowsMenuUI.java 1.24 03/12/19
  3. *
  4. * Copyright 2004 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.event.MouseInputListener;
  13. import javax.swing.*;
  14. /**
  15. * Windows rendition of the component.
  16. * <p>
  17. * <strong>Warning:</strong>
  18. * Serialized objects of this class will not be compatible with
  19. * future Swing releases. The current serialization support is appropriate
  20. * for short term storage or RMI between applications running the same
  21. * version of Swing. A future release of Swing will provide support for
  22. * long term persistence.
  23. */
  24. public class WindowsMenuUI extends BasicMenuUI {
  25. public static ComponentUI createUI(JComponent x) {
  26. return new WindowsMenuUI();
  27. }
  28. protected void installDefaults() {
  29. super.installDefaults();
  30. if (!WindowsLookAndFeel.isClassicWindows()) {
  31. menuItem.setRolloverEnabled(true);
  32. }
  33. }
  34. /**
  35. * Draws the background of the menu.
  36. * @since 1.4
  37. */
  38. protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) {
  39. JMenu menu = (JMenu)menuItem;
  40. ButtonModel model = menu.getModel();
  41. // Use superclass method for the old Windows LAF,
  42. // for submenus, and for XP toplevel if selected or pressed
  43. if (WindowsLookAndFeel.isClassicWindows() ||
  44. !menu.isTopLevelMenu() ||
  45. (XPStyle.getXP() != null && (model.isArmed() || model.isSelected()))) {
  46. super.paintBackground(g, menu, bgColor);
  47. return;
  48. }
  49. Color oldColor = g.getColor();
  50. int menuWidth = menu.getWidth();
  51. int menuHeight = menu.getHeight();
  52. UIDefaults table = UIManager.getLookAndFeelDefaults();
  53. Color highlight = table.getColor("controlLtHighlight");
  54. Color shadow = table.getColor("controlShadow");
  55. g.setColor(menu.getBackground());
  56. g.fillRect(0,0, menuWidth, menuHeight);
  57. if (menu.isOpaque()) {
  58. if (model.isArmed() || model.isSelected()) {
  59. // Draw a lowered bevel border
  60. g.setColor(shadow);
  61. g.drawLine(0,0, menuWidth - 1,0);
  62. g.drawLine(0,0, 0,menuHeight - 2);
  63. g.setColor(highlight);
  64. g.drawLine(menuWidth - 1,0, menuWidth - 1,menuHeight - 2);
  65. g.drawLine(0,menuHeight - 2, menuWidth - 1,menuHeight - 2);
  66. } else if (model.isRollover() && model.isEnabled()) {
  67. // Only paint rollover if no other menu on menubar is selected
  68. boolean otherMenuSelected = false;
  69. MenuElement[] menus = ((JMenuBar)menu.getParent()).getSubElements();
  70. for (int i = 0; i < menus.length; i++) {
  71. if (((JMenuItem)menus[i]).isSelected()) {
  72. otherMenuSelected = true;
  73. break;
  74. }
  75. }
  76. if (!otherMenuSelected) {
  77. if (XPStyle.getXP() != null) {
  78. g.setColor(selectionBackground); // Uses protected field.
  79. g.fillRect(0, 0, menuWidth, menuHeight);
  80. } else {
  81. // Draw a raised bevel border
  82. g.setColor(highlight);
  83. g.drawLine(0,0, menuWidth - 1,0);
  84. g.drawLine(0,0, 0,menuHeight - 2);
  85. g.setColor(shadow);
  86. g.drawLine(menuWidth - 1,0, menuWidth - 1,menuHeight - 2);
  87. g.drawLine(0,menuHeight - 2, menuWidth - 1,menuHeight - 2);
  88. }
  89. }
  90. }
  91. }
  92. g.setColor(oldColor);
  93. }
  94. /**
  95. * Method which renders the text of the current menu item.
  96. * <p>
  97. * @param g Graphics context
  98. * @param menuItem Current menu item to render
  99. * @param textRect Bounding rectangle to render the text.
  100. * @param text String to render
  101. * @since 1.4
  102. */
  103. protected void paintText(Graphics g, JMenuItem menuItem,
  104. Rectangle textRect, String text) {
  105. JMenu menu = (JMenu)menuItem;
  106. ButtonModel model = menuItem.getModel();
  107. Color oldColor = g.getColor();
  108. // Only paint rollover if no other menu on menubar is selected
  109. boolean paintRollover = model.isRollover();
  110. if (paintRollover && menu.isTopLevelMenu()) {
  111. MenuElement[] menus = ((JMenuBar)menu.getParent()).getSubElements();
  112. for (int i = 0; i < menus.length; i++) {
  113. if (((JMenuItem)menus[i]).isSelected()) {
  114. paintRollover = false;
  115. break;
  116. }
  117. }
  118. }
  119. if ((model.isSelected() && (WindowsLookAndFeel.isClassicWindows() ||
  120. !menu.isTopLevelMenu())) ||
  121. (XPStyle.getXP() != null && (paintRollover ||
  122. model.isArmed() ||
  123. model.isSelected()))) {
  124. g.setColor(selectionForeground); // Uses protected field.
  125. }
  126. WindowsGraphicsUtils.paintText(g, menuItem, textRect, text, 0);
  127. g.setColor(oldColor);
  128. }
  129. protected MouseInputListener createMouseInputListener(JComponent c) {
  130. return new WindowsMouseInputHandler();
  131. }
  132. /**
  133. * This class implements a mouse handler that sets the rollover flag to
  134. * true when the mouse enters the menu and false when it exits.
  135. * @since 1.4
  136. */
  137. protected class WindowsMouseInputHandler extends BasicMenuUI.MouseInputHandler {
  138. public void mouseEntered(MouseEvent evt) {
  139. super.mouseEntered(evt);
  140. JMenu menu = (JMenu)evt.getSource();
  141. ButtonModel model = menu.getModel();
  142. if (menu.isRolloverEnabled()) {
  143. model.setRollover(true);
  144. menuItem.repaint();
  145. }
  146. }
  147. public void mouseExited(MouseEvent evt) {
  148. super.mouseExited(evt);
  149. JMenu menu = (JMenu)evt.getSource();
  150. ButtonModel model = menu.getModel();
  151. if (menu.isRolloverEnabled()) {
  152. model.setRollover(false);
  153. menuItem.repaint();
  154. }
  155. }
  156. }
  157. }